Prolog - 乐透机

时间:2015-03-10 15:14:55

标签: list random prolog rules

这是我的第一篇文章。我一直在教自己Prolog的大学项目,我的任务是生成一个模拟乐透的程序,并将随机数(在这种情况下为6)与用户拥有的数字进行比较。如果它们都匹配,那么如果没有你就会被视为胜利者,那么它就会回归“运气不好”。

我迄今为止所做的就是在1-50范围内生成一个随机数。之后我不知道该怎么做。

  

: - use_module(library(random))。

     

? - 随机(1,50,Out)。

我知道我必须将随机数添加到列表中,但我不确定如何实现它。然后在数据库或事实库中有另一个数字列表(user_numbers)。然后使用SWI-Prolog检查它们是否相等。

对我来说,在Prolog中尝试做是一个非常艰难的计划,尤其是看到我正在教给自己。如果有人能给我一些关于如何处理它的指示,我将非常感激。

1 个答案:

答案 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).