※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

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

プロジェクトオイラー問54」の最新版変更点

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

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

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