最近出现的代码挑战之一要求我解决最少量的输入材料,我可以使用这些材料来应用一组给定的反应并获得 1 个单位的输出材料。
例如,给定
10 ORE => 10 A
1 ORE => 1 B
7 A, 1 B => 1 C
7 A, 1 C => 1 D
7 A, 1 D => 1 E
7 A, 1 E => 1 FUEL
我们总共需要 31 块矿石来制造 1 种燃料(1 块用来生产单位 B,然后 30 块用来制造必需的 28 A)。
今年,我一直在努力拓展我的编程语言视野,所以我已经完成了 SML/NJ 的大部分挑战。这个似乎——<em>似乎——很适合 Prolog,考虑到我对它的了解很少:逻辑编程、约束求解等。
但是,我无法成功地对约束进行建模。
我首先把这个简单的例子变成了一些事实:
makes([ore(10)], a(10)).
makes([ore(1)], b(1)).
makes([a(7), b(7)], c(1)).
makes([a(7), c(1)], d(1)).
makes([a(7), d(1)], e(1)).
makes([a(7), e(1)], fuel(1)).
老实说,我什至不确定 list 参数是否是一个好的结构,或者函子表示法 ( ore(10)
) 是否是一个好的模型。
然后我想建立允许你说的规则,例如,10 矿石足够 7 a:
% handles the case where we have leftovers?
% is this even the right way to model all this... when we have leftovers, we may
% have to use them in the "reaction"...
makes(In, Out) :-
Out =.. [F,N],
Val #>= N,
OutN =.. [F,Val],
makes(In, OutN).
这可行1,但我不确定它是否足够,因为我们可能会关心剩菜(毕竟这是一个最小化问题)?
我被困在接下来的两件事情上:
- 我可以问是什么使 7 A 得到 10 矿石,但我不能问什么才足够 20 A:我如何编写一个编码乘法/整数因子的规则?
- 我可以说 7 A 和 1 E 制造 1 种燃料,但我不能递归地说明这一点:也就是说,我不能说 14 A 和 1 D也制造 1 种燃料。如何编写对此进行编码的规则?
我愿意为我提出的事实使用替代数据编码——最终,我将编写从 Advent 的输入到 Prolog 的事实的转换脚本,所以这是我最不担心的。我觉得如果我能让这个小例子工作,我可以解决更大的问题。
?- makes(X, a(7)).
无限回馈X=[ore(10)]
(即,如果我一直;
按提示,它会继续)。有没有办法来解决这个问题?