あなたのスキルで飯は食えるか2

麻雀の手牌が入力として与えられたとき、「待ち」を出力するプログラムを書いてください。
1122335556799 :
“99”をアタマの両面か“55”“99”のシャボであるので、(123)(123)(555)(99)[67]、(123)(123)(55)(567)[99]、(123)(123)(99)(567)[55]が正解です。

http://www.itmedia.co.jp/enterprise/articles/1004/03/news002_2.html

SWI-Prologで再挑戦。

ソースコード

外部からpermutationの出力をくわすかわりに内部でselectを使うようにした。
各行の意味は前回とほぼ同じ。

tenpai([X],[x(X)]).
tenpai(Xs,[[X,X],x(Y,Z)]) :- select(X,Xs,R1), select(X,R1,[Y,Z]), Y=<Z, Z=<Y+2.
tenpai(Xs,[[X,X,X]|Ys])   :- select(X,Xs,R1), select(X,R1,R2), select(X,R2,R3), tenpai(R3,Ys).
tenpai(Xs,[[X,Y,Z]|Ys])   :- select(X,Xs,R1), Y is X+1, select(Y,R1,R2), Z is X+2, select(Z,R2,R3), tenpai(R3,Ys).

test(X,Z) :- tenpai(X,Y), msort(Y,Z).
tests(X,Z) :- setof(Y,test(X,Y),Z).

実行結果

待ちのところをx(…)であらわすようにした。

?- tests([1,1,2,2,3,3,5,5,5,6,7,9,9],X).

X = [[[1, 2, 3], [1, 2, 3], [5, 5], [5, 6, 7], x(9, 9)],
     [[1, 2, 3], [1, 2, 3], [5, 5, 5], [9, 9], x(6, 7)], 
     [[1, 2, 3], [1, 2, 3], [5, 6, 7], [9, 9], x(5, 5)]]

よし、今回は普通に結果がかえってくる。

おぼえがき

sortは重複排除もする。
純粋にソートだけするときはmsortを使う。