「プロジェクトオイラー問54」の編集履歴(バックアップ)一覧はこちら

プロジェクトオイラー問54」(2014/02/20 (木) 03:00:56) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2054 *Problem 54 「ポーカーハンド」 † ポーカーの勝敗を判定する問題。 詳細はリンク先を参照のこと。 解法 世界中で何回ポーカーの役判定のコードが書かれたのだろうかと思いをはせる問題です。 両者ともに素朴に役を判定して役に対応したスコアと役で使ったカードの数字を返し、 Aのほうがスコアが大きいなら勝利、同じならカードを比べてAの勝利か判定するだけ。 1を14として取り扱うと話が綺麗になります。 判定には巧みな手法があるそうなのでそれを調べるのもいいかもしれませんね。 max(A,B,A):-A>B,!. max(_,B,B):-!. min(A,B,A):-A<B,!. min(_,B,B):-!. toNum(84,10):-!. toNum(74,11):-!. toNum(81,12):-!. toNum(75,13):-!. toNum(65,14):-!. toNum(N,N1):-!,N1 is N-48. last([X],X):-!. last([_|Xs],Result):- !, last(Xs,Result). count([],Count,Result):- !, sort(Count,Count1), reverse(Count1,Result). count([[N,_]|Rest],Count,Result):- select([C,N],Count,Count1), !, C1 is C+1, count(Rest,[[C1,N]|Count1],Result). count([[N,_]|Rest],Count,Result):- !, count(Rest,[[1,N]|Count],Result). cards_toNum([],[]):-!. cards_toNum([[Y,S]|Rest],[[N,S]|Result]):- !, toNum(Y,N), cards_toNum(Rest,Result). % ロイヤルフラッシュ yaku1([[14,X],[10,X],[11,X],[12,X],[13,X]],9000,[14,13,12,11,10]):-!. % ストレートフラッシュ yaku1([[N1,X],[N2,X],[N3,X],[N4,X],[N5,X]],8000,[N5,N4,N3,N2,N1]):- N2=:=N1+1, N3=:=N2+1, N4=:=N3+1, N5=:=N4+1, !. % フラッシュ yaku1([[N1,X],[N2,X],[N3,X],[N4,X],[N5,X]],5000,[N5,N4,N3,N2,N1]):-!. % ストレート yaku1([[N1,_],[N2,_],[N3,_],[N4,_],[N5,_]],4000,[N5,N4,N3,N2,N1]):- N2=:=N1+1, N3=:=N2+1, N4=:=N3+1, N5=:=N4+1, !. yaku1([[N1,_],[N2,_],[N3,_],[N4,_],[N5,_]],0,[N5,N4,N3,N2,N1]):-!. %4Card yaku2([[4,N1]|_],7000,[N1]):- !. %fullHouse yaku2([[3,N1],[2,N2]],6000,[ReN2,ReN1]):- !, max(N1,N2,ReN2), min(N1,N2,ReN1). %3Card yaku2([[3,N1]|_],3000,[N1]):-!. %2pare yaku2([[2,N1],[2,N2]|_],2000,[ReN2,ReN1]):- !, max(N1,N2,ReN2), min(N1,N2,ReN1). %1pare yaku2([[2,N1]|_],1000,[N1]):-!. yaku2(_,0,[0]):-!. calc_yaku(Cards,[Score,Nums]):- yaku1(Cards,Score,Nums). calc_yaku(Cards,[Score,Nums]):- count(Cards,[],Count), yaku2(Count,Score,Nums). calc_yaku_w(Cards,Result):- cards_toNum(Cards,Cards1), sort(Cards1,Cards2), findall(Set,calc_yaku(Cards2,Set),Sets), sort(Sets,Sets1), last(Sets1,Result). is_big([],[]):-!,fail. is_big([_|_],[]):-!. is_big([X|_],[Y|_]):-X<Y,!,fail. is_big([X|_],[Y|_]):-X>Y,!. is_big([_|Xs],[_|Ys]):- !, is_big(Xs,Ys). isV(Cards1,Cards2,V,V1):- calc_yaku_w(Cards1,[Score1,Nums1]), calc_yaku_w(Cards2,[Score2,Nums2]), (Score1>Score2 -> V1 is V+1; ((Score1=:=Score2,is_big(Nums1,Nums2))-> V1 is V+1;V1 is V)). myread(IS,V):-at_end_of_stream(IS),!,close(IS),write(V). myread(IS,V):- read_term(IS,Cards,[]), [A1,A2,A3,A4,A5,B1,B2,B3,B4,B5]=Cards, isV([A1,A2,A3,A4,A5],[B1,B2,B3,B4,B5],V,V1), myread(IS,V1). main54:- open('pe54.txt',read,IS), myread(IS,0).
http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2054 *Problem 54 「ポーカーハンド」 † ポーカーの勝敗を判定する問題。 詳細はリンク先を参照のこと。 解法 世界中で何回ポーカーの役判定のコードが書かれたのだろうかと思いをはせる問題です。 両者ともに素朴に役を判定して役に対応したスコアと役で使ったカードの数字を返し、 Aのほうがスコアが大きいなら勝利、同じならカードを比べてAの勝利か判定するだけ。 1を14として取り扱うと話が綺麗になります。 判定には巧みな手法があるそうなのでそれを調べるのもいいかもしれませんね。 ファイルは一行ごと10枚のカードを現すリストと変換しています。 max(A,B,A):-A>B,!. max(_,B,B):-!. min(A,B,A):-A<B,!. min(_,B,B):-!. toNum(84,10):-!. toNum(74,11):-!. toNum(81,12):-!. toNum(75,13):-!. toNum(65,14):-!. toNum(N,N1):-!,N1 is N-48. last([X],X):-!. last([_|Xs],Result):- !, last(Xs,Result). count([],Count,Result):- !, sort(Count,Count1), reverse(Count1,Result). count([[N,_]|Rest],Count,Result):- select([C,N],Count,Count1), !, C1 is C+1, count(Rest,[[C1,N]|Count1],Result). count([[N,_]|Rest],Count,Result):- !, count(Rest,[[1,N]|Count],Result). cards_toNum([],[]):-!. cards_toNum([[Y,S]|Rest],[[N,S]|Result]):- !, toNum(Y,N), cards_toNum(Rest,Result). % ロイヤルフラッシュ yaku1([[14,X],[10,X],[11,X],[12,X],[13,X]],9000,[14,13,12,11,10]):-!. % ストレートフラッシュ yaku1([[N1,X],[N2,X],[N3,X],[N4,X],[N5,X]],8000,[N5,N4,N3,N2,N1]):- N2=:=N1+1, N3=:=N2+1, N4=:=N3+1, N5=:=N4+1, !. % フラッシュ yaku1([[N1,X],[N2,X],[N3,X],[N4,X],[N5,X]],5000,[N5,N4,N3,N2,N1]):-!. % ストレート yaku1([[N1,_],[N2,_],[N3,_],[N4,_],[N5,_]],4000,[N5,N4,N3,N2,N1]):- N2=:=N1+1, N3=:=N2+1, N4=:=N3+1, N5=:=N4+1, !. yaku1([[N1,_],[N2,_],[N3,_],[N4,_],[N5,_]],0,[N5,N4,N3,N2,N1]):-!. %4Card yaku2([[4,N1]|_],7000,[N1]):- !. %fullHouse yaku2([[3,N1],[2,N2]],6000,[ReN2,ReN1]):- !, max(N1,N2,ReN2), min(N1,N2,ReN1). %3Card yaku2([[3,N1]|_],3000,[N1]):-!. %2pare yaku2([[2,N1],[2,N2]|_],2000,[ReN2,ReN1]):- !, max(N1,N2,ReN2), min(N1,N2,ReN1). %1pare yaku2([[2,N1]|_],1000,[N1]):-!. yaku2(_,0,[0]):-!. calc_yaku(Cards,[Score,Nums]):- yaku1(Cards,Score,Nums). calc_yaku(Cards,[Score,Nums]):- count(Cards,[],Count), yaku2(Count,Score,Nums). calc_yaku_w(Cards,Result):- cards_toNum(Cards,Cards1), sort(Cards1,Cards2), findall(Set,calc_yaku(Cards2,Set),Sets), sort(Sets,Sets1), last(Sets1,Result). is_big([],[]):-!,fail. is_big([_|_],[]):-!. is_big([X|_],[Y|_]):-X<Y,!,fail. is_big([X|_],[Y|_]):-X>Y,!. is_big([_|Xs],[_|Ys]):- !, is_big(Xs,Ys). isV(Cards1,Cards2,V,V1):- calc_yaku_w(Cards1,[Score1,Nums1]), calc_yaku_w(Cards2,[Score2,Nums2]), (Score1>Score2 -> V1 is V+1; ((Score1=:=Score2,is_big(Nums1,Nums2))-> V1 is V+1;V1 is V)). myread(IS,V):-at_end_of_stream(IS),!,close(IS),write(V). myread(IS,V):- read_term(IS,Cards,[]), [A1,A2,A3,A4,A5,B1,B2,B3,B4,B5]=Cards, isV([A1,A2,A3,A4,A5],[B1,B2,B3,B4,B5],V,V1), myread(IS,V1). main54:- open('pe54.txt',read,IS), myread(IS,0).

表示オプション

横に並べて表示:
変化行の前後のみ表示: