在序言中获取列表的分布
Get a distribution of a list in prolog
我想在序言中计算手牌的分布。
这意味着得到这个结果:
?- distribution([sq,s9,s8,ha,hk,h5,da,dk,dj,d4,ca,c7,c6],D).
D=[[spade,3],[heart,3],[diamond,4],[club,3]]
但我不知道如何进行。我可以使用以下脚本逐一获取每种颜色:
distribution([], []).
distribution([H|T], [E|D]):-
atom_chars(H, X),
nth0(0, X, E),
(
E == 's' -> distribution(T, D);
E == 'h' -> distribution(T, D);
E == 'd' -> distribution(T, D);
E == 'c' -> distribution(T, D)
).
谁能帮帮我?谢谢
一个可能的解决方案是:
distribution(Cards, Distribution) :-
distribution(Cards, [], Distribution).
distribution([], Distribution, Distribution).
distribution([Card|Cards], Accumulator, Distribution) :-
suit(Card, Suit),
update(Accumulator, Suit, NewAccumulator),
distribution(Cards, NewAccumulator, Distribution).
suit(Card, Suit) :-
atom_chars(Card, [First|_]),
text(First, Suit).
text(c, club).
text(s, spade).
text(h, heart).
text(d, diamond).
update([], Suit, [[Suit,1]]).
update([[S,N]|Rest], Suit, Distribution) :-
( S = Suit
-> succ(N, N1),
Distribution = [[S,N1]|Rest]
; Distribution = [[S,N]|Rest1],
update(Rest, Suit, Rest1) ).
示例:
?- distribution([sq,s9,s8,ha,hk,h5,da,dk,dj,d4,ca,c7,c6],D).
D = [[spade, 3], [heart, 3], [diamond, 4], [club, 3]].
备注 在 Prolog 中,将一对 [x,y]
表示为 x-y
.
形式的项更为惯用
使用swi-prolog built-in谓词,另一种可能的解决方案是:
distribution2(Cards, Distribution) :-
maplist(suit, Cards, Suits),
msort(Suits, SortedSuits),
clumped(SortedSuits, Distribution).
示例:
?- distribution2([sq,s9,s8,ha,hk,h5,da,dk,dj,d4,ca,c7,c6],D).
D = [club-3, diamond-4, heart-3, spade-3].
我想出了[编辑,使用来自 slago 的回答的 clumped
好多了]:
card_suite(Card, Suite) :- % from s5
atom_concat(Char, _, Card), % to s + 5 = s5
select(Char-Suite, [s-spade, h-heart, d-diamond, c-club], _). % to spade
cards_distribution(Cards, Distribution) :- % from [s5, c7, s2]
sort(0, @=<, Cards, SortedCards), % to [c7, s2, s5]
maplist(card_suite, SortedCards, Suites), % to [club, spade, spade]
clumped(Suites, Distribution). % to [club-1, spade-2]
例如
?- cards_distribution([sq,s9,s8,ha,hk,h5,da,dk,dj,d4,ca,c7,c6,s8],D).
D = [club-3, diamond-4, heart-3, spade-4]
相关logically pure group counting代码。
为什么不使用 复合词 表示卡片?
考虑红心皇后 ():hq
是一个原子,h(q)
是一个化合物。
这让事情变得简单多了:不需要排序并且一切都保持纯粹的关系。
cards_([],[],[],[],[]).
cards_([Card|Cards],Cs,Ds,Hs,Ss) :-
card_(Card,Cards,Cs,Ds,Hs,Ss).
card_(c(X),Cards,[X|Cs],Ds,Hs,Ss) :- cards_(Cards,Cs,Ds,Hs,Ss).
card_(d(X),Cards,Cs,[X|Ds],Hs,Ss) :- cards_(Cards,Cs,Ds,Hs,Ss).
card_(h(X),Cards,Cs,Ds,[X|Hs],Ss) :- cards_(Cards,Cs,Ds,Hs,Ss).
card_(s(X),Cards,Cs,Ds,Hs,[X|Ss]) :- cards_(Cards,Cs,Ds,Hs,Ss).
获取相应计数的示例查询:
?- Cards = [s(q),s(9),s(8),h(a),h(k),h(5),d(a),d(k),d(j),d(4),c(a),c(7),c(6)],
cards_(Cards,Clubs,Diamonds,Hearts,Spades),
length(Clubs,N_Clubs),
length(Diamonds,N_Diamonds),
length(Hearts,N_Hearts),
length(Spades,N_Spades).
Cards = [s(q),s(9),s(8),h(a),h(k),h(5),d(a),d(k),d(j),d(4),c(a),c(7),c(6)],
Clubs = [a,7,6],
Diamonds = [a,k,j,4],
Hearts = [a,k,5],
Spades = [q,9,8],
N_Clubs = 3,
N_Diamonds = 4,
N_Hearts = 3,
N_Spades = 3.
我想在序言中计算手牌的分布。 这意味着得到这个结果:
?- distribution([sq,s9,s8,ha,hk,h5,da,dk,dj,d4,ca,c7,c6],D).
D=[[spade,3],[heart,3],[diamond,4],[club,3]]
但我不知道如何进行。我可以使用以下脚本逐一获取每种颜色:
distribution([], []).
distribution([H|T], [E|D]):-
atom_chars(H, X),
nth0(0, X, E),
(
E == 's' -> distribution(T, D);
E == 'h' -> distribution(T, D);
E == 'd' -> distribution(T, D);
E == 'c' -> distribution(T, D)
).
谁能帮帮我?谢谢
一个可能的解决方案是:
distribution(Cards, Distribution) :-
distribution(Cards, [], Distribution).
distribution([], Distribution, Distribution).
distribution([Card|Cards], Accumulator, Distribution) :-
suit(Card, Suit),
update(Accumulator, Suit, NewAccumulator),
distribution(Cards, NewAccumulator, Distribution).
suit(Card, Suit) :-
atom_chars(Card, [First|_]),
text(First, Suit).
text(c, club).
text(s, spade).
text(h, heart).
text(d, diamond).
update([], Suit, [[Suit,1]]).
update([[S,N]|Rest], Suit, Distribution) :-
( S = Suit
-> succ(N, N1),
Distribution = [[S,N1]|Rest]
; Distribution = [[S,N]|Rest1],
update(Rest, Suit, Rest1) ).
示例:
?- distribution([sq,s9,s8,ha,hk,h5,da,dk,dj,d4,ca,c7,c6],D).
D = [[spade, 3], [heart, 3], [diamond, 4], [club, 3]].
备注 在 Prolog 中,将一对 [x,y]
表示为 x-y
.
使用swi-prolog built-in谓词,另一种可能的解决方案是:
distribution2(Cards, Distribution) :-
maplist(suit, Cards, Suits),
msort(Suits, SortedSuits),
clumped(SortedSuits, Distribution).
示例:
?- distribution2([sq,s9,s8,ha,hk,h5,da,dk,dj,d4,ca,c7,c6],D).
D = [club-3, diamond-4, heart-3, spade-3].
我想出了[编辑,使用来自 slago 的回答的 clumped
好多了]:
card_suite(Card, Suite) :- % from s5
atom_concat(Char, _, Card), % to s + 5 = s5
select(Char-Suite, [s-spade, h-heart, d-diamond, c-club], _). % to spade
cards_distribution(Cards, Distribution) :- % from [s5, c7, s2]
sort(0, @=<, Cards, SortedCards), % to [c7, s2, s5]
maplist(card_suite, SortedCards, Suites), % to [club, spade, spade]
clumped(Suites, Distribution). % to [club-1, spade-2]
例如
?- cards_distribution([sq,s9,s8,ha,hk,h5,da,dk,dj,d4,ca,c7,c6,s8],D).
D = [club-3, diamond-4, heart-3, spade-4]
相关logically pure group counting代码。
为什么不使用 复合词 表示卡片?
考虑红心皇后 ():hq
是一个原子,h(q)
是一个化合物。
这让事情变得简单多了:不需要排序并且一切都保持纯粹的关系。
cards_([],[],[],[],[]). cards_([Card|Cards],Cs,Ds,Hs,Ss) :- card_(Card,Cards,Cs,Ds,Hs,Ss). card_(c(X),Cards,[X|Cs],Ds,Hs,Ss) :- cards_(Cards,Cs,Ds,Hs,Ss). card_(d(X),Cards,Cs,[X|Ds],Hs,Ss) :- cards_(Cards,Cs,Ds,Hs,Ss). card_(h(X),Cards,Cs,Ds,[X|Hs],Ss) :- cards_(Cards,Cs,Ds,Hs,Ss). card_(s(X),Cards,Cs,Ds,Hs,[X|Ss]) :- cards_(Cards,Cs,Ds,Hs,Ss).
获取相应计数的示例查询:
?- Cards = [s(q),s(9),s(8),h(a),h(k),h(5),d(a),d(k),d(j),d(4),c(a),c(7),c(6)], cards_(Cards,Clubs,Diamonds,Hearts,Spades), length(Clubs,N_Clubs), length(Diamonds,N_Diamonds), length(Hearts,N_Hearts), length(Spades,N_Spades). Cards = [s(q),s(9),s(8),h(a),h(k),h(5),d(a),d(k),d(j),d(4),c(a),c(7),c(6)], Clubs = [a,7,6], Diamonds = [a,k,j,4], Hearts = [a,k,5], Spades = [q,9,8], N_Clubs = 3, N_Diamonds = 4, N_Hearts = 3, N_Spades = 3.