[机器小伟]在[工程师阿伟]的陪同下进入练气期第四层功法的修炼,
这次要修炼的目标是[数学广角──推理]。
正剧开始:
星历2016年01月10日 14:45:20, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[推理]这一节功法。
星历2016年01月10日 14:46:35, [工程师阿伟]说:这节功法中的问题,如果是由我来做
,当然是不费劲的,但是你做可要费大劲了。[机器小伟]。
小伟不相信。
14:47:46, 阿伟沉思了很久,最后决定还是让[机器小伟]来做这些题,尽管这样导致的是
难度系数会上几个层次,但阿伟想,要玩就玩得大点。
于是,阿伟为了让[机器小伟]做这些题,真正的发扬了愚公移山的精神。
来看上面这题吧:
<span style="font-size:18px;">def tmp():
a = ['小红', '小丽', '小刚'];
b = ['语文', '数学', '品德与生活'];
result = [];
for i in range(len(a)):
for j in range(len(b)):
result.append([a[i],b[j]]);
for i in range(len(result)):
for j in range(len(result)):
for k in range(len(result)):
if i == j or i == k or j == k:
continue;
elif (result[i][0] != a[0] or result[i][1] != b[0]):
continue;
elif (result[j][0] != a[1] or result[j][1] == b[1]):
continue;
elif (result[k][0] != a[2]):
continue;
elif (result[i][1] == result[j][1] or \
result[i][1] == result[k][1] or \
result[j][1] == result[k][1]):
continue;
else:
print('{0} 拿的是 {1}, {2}拿的是{3}, {4}拿的是{5}'.format(\
result[i][0], result[i][1], \
result[j][0], result[j][1], \
result[k][0], result[k][1]));
if __name__ == '__main__':
tmp();
>>>
小红 拿的是 语文, 小丽拿的是品德与生活, 小刚拿的是数学
>>> </span>
<span style="font-size:18px;">def tmp():
a = ['欢欢', '乐乐', '笑笑'];
b = [7, 5, 9];
result = [];
for i in range(len(a)):
for j in range(len(b)):
result.append([a[i],b[j]]);
for i in range(len(result)):
for j in range(len(result)):
for k in range(len(result)):
if (result[i][0] == result[j][0] or \
result[i][0] == result[k][0] or \
result[j][0] == result[k][0]):
continue;
elif (result[i][1] == result[j][1] or \
result[i][1] == result[k][1] or \
result[j][1] == result[k][1]):
continue;
elif (result[i][0] != a[0] or \
result[j][0] != a[1] or \
result[k][0] != a[2]):
continue;
elif (result[i][1] > result[j][1]):
continue;
elif (result[k][1] > result[i][1] or \
result[k][1] > result[j][1]):
continue;
else:
print('{0}重{1}千克, {2}重{3}千克, {4}重{5}千克'.format(\
result[i][0], result[i][1], \
result[j][0], result[j][1], \
result[k][0], result[k][1]));
if __name__ == '__main__':
tmp();
>>>
欢欢重7千克, 乐乐重9千克, 笑笑重5千克</span>
<span style="font-size:18px;">def tmp():
a = ['小冬', '小雨', '小伟'];
b = ['一斑', '二斑', '三班'];
result = [];
for i in range(len(a)):
for j in range(len(b)):
result.append([a[i],b[j]]);
for i in range(len(result)):
for j in range(len(result)):
for k in range(len(result)):
if (result[i][0] == result[j][0] or \
result[i][0] == result[k][0] or \
result[j][0] == result[k][0]):
continue;
elif (result[i][1] == result[j][1] or \
result[i][1] == result[k][1] or \
result[j][1] == result[k][1]):
continue;
elif (result[i][0] != a[0] or \
result[j][0] != a[1] or \
result[k][0] != a[2]):
continue;
#各题判断条件的区别从这里开始
elif (result[k][1] != b[2]):
continue;
elif (result[j][1]== b[0]):
continue;
else:
print('{0}在{1}, {2}在{3}, {4}在{5}'.format(\
result[i][0], result[i][1], \
result[j][0], result[j][1], \
result[k][0], result[k][1]));
if __name__ == '__main__':
tmp();
>>>
小冬在一斑, 小雨在二斑, 小伟在三班
>>> </span>
是数独吧,阿伟默默的想。
答案很简单,但得到答案的过程就不是那么简单了。阿伟不禁想起了所做的一切:
当初看到了这种题,阿伟首先想的是把所有的可能性放到一个候选集中,再从中选合适的,为此来做了一个求全排列的函数:
<span style="font-size:18px;">def perm(array):
if (len(array)<=1):
return [array];
r = [];
for i in range(len(array)):
#抽去array[i]
s = array[:i]+array[i+1:];
p = perm(s);
for x in p:
#array[i]置顶
r.append(array[i:i+1]+x);
return r;
def tmp():
array = [1,2,3,4];
candidate = perm(array);
print(candidate);
print('共有{0}个候选者'.format(len(candidate)));</span>
然后,经过半天的奋战,阿伟郁闷地发现,用全排列会造成极度庞大的运算量,不可取。
经过再三的尝试,阿伟终于意识到,像这种题,要想单独让[机器小伟]去解决,那是不可能的,
其中回溯造成的运算量太庞大了,不可预知性太强了。最终,阿伟这样实现:
<span style="font-size:18px;">#测试有效性
def effective(num, matrix, row, col):
span = len(matrix);
for i in range(span):
if matrix[i][col] == num:
return 0;
for j in range(span):
if matrix[row][j] == num:
return 0;
return 1;
#测试结果是否成功
def success(matrix):
for i in iter(matrix):
if i == 0:
return 0;
return 1;</span>
<span style="font-size:18px;">def puzzle():
span = 4;
a = [[0]*span for i in range(span)];
tryArray = [];
tried = [];
a[0][0]=3;
a[0][1]=2;
a[1][3]=2;
a[2][2]=3;
a[3][0]=1;
print('原矩阵是:');
for i in range(span):
print(a[i]);
step = 0;
gameover = 0;
for row in range(span):
if gameover == 1:
break;
for col in range(span):
step+=1;
if (a[row][col] == 0):
tryArray = [];
for num in range(1, span+1):
#数字num放在row, col处时和矩阵a不冲突就行
if effective(num, a, row, col):
tryArray.append(num);
#考虑到让机器全程回溯不靠谱,实现为让机器给出选项,您来选择。
if len(tryArray)>1:
print('第{0}步:现在的矩阵是:'.format(step));
for i in range(span):
print(a[i]);
print('第{0}行, 第{1}列处的选择超过一个。有以下选择:'.\
format(row+1, col+1));
for i in range(len(tryArray)):
print(tryArray[i], end=', ');
a[row][col] = int(input('请输入您的选择:'));
tried.append(a[row][col]);
elif len(tryArray)==1:
a[row][col] = tryArray[0];
else:
print('\n\n前几步的选择造成无解的困境,请重新尝试,Game Over。');
print('您所做过的选择是:');
for i in range(len(tried)):
print(tried[i], end=', ');
gameover = 1;
if success(a, span, span):
print('\n\n您成功了,您做了英明正确的选择,您所做的选择是:');
for i in range(len(tried)):
print(tried[i], end=', ');
print('新矩阵是:');
for i in range(span):
print(a[i]);</span>
<span style="font-size:18px;">>>>
原矩阵是:
[3, 2, 0, 0]
[0, 0, 0, 2]
[0, 0, 3, 0]
[1, 0, 0, 0]
第3步:现在的矩阵是:
[3, 2, 0, 0]
[0, 0, 0, 2]
[0, 0, 3, 0]
[1, 0, 0, 0]
第1行, 第3列处的选择超过一个。有以下选择:
1, 4, 请输入您的选择:4
第6步:现在的矩阵是:
[3, 2, 4, 1]
[4, 0, 0, 2]
[0, 0, 3, 0]
[1, 0, 0, 0]
第2行, 第2列处的选择超过一个。有以下选择:
1, 3, 请输入您的选择:3
第10步:现在的矩阵是:
[3, 2, 4, 1]
[4, 3, 1, 2]
[2, 0, 3, 0]
[1, 0, 0, 0]
第3行, 第2列处的选择超过一个。有以下选择:
1, 4, 请输入您的选择:1
您成功了,您做了英明正确的选择,您所做的选择是:
4, 3, 1, 新矩阵是:
[3, 2, 4, 1]
[4, 3, 1, 2]
[2, 1, 3, 4]
[1, 4, 2, 3]</span>
为了看起来更好看,阿伟又写了下面的函数来绘制矩阵:
<span style="font-size:18px;">/**
* @usage 绘制矩阵
* @author mw
* @date 2016年01月10日 星期日 14:59:38
* @param
* @return
*
*/
function drawMatrix(matrix, row, col) {
plot.save();
var digit = new Digit();
var r = 30;
for (var i = 0; i < row; i++) {
for (var j = 0; j < col; j++) {
plot.setStrokeStyle('black');
digit.number(matrix[j][i], 2 * r * (i+1-2.5), 2 * r * (j+1-2.5), r);
plot.setStrokeStyle('red');
shape.strokeRect(2 * r * (i+1-2.5), 2 * r * (j+1-2.5), 2 * r, 2 * r);
}
}
plot.restore();
}</span>
<span style="font-size:18px;">function myDraw() {
var config = new PlotConfiguration();
config.init();
config.setPreference();
config.setSector(1,1,1,1);
var matrix =
[[1, 3, 4, 2],
[2, 4, 3, 1],
[3, 2, 1, 4],
[4, 1, 2, 3]];
drawMatrix(matrix, 4, 4);
}</span>
有了这些神器,后面的同类型问题就简单了:
<span style="font-size:18px;"> a[0][1]=3;
a[1][3]=1;
a[2][1]=2;
a[3][0]=4;
a[3][2]=2;
原矩阵是:
[0, 3, 0, 0]
[0, 0, 0, 1]
[0, 2, 0, 0]
[4, 0, 2, 0]
第1步:现在的矩阵是:
[0, 3, 0, 0]
[0, 0, 0, 1]
[0, 2, 0, 0]
[4, 0, 2, 0]
第1行, 第1列处的选择超过一个。有以下选择:
1, 2, 请输入您的选择:1
第5步:现在的矩阵是:
[1, 3, 4, 2]
[0, 0, 0, 1]
[0, 2, 0, 0]
[4, 0, 2, 0]
第2行, 第1列处的选择超过一个。有以下选择:
2, 3, 请输入您的选择:2
您成功了,您做了英明正确的选择,您所做的选择是:
1, 2, 新矩阵是:
[1, 3, 4, 2]
[2, 4, 3, 1]
[3, 2, 1, 4]
[4, 1, 2, 3]</span>
<span style="font-size:18px;"> a[0][0]=2;
a[0][3]=3;
a[2][1]=4;
a[3][3]=2;
原矩阵是:
[2, 0, 0, 3]
[0, 0, 0, 0]
[0, 4, 0, 0]
[0, 0, 0, 2]
第5步:现在的矩阵是:
[2, 1, 4, 3]
[0, 0, 0, 0]
[0, 4, 0, 0]
[0, 0, 0, 2]
第2行, 第1列处的选择超过一个。有以下选择:
1, 3, 4, 请输入您的选择:1
第6步:现在的矩阵是:
[2, 1, 4, 3]
[1, 0, 0, 0]
[0, 4, 0, 0]
[0, 0, 0, 2]
第2行, 第2列处的选择超过一个。有以下选择:
2, 3, 请输入您的选择:2
第11步:现在的矩阵是:
[2, 1, 4, 3]
[1, 2, 3, 4]
[3, 4, 0, 0]
[0, 0, 0, 2]
第3行, 第3列处的选择超过一个。有以下选择:
1, 2, 请输入您的选择:2
您成功了,您做了英明正确的选择,您所做的选择是:
1, 2, 2, 新矩阵是:
[2, 1, 4, 3]
[1, 2, 3, 4]
[3, 4, 2, 1]
[4, 3, 1, 2]</span>
<span style="font-size:18px;"> a[0][2]=1;
a[1][1]=2;
a[1][3]=3;
a[3][1]=3;
原矩阵是:
[0, 0, 1, 0]
[0, 2, 0, 3]
[0, 0, 0, 0]
[0, 3, 0, 0]
第1步:现在的矩阵是:
[0, 0, 1, 0]
[0, 2, 0, 3]
[0, 0, 0, 0]
[0, 3, 0, 0]
第1行, 第1列处的选择超过一个。有以下选择:
2, 3, 4, 请输入您的选择:3
第5步:现在的矩阵是:
[3, 4, 1, 2]
[0, 2, 0, 3]
[0, 0, 0, 0]
[0, 3, 0, 0]
第2行, 第1列处的选择超过一个。有以下选择:
1, 4, 请输入您的选择:1
第9步:现在的矩阵是:
[3, 4, 1, 2]
[1, 2, 4, 3]
[0, 0, 0, 0]
[0, 3, 0, 0]
第3行, 第1列处的选择超过一个。有以下选择:
2, 4, 请输入您的选择:2
您成功了,您做了英明正确的选择,您所做的选择是:
3, 1, 2, 新矩阵是:
[3, 4, 1, 2]
[1, 2, 4, 3]
[2, 1, 3, 4]
[4, 3, 2, 1]</span>
这一批题终于过去了,下面来了一种不同类型的题:
这种题就可以由[机器小伟]独自来做了:
<span style="font-size:18px;">def hasRepeat(array):
size = len(array);
for i in range(size):
for j in range(i+1, size):
if array[i] == array[j]:
return 1;
return 0;
def puzzle2():
array = [];
for a in range(1, 10):
for b in range(1, 10):
for c in range(1, 10):
if (10*a + 7 + 10*b + c) == 58:
array=[5, 8, 7, a, b, c];
if hasRepeat(array) == 1:
pass;
else:
print('{0} + {1} = 58'.format(a*10+7, b*10+c));
array=[];
>>>
27 + 31 = 58
37 + 21 = 58</span>
<span style="font-size:18px;">def puzzle2():
array = [];
for a in range(1, 10):
for b in range(1, 10):
for c in range(1, 10):
for d in range(1, 10):
if (10*a + b + 10*c + d) == 86:
array=[8, 6, a, b, c, d];
if hasRepeat(array) == 1:
pass;
else:
print('{0} + {1} = 86'.format(a*10+b, c*10+d));
array=[];
>>>
12 + 74 = 86
14 + 72 = 86
27 + 59 = 86
29 + 57 = 86
32 + 54 = 86
34 + 52 = 86
37 + 49 = 86
39 + 47 = 86
47 + 39 = 86
49 + 37 = 86
52 + 34 = 86
54 + 32 = 86
57 + 29 = 86
59 + 27 = 86
72 + 14 = 86
74 + 12 = 86
def puzzle2():
array = [];
for a in range(1, 10):
for b in range(1, 10):
for c in range(1, 10):
for d in range(8,9):
if (10*a + b - (10*c + d)) == 74:
array=[7, 4, a, b, c, d];
if hasRepeat(array) == 1:
pass;
else:
print('{0} - {1} = 74'.format(a*10+b, c*10+d));
array=[];
>>>
92 - 18 = 74
def puzzle2():
array = [];
for a in range(1, 10):
for b in range(2, 3):
for c in range(1, 10):
for d in range(1,10):
if (10*a + b - (10*c + d)) == 63:
array=[6, 3, a, b, c, d];
if hasRepeat(array) == 1:
pass;
else:
print('{0} - {1} = 63'.format(a*10+b, c*10+d));
array=[];
>>>
82 - 19 = 63</span>
很快,小伟就做完了。
接下来遇到的这种题好有趣:
答案是这样的:
为了得到这个答案,阿伟专门制作了神器来画这种排雷系的题:
<span style="font-size:18px;">function myDraw() {
var config = new PlotConfiguration();
config.init();
config.setPreference();
//config.setSector(1,1,1,1);
//config.axis2D(0, 0, 180);
var digit = new Digit();
var r = 50;
var row = 7;
var col = 9;
plot.translate(r, r);
var array = new Array(row * col);
for (var i = 0; i < row; i++) {
for (var j = 0; j < col; j++) {
array[i * col + j] = 0;
}
}
//设置笑脸
for (var x = 1; x < row; x+= 2) {
for (var y = 1; y<col; y+=3) {
array[x * col + y] = 'f';
}
}
//计算数字
for (var i = 0; i < row; i++) {
for (var j = 0; j < col; j++) {
if (array[i * col + j] == 'f') {
if (i -1 >= 0) {
if (j - 1 >= 0) {
if (array[(i-1)*col + j-1] != 'f')
array[(i-1)*col + j-1]++;
}
if (j+1 < col) {
if (array[(i-1)*col + j+1] != 'f')
array[(i-1)*col + j+1]++;
}
if (array[(i-1)*col + j] != 'f')
array[(i-1)*col+j]++;
}
if (i + 1 < row) {
if (j - 1 >= 0) {
if (array[(i+1)*col + j-1] != 'f')
array[(i+1)*col + j-1]++;
}
if (j+1 < col) {
if (array[(i+1)*col + j+1] != 'f')
array[(i+1)*col + j+1]++;
}
if (array[(i+1)*col + j] != 'f')
array[(i+1)*col+j]++;
}
if (j - 1 >= 0) {
if (array[i*col + j-1] != 'f')
array[i*col + j-1]++;
}
if (j+1 < col) {
if (array[i*col + j+1] != 'f')
array[i*col + j+1]++;
}
}
}
}
for (var i = 0; i < row; i++) {
for (var j = 0; j < col; j++) {
shape.strokeRect(j * r, i * r, r, r);
if (array[i * col + j] == 'f') {
plot.setFillStyle('red');
shape.fillCircle(j * r, i * r, 20);
plot.setFillStyle('yellow');
shape.fillEllipse(j * r, i * r, 15, 10);
}
else if (array[i * col + j] > 0) {
plot.setFillStyle('#880000');
digit.number(array[i * col + j], j * r, i * r, r);
}
}
}
}
</span>
上面这段代码可以得到下面这张图:
这种题要是依靠[机器小伟]做,想来也是太过艰难了,关键是阿伟现在功力消耗过大,已经
提不起精神再让小伟去做了,于是就自己解了答案,让小伟去验证:
<span style="font-size:18px;">/**
* @usage 找笑脸
* @author mw
* @date 2016年01月10日 星期日 14:59:38
* @param
* @return
*
*/
function myDraw_1() {
var config = new PlotConfiguration();
config.init();
config.setPreference();
//config.setSector(1,1,1,1);
//config.axis2D(0, 0, 180);
var digit = new Digit();
var r = 50;
var row = 7;
var col = 9;
plot.translate(r, r);
var array = new Array(row * col);
for (var i = 0; i < row; i++) {
for (var j = 0; j < col; j++) {
array[i * col + j] = 0;
}
}
//设置笑脸
var a = [0,2, 0,7, 1,5, 1,8, 3,2, 4,7];
len = a.length / 2;
for (var i = 0; i < len; i++) {
array[a[2*i] * col + a[2*i+1]] = 'f';
}
//计算数字
for (var i = 0; i < row; i++) {
for (var j = 0; j < col; j++) {
if (array[i * col + j] == 'f') {
if (i -1 >= 0) {
if (j - 1 >= 0) {
if (array[(i-1)*col + j-1] != 'f')
array[(i-1)*col + j-1]++;
}
if (j+1 < col) {
if (array[(i-1)*col + j+1] != 'f')
array[(i-1)*col + j+1]++;
}
if (array[(i-1)*col + j] != 'f')
array[(i-1)*col+j]++;
}
if (i + 1 < row) {
if (j - 1 >= 0) {
if (array[(i+1)*col + j-1] != 'f')
array[(i+1)*col + j-1]++;
}
if (j+1 < col) {
if (array[(i+1)*col + j+1] != 'f')
array[(i+1)*col + j+1]++;
}
if (array[(i+1)*col + j] != 'f')
array[(i+1)*col+j]++;
}
if (j - 1 >= 0) {
if (array[i*col + j-1] != 'f')
array[i*col + j-1]++;
}
if (j+1 < col) {
if (array[i*col + j+1] != 'f')
array[i*col + j+1]++;
}
}
}
}
for (var i = 0; i < row; i++) {
for (var j = 0; j < col; j++) {
shape.strokeRect(j * r, i * r, r, r);
if (array[i * col + j] == 'f') {
plot.setFillStyle('red');
shape.fillCircle(j * r, i * r, 20);
plot.setFillStyle('yellow');
shape.fillEllipse(j * r, i * r, 15, 10);
}
else if (array[i * col + j] > 0) {
plot.setFillStyle('#880000');
digit.number(array[i * col + j], j * r, i * r, r);
}
}
}
}</span>
笑脸全部在这里了。
这次玩得太High, 阿伟真是又痛又快乐。
本节到此结束,欲知后事如何,请看下回分解。