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

http://d.hatena.ne.jp/katona/20100422/p1
こっちに修正版を書きました

麻雀の手牌が入力として与えられたとき、「待ち」を出力するプログラムを書いてください。
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で挑戦してみた。

tenpai([X],[[X]]).                                                  %単騎待ち
tenpai([X,X,Y,Z],[[X,X],[Y,Z]]) :- Y=<Z, Z=<Y+2.                    %Zの値が、Yならシャボ、Y+1なら両面or辺張、Y+2なら嵌張待ち
tenpai([X,X,X|Xs],[[X,X,X]|Ys]) :- tenpai(Xs,Ys).                   %刻子あり
tenpai([X,Y,Z|Xs],[[X,Y,Z]|Ys]) :- Y=:=X+1, Z=:=X+2, tenpai(Xs,Ys). %順子あり

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

実行結果
(見やすいように改行を入れてる)

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

さすがに力任せすぎだった。
本番のtests([1,1,2,2,3,3,5,5,5,6,7,9,9],X).のクエリは時間切れで終わらず(笑)。

おぼえがき

「以下」は、<=ではなくて、=<を使うので注意。
「以上」は、普通の言語と同じで>=。
setofはbagofの結果をソートして重複排除する。
SWI-Prolog では解の表示が省略されたときは w を押すと全部表示してくれる。