这是我的第一篇文章。我一直在教自己Prolog的大学项目,我的任务是生成一个模拟乐透的程序,并将随机数(在这种情况下为6)与用户拥有的数字进行比较。如果它们都匹配,那么如果没有你就会被视为胜利者,那么它就会回归“运气不好”。
我迄今为止所做的就是在1-50范围内生成一个随机数。之后我不知道该怎么做。
: - use_module(library(random))。
? - 随机(1,50,Out)。
我知道我必须将随机数添加到列表中,但我不确定如何实现它。然后在数据库或事实库中有另一个数字列表(user_numbers)。然后使用SWI-Prolog检查它们是否相等。
对我来说,在Prolog中尝试做是一个非常艰难的计划,尤其是看到我正在教给自己。如果有人能给我一些关于如何处理它的指示,我将非常感激。
答案 0 :(得分:1)
pick_number(N) :- random(1, 50, N).
我们需要选择6个数字的列表
lotto_numbers(Ns) :-
length(Ns, 6), % The length of our list is 6, now we have a list of 6 free variables.
select_numbers(Ns). % We need to select our numbers, binding them to our free variables.
select_numbers([]). % An empty list needs no picking
select_numbers([N|Ns]) :-
pick_number(N), % We pick the first number (bind the free variable to a random number)
select_numbers(Ns). % Then we pick the rest of the numbers.
我们需要检查持票人是否有中奖号码。数字的顺序是否重要?如果是,那么我们可以检查两个列表是否统一:LottoNumbers = LottoTicketNumbers
。如果我们不关心订单,那么我们需要一个稍微复杂的解决方案:
numbers_match([], []). % if both lists are empty, then they must have all matched.
numbers_match([N|Ns], Ms) :-
select(N, Ms, NewMs), % remove N from Ms (if N matches an element in Ms), leaving NewMs
numbers_match(Ns, NewMs). % remove the rest of Ns from NewMs.
如果两个列表同时没有清空,那么它们都不会匹配。 假设我们在数据库中有一些loto票,
lotto_ticket(Ns) :- lotto_numbers(Ns).
通过我们程序中的所有上述定义,我们可以生成乐透票,并生成一些乐透号码(实际上是相同的过程,但出于说明目的而命名不同),并查看它们是否具有全部且仅相同的数字:
?- lotto_ticket(T), lotto_numbers(L), numbers_match(T, L).
false.
阿。毫不奇怪,我们失去了......
这一切都很好,但我们可以通过使用更高阶来节省很多步骤 谓词和一些常见的库谓词:
alt_lotto_numbers(Ns) :-
length(Ns, 6),
maplist(random(1,50), Ns). % `maplist/2` is just a way of calling a predicate on every member of a list.
alt_numbers_match(Ns, Ms) :-
same_length(Ns, Ms),
subset(Ns, Ms).