正剧开始:
星历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, 阿伟真是又痛又快乐。
本节到此结束,欲知后事如何,请看下回分解。