小时候在《科学画报》上看到过,不会。长大后会编程了,能做到试3!×3!×4!×4!次了,又发现手工可解。
先看手工:用个5x5的表格表示状态,行依次是:国籍、房子颜色、饮料、香烟、宠物。表格初始空白。
“挪威人住第一间房,挪威人住蓝房子隔壁,住中间房子的喝牛奶”:

“绿房子在白房子左面隔壁,住绿房子的喝咖啡”。像拼图或俄罗斯方块:

上图这一块,往哪儿插呢?或者多层透明塑料上写的有字,叠起来后字不能挡住字。
HTML+CSS/Canvas, Python (Pillow)等等都可以alpha blend, AI还特别喜欢overkill,下图是CSS做的:

这倒是也可以开发个“游戏”:n张卡片有3D堆叠效果,可以点击选择某一张进行编辑,有个按钮“模拟显示”(致敬DOS版WPS)把它们叠起来,程序判断有无冲突。
或者朴素点,像华容道或数字迷宫,点击同一行里的两个方块可以交换位置,程序判断是否整个表格满足条件。
依次类推,比如”英国人住红房子”,房子只有一个空位了。最后几步得试几种可能,没有必然。
人工+Python搜索:
from itertools import permutations as pmt L = lambda s: list(s) a = [L('挪丹英德瑞'),L('黄蓝红绿白'),L('水茶奶咖啤'),L('dbmps'),L('猫马鸟鱼狗')] def let(row, cols, s): for i in range(len(cols)): a[row][cols[i]] = s[i] for n in pmt([1,3,4]): # nation let(0, n, '丹德瑞') for d in pmt([0,1,4]): # drink if n[0] != d[0]: continue # 丹麦人喝茶 let(2, d, '茶水啤') for p in pmt([0,2,3,4]): # pet if n[2] != p[2]: continue # 瑞典人养狗 let(4, p, '鸟猫狗鱼') for c in pmt(range(1,5)): # cigarette if p[0] != c[3]: continue # 抽m烟的养鸟 if n[1] != c[1]: continue # 德国人抽p烟 if d[2] != c[2]: continue # 喝啤酒的抽s烟 if abs(c[0]-d[1]) != 1: continue # 抽b烟的挨着喝水的 if abs(c[0]-p[1]) != 1: continue # 抽b烟的挨着养猫的 let(3, c, 'bpsm') for r in a: print(''.join(r))
这样的题是如何编出来的呢?最少需要几个怎样的条件才能唯一确定?

HTML堆叠各层:
<html><head><meta charset="UTF-8"><style> body { display: flex; justify-content: center; align-items: center; } .container { position: relative; width: 300px; height: 300px; } table { position: absolute; width: 100%; height: 100%; border-collapse: collapse; mix-blend-mode: multiply; /* 关键属性 */ } td { text-align: center; padding: 10px; background: transparent !important; font: 16pt serif; } .controls { position: fixed; bottom: 20px; display: flex; gap: 10px; margin: 1rem 0; padding: 1rem; } input { position: relative; margin-right: 16px; width: 24px; height: 24px; vertical-align: middle; } </style></head><body> <div class="container" id="tableContainer"></div> <div class="controls"> <div style="font-size:150%"> <!-- 自闭合标签(void element)--> <input type="checkbox" value="0">1 <input type="checkbox" value="1">2 <input type="checkbox" value="2">3 <input type="checkbox" value="3">4 <input type="checkbox" value="4">5 </div> </div> <script> const data = [ '挪 蓝 ', ' 奶 ', ' 绿白 咖 ', ' 英 红 ', '挪丹英德瑞黄蓝红绿白水茶奶咖啤dbmps猫马鸟鱼狗' ]; const colors = [ 'rgba(60, 179, 113, 0.6)', // 海洋绿 'rgba(30, 144, 255, 0.6)', // 道奇蓝 'rgba(238, 130, 238, 0.6)', // 紫罗兰 'rgba(255, 215, 0, 0.6)', // 金色 'rgba(218, 112, 214, 0.6)' // 兰花粉 ]; let container = document.getElementById('tableContainer'); let tables = []; function createTable(index) { const table = document.createElement('table'); for (let i = 0; i < 5; i++) { const row = document.createElement('tr'); for (let j = 0; j < 5; j++) { const cell = document.createElement('td'); cell.textContent = data[index][i * 5 + j] row.appendChild(cell) } table.appendChild(row); } table.style.backgroundColor = colors[index]; tables.push(table); container.appendChild(table); } for (let i = 0; i < 5; i++) createTable(i); document.querySelectorAll('input').forEach( cb => { cb.setAttribute('checked', true) // 箭头函数的this继承自外层作用域(词法作用域),定义时就已经确定且无法改变。 // 与传统函数动态绑定this不同。 cb.addEventListener('change', function() { let i = parseInt(this.value) tables[i].style.display = this.checked ? 'table' : 'none' }); }) </script></body></html>
在HTML中,void元素(如<input>、<img>等)可以写成自闭合形式(即带有/的结束标记),但这不是强制要求。现代HTML5规范中,自闭合的/是可选的,更倾向于简化写法。
下面的截图是CSS Tricks网站的首页:

我那个程序,可能因为body的background是white,混合后颜色很难看。
浙公网安备 33010602011771号