Skip to content

Instantly share code, notes, and snippets.

@junpeitsuji
Last active November 27, 2021 10:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save junpeitsuji/e335dd07a0fd8e30b4adba8031a93462 to your computer and use it in GitHub Desktop.
Save junpeitsuji/e335dd07a0fd8e30b4adba8031a93462 to your computer and use it in GitHub Desktop.
###
# 素数大富豪で出せるかどうかを判定する関数
#
# 素数大富豪で出せるかどうか判定する関数
#
# arguments:
# number: 判定したい数(str型)
# debug: デバッグモードかどうか(bool型・任意)
#
# return:
# True or False
#
# Part 1:4〜9までのカードが使用されたか
# を実行し残りの処理は Part 2 に引き継ぐ
def is_primeqk_number(number, debug=False):
if debug:
print(number)
size = len(number)
if size <= 1:
return True
# 使用したカードの枚数をカウントする変数
cards = [0 for _ in range(14)] # Jokerは 0
# numberについて1文字ずつ判定する
for i in range(size):
a = int(number[i])
# 4 - 9 について判定
if 4 <= a and a <= 9:
number = set_ast(number, i)
count_card(cards, a)
return is_primeqk_number_part_2(number, cards, debug)
# Part 2:2つの数の組を再帰的に処理する
def is_primeqk_number_part_2(number, cards, debug=False):
size = len(number)
if debug:
print_current_state(number, cards)
joker_index = 0
if cards[joker_index] > 2:
# ジョーカーの個数が 2 より大きい場合は False
return False
else:
# ジョーカーの個数が 2 個以下
check_string = '*' * size # '*' を size 個分並べた文字列を生成
if number == check_string:
# numberの各桁がすべて '*' であれば True
return True
# 新しい変数にコピー
new_number = number
new_cards = [x for x in cards]
# 2桁ずつセットで判定
for i in range(size-1):
if new_number[i] != '*' and new_number[i+1] != '*':
# ab型(どちらも '*' ではない)の判定
a = int(new_number[i])
b = int(new_number[i+1])
ab = 10*a + b
# ab型①: abを1つの数だと思って再帰的に実行する
if 10 <= ab and ab <= 13:
new_number = set_ast(new_number, i)
new_number = set_ast(new_number, i+1)
count_card(new_cards, ab)
if is_primeqk_number_part_2(new_number, new_cards, debug):
return True
# ab型②: ①がFalseだった場合, aの方だけ '*' に変更する
new_number = number # 再度コピーし直す
new_cards = [x for x in cards] # 再度コピーし直す
new_number = set_ast(new_number, i)
count_card(new_cards, a)
break
elif new_number[i] != '*' and new_number[i+1] == '*':
# a*型の判定
a = int(new_number[i])
new_number = set_ast(new_number, i)
count_card(new_cards, a)
break
elif i == size-2 and new_number[i] == '*' and new_number[i+1] != '*':
# *b型(末尾型)の判定
b = int(new_number[i+1])
new_number = set_ast(new_number, i+1)
count_card(new_cards, b)
break
# 再帰的に実行
return is_primeqk_number_part_2(new_number, new_cards, debug)
# 現在の状態を表示する
def print_current_state(number, cards):
card_labels = ['X','1','2','3','4','5','6','7','8','9','T','J','Q','K']
print(number, '{'+', '.join([card_labels[i]+':'+str(cards[i]) for i in range(len(cards))])+'}')
# s の index 番目にアスタリスクを代入した文字列を返す
def set_ast(s, index):
return s[:index] + '*' + s[index+1:]
# index番目のカードの使用回数をカウントする処理
def count_card(cards, index):
joker_index = 0
# index番目のカードの使用回数をカウント
cards[index] += 1
# 超過した分はジョーカーに回す
if cards[index] > 4:
cards[joker_index] += (cards[index] - 4)
cards[index] = 4
if __name__ == '__main__':
# テスト用のコード
s = "246810121"
print( is_primeqk_number(s, True) ) # => True
print('')
s = "246801121"
print( is_primeqk_number(s, True) ) # => True
print('')
s = "40009"
print( is_primeqk_number(s, True) ) # => False
print('')
s = "1111111111111111"
print( is_primeqk_number(s, True) ) # => True
print('')
# 計算結果の量が多いのでdebug = Falseで実行
s = "11111111111111111"
print(s)
print( is_primeqk_number(s) ) # => False
print('')
@prinum2357
Copy link

prinum2357 commented Nov 27, 2021

すみません。数え間違えていました。。。
以下の内容は無視してください

ーーー元のコメントーーー

以下の数字で正しく判定できていないことを確認しました

コード(抜粋)

    s = "113113113113113113113113113113"
    print(s)
    print( is_primeqk_number(s) ) # => False
    print('')

実行結果

113113113113113113113113113113
False

カードとしては AKAKAKAKJ3J3J3J3XX (X=1,13) です

113 の数列の処理の際にJとして処理するかKとして処理するかを考慮する必要がありそう?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment