http://nabetani.sakura.ne.jp/hena/ord5dahimi/
で出題された大貧民をPythonで解くことに挑戦してみる。
もう、どうしようという感じでテストコードが通らないまま投稿してしまう。
多分、目視では正解していると思うのですが。
出せる手札の組み合わせを計算するのにitertoolsを使ってみた。
計算した組み合わせの中から出せる手札を探して回る作戦。
複数枚手札を出す場合の結果と期待値が同じ並びにならないので、テストコードが通らない。
結果の比較の仕方をもっと工夫しないとうまくいかない。ぐぬぬ。
2017/7/23追記
コメントいただいた内容を参考に、テストコードを通るように修正。
同じランクが出せていたバグを発見したので、こっそり修正。 test("C7H7,S7CTH8D5HACQS8JoD6SJS5H4", "HAJo,JoSJ,H8S8,H8Jo,CQJo,CTJo,JoS8" );
でC7Joも出せる手札に加わっていた。
yhpg05.py
# !/usr/bin/env python3
# -*- coding:utf-8 -*-
# https://yhpg.doorkeeper.jp/
# http://nabetani.sakura.ne.jp/hena/ord5dahimi/
import itertools
# 数値の大小で求められるように都合よく変換する
converter = {
"3":0,
"4":1,
"5":2,
"6":3,
"7":4,
"8":5,
"9":6,
"T":7,
"J":8,
"Q":9,
"K":10,
"A":11,
"2":12,
"o":13
}
def solve(data):
data = data.split(",")
field = list(sorted([data[0][i: i+2] for i in range(0, len(data[0]), 2)]))
hands = [data[1][i: i+2] for i in range(0, len(data[1]), 2)]
# 手札にあるカードで場に出ている枚数を出す場合の組み合わせを作っておく
hands = list(sorted(itertools.combinations(hands,len(field))))
# 出せる手札が1枚もない場合は終わり
if len(hands) == 0:
return list("-")
result = []
if len(field) == 1:
#場が1枚だけカードが出ている
for hand in hands:
if isAvailableCard(field[0][1:2], hand[0][1:2]):
result.append(hand[0])
else:
#場に2枚以上カードが出ている
#場の値がいくつなのか取得する
num = getFieldNum(field)
#手札から出せるカードを調べる
temp = []
temp.append(getAvailableCards(num,hands))
temp = temp[0]
for card in temp:
result.append("".join(card))
if len(result) == 0:
return list("-")
else:
return result
# 場に2枚以上カードが出ている場合のランクから計算用の値に変換して返す
def getFieldNum(field):
for card in field:
if card == "Jo":
#ジョーカーは無視
continue
else:
#同じランクの同時出ししか対応しないので、最初に見つけたのを返す
return converter[card[1]]
# 場にカードが一枚しか出ていない前提で手持ちのカードが出せる場合はtrueが返る
def isAvailableCard(field, hand):
return converter[field] < converter[hand]
# 場にカードが2枚以上出されている場合に、出せる手札のlistを作成して返す
def getAvailableCards(num, hands):
result = []
for cards in hands:
for card in cards:
if card == "Jo":
#ジョーカーは無視
continue
else:
#if converter[card[1]] < num:
if converter[card[1]] <= num:
continue
else:
#ほかの組がすべて同じランクだったら、出せる手札
if isSameRank(cards):
result.append(cards)
break
return result
# ランクがすべて同じ値ならtrueを返す
def isSameRank(cards):
rank = -1
for card in cards:
if card == "Jo":
#ジョーカーは無視
continue
else:
if rank == -1:
rank = card[1]
else:
if rank == card[1]:
continue
else:
#違うランクが含まれている場合はNG
return False
# ここまで来た場合はすべてのカードが同じランク
return True
def test(data, expect):
def sort(hands):
result = []
for hand in hands:
result.append(sorted([hand[i: i+2] for i in range(0, len(hand), 2)]))
return sorted(result)
result = solve(data)
expect = sort(expect.split(","))
result = sort(result)
if result == expect:
print("成功: " , result , "/" , expect )
else:
print("失敗: " , result , "/" , expect )
test( "DJ,", "-" );
test( "H7,HK", "HK" );
test( "S3,D4D2", "D4,D2" );
test( "S9,C8H4", "-" );
test( "S6,S7STCK", "CK,ST,S7" );
test( "H4,SAS8CKH6S4", "S8,CK,H6,SA" );
test( "ST,D6S8JoC7HQHAC2CK", "Jo,C2,CK,HA,HQ" );
test( "SA,HAD6S8S6D3C4H2C5D4CKHQS7D5", "H2" );
test( "S2,D8C9D6HQS7H4C6DTS5S6C7HAD4SQ", "-" );
test( "Jo,HAC8DJSJDTH2", "-" );
test( "S4Jo,CQS6C9DQH9S2D6S3", "DQCQ,D6S6,H9C9" );
test( "CTDT,S9C2D9D3JoC6DASJS4", "JoC2,SJJo,DAJo" );
test( "H3D3,DQS2D6H9HAHTD7S6S7Jo", "JoHA,JoD6,JoH9,D6S6,D7S7,JoS6,HTJo,JoDQ,S2Jo,JoD7,JoS7" );
test( "D5Jo,CQDAH8C6C9DQH7S2SJCKH5", "CQDQ" );
test( "C7H7,S7CTH8D5HACQS8JoD6SJS5H4", "HAJo,JoSJ,H8S8,H8Jo,CQJo,CTJo,JoS8" );
test( "SAHA,S7SKCTS3H9DJHJH7S5H2DKDQS4", "-" );
test( "JoC8,H6D7C5S9CQH9STDTCAD9S5DAS2CT", "CTDT,H9D9,S9D9,DACA,CTST,H9S9,DTST" );
test( "HTST,SJHJDJCJJoS3D2", "DJCJ,SJDJ,JoHJ,CJHJ,SJJo,HJSJ,DJJo,JoCJ,JoD2,SJCJ,DJHJ" );
test( "C7D7,S8D8JoCTDTD4CJ", "D8S8,JoS8,CTJo,DTJo,JoCJ,CTDT,D8Jo" );
test( "DJSJ,DTDKDQHQJoC2", "JoDK,HQDQ,DQJo,C2Jo,JoHQ" );
test( "C3H3D3,CKH2DTD5H6S4CJS5C6H5S9CA", "S5H5D5" );
test( "D8H8S8,CQHJCJJoHQ", "JoCQHQ,JoHJCJ" );
test( "H6D6S6,H8S8D8C8JoD2H2", "D2H2Jo,D8JoS8,D8S8C8,C8D8H8,JoC8S8,H8JoC8,S8H8C8,JoS8H8,C8JoD8,D8H8S8,D8JoH8" );
test( "JoD4H4,D3H3S3C3CADASAD2", "DACASA" );
test( "DJHJSJ,SQDQJoHQCQC2CA", "SQJoCQ,DQCQJo,JoSQHQ,SQCQHQ,DQHQSQ,HQDQCQ,HQDQJo,SQDQCQ,CQJoHQ,SQJoDQ" );
test( "H3D3Jo,D4SKH6CTS8SAS2CQH4HAC5DADKD9", "HASADA" );
test( "C3JoH3D3,S2S3H7HQCACTC2CKC6S7H5C7", "-" );
test( "H5C5S5D5,C7S6D6C3H7HAH6H4C6HQC9", "C6D6S6H6" );
test( "H7S7C7D7,S5SAH5HAD5DAC5CA", "SADACAHA" );
test( "D4H4S4C4,S6SAH6HAD6DAC6CAJo", "C6H6S6D6,SAJoDACA,S6H6C6Jo,SACAJoHA,HADASAJo,HADAJoCA,CADAHASA,D6C6JoH6,S6D6C6Jo,H6JoS6D6" );
test( "DTCTSTHT,S3SQH3HQD3DQC3CQJo", "HQSQJoDQ,SQCQDQJo,DQCQHQJo,SQHQJoCQ,CQDQHQSQ" );
test( "JoS8D8H8,S9DTH9CTD9STC9CAC2", "H9C9D9S9" );