きなこの精進日記[python]

tenka1-2012-qualC B - ロイヤルストレートフラッシュ解説[python]

実装で詰まって1時間くらいかけてしまった

概要

トランプの山札の並び順が与えられ、それを先頭から1枚ずつ引く。
最短でロイヤルストレートフラッシュを完成させる時、山札から引いたが、ロイヤルストレートフラッシュの型に使わなかったカードを引いた順に出力せよ

考察

それぞれのマーク(S,H,D,C)について、何ターン目までに10、J、Q、K、Aがでてくるかを数え、最短のものが終了時のターンになる。
使わないカードはマークを決めた後にそれ以外を求めればOK

実装

文字列で与えられるのでパースするのが本質な問題
11~13はJ,Q,K,Aと文字列で与えられ、数字の箇所も1文字と2文字(10)があるのでめんどくさい。

4回ループしても良いが、それぞれ長さ4のbit のリストを持ってどれが出たかの状態を管理する。

#!/usr/bin/env python3
# input
deck = input()
length = len(deck)
SHDC = [[0] * 5 for _ in range(4)]  # それぞれのマークの10~12が出たかを管理
pos = 0
Mark = "SHDC"
Flash = ["10", "J", "Q", "K", "A"]
remove_mark = ""
while True:
    if deck[pos + 1] in Flash or 50 <= ord(deck[pos + 1]) <= 57:
        mark = deck[pos]
        num = deck[pos + 1]
        pos += 2
    elif deck[pos + 2] in Mark:
        mark = deck[pos]
        num = deck[pos + 1]
        pos += 2
    else:
        mark = deck[pos]
        num = deck[pos + 1 : pos + 3]
        pos += 3
    if num in Flash:
        SHDC[Mark.index(mark)][Flash.index(num)] = 1
        if sum(SHDC[Mark.index(mark)]) == 5:
            remove_mark = mark
            break
    if pos >= length:
        break
ans = ""
cnt = 0
lim_pos = pos
pos = 0
while True:
    if deck[pos + 1] in Flash or 50 <= ord(deck[pos + 1]) <= 57:
        mark = deck[pos]
        num = deck[pos + 1]
        pos += 2
    elif deck[pos + 2] in Mark:
        mark = deck[pos]
        num = deck[pos + 1]
        pos += 2
    else:
        mark = deck[pos]
        num = deck[pos + 1 : pos + 3]
        pos += 3
    if mark == remove_mark and num in Flash:
        cnt += 1
        if cnt == 5:
            break
    else:
        # print(mark, remove_mark, num)
        ans += mark + num
    if pos >= lim_pos:
        break
if ans == "":
    print(0)
else:
    print(ans)

反省

実装:
 ほとんど同じコードを二回書いているので無駄な感じする。num とmark を別々に持たせたかったのでこうしたが、それぞれ別にリストに入れたらよかったっぽい。
 

次どうやったら早く溶けるか?
 考察を上に書いただけしか考えずに実装したのでもっと詰めてから実装するべき
 一致するかをリストで判定するのは楽なので積極的に使う。(種類が限られている時)
 2回目のwhile loop でpos を再度0 初期化する
 pos >= length でのbreakなど基本的なところでデバッグハマったので気を付ける。(while の時は特に終了条件)