小时候在《科学画报》上看到过,不会。长大后会编程了,能做到试3!×3!×4!×4!次了,又发现手工可解。

先看手工:用个5x5的表格表示状态,行依次是:国籍、房子颜色、饮料、香烟、宠物。表格初始空白。

“挪威人住第一间房,挪威人住蓝房子隔壁,住中间房子的喝牛奶”:

Screenshot_20251018_134308

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

Screenshot_20251018_135726

上图这一块,往哪儿插呢?或者多层透明塑料上写的有字,叠起来后字不能挡住字。

HTML+CSS/Canvas, Python (Pillow)等等都可以alpha blend, AI还特别喜欢overkill,下图是CSS做的:

Screenshot_20251018_134654

这倒是也可以开发个“游戏”: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))

这样的题是如何编出来的呢?最少需要几个怎样的条件才能唯一确定?

Screenshot_20251018_150808

 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>
View Code

在HTML中,void元素(如<input>、<img>等)可以写成自闭合形式(即带有/的结束标记),但这不是强制要求。现代HTML5规范中,自闭合的/是可选的,更倾向于简化写法。

下面的截图是CSS Tricks网站的首页:

Screenshot_20251019_233909

我那个程序,可能因为body的background是white,混合后颜色很难看。

posted on 2025-10-18 13:55  华容道专家  阅读(15)  评论(0)    收藏  举报