Edited at

シェリルの誕生日

More than 1 year has passed since last update.

追記:2018/06/26

誕生日から問題を作成するプログラムも書きました。

https://qiita.com/hnkyi/items/43459e72c19348b322e6


Twitterで見かけたツイート。

https://twitter.com/izakayanotenin/status/947705747852337152

パッと見た感じ分からず、

リプ欄で確認して納得したんですが、

プログラムに落とし込めないかなと思い、書いてみました。


プログラムを書いてみた感想。


  • アルバートとバーナードが消え去ってしまった...


    • どこかで使ってあげたい...



  • Listを何回も二重ループしてるのでパフォーマンス悪そうだし、見た目も格好悪い


    • イケてるコードをさらっと書けるようになりたい...

    • 誰かご指摘お願いいたします。申し訳ありません...




コード

今回はPython3で書きました。

# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

#
# 『シェリルの誕生日』
#
# 出題元:
# https://twitter.com/izakayanotenin/status/947705747852337152
#
# シェリルは、アルバートには何月かを、バーナードには何日かだけを、別々にこっそり教えます。
# アルバート:「僕はシェリルの誕生日がいつかはわからないんだけど、君も知らないって事だけは分かる」
# バーナード:「僕、最初はシェリルの誕生日がいつかわからなかったんだけど、今のでもう分かったよ」
# アルバート:「あ、じゃあ、僕も分かったよ」
#
# step1. 候補日を舐めて、重複していないdayを取得
# step2. 重複していないdayは、バーナードが誕生日を特定できるためFalse
# step3. step2により、重複していないdayのmonthは有り得ないため、そのmonthはFalse
# step4. 残る候補日のうち、重複しているdayを取得。重複している場合はバーナードが「分かった」と答えられないためFalse
# step5. 残る候補日のうち、重複していないmonthを取得(確定)
#
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

# 実際の誕生日
BIRTHDAY = "7/16"

# 候補日
candidates = [
"5/15", "5/16", "5/19",
"6/17", "6/18",
"7/14", "7/16",
"8/14", "8/15", "8/17"
]

# 今回使ってないけど、どうやって使ったらいいかな...
# albert_month = BIRTHDAY.split("/")[0]
# bernard_day = BIRTHDAY.split("/")[1]

# ユニークな日を探して、その月を削除(step1~3)
unique_days = []
for idx1 in range(0, len(candidates)):
is_unique = True
target_day1 = candidates[idx1].split("/")[1]
for idx2 in range(0, len(candidates)):
if idx1 == idx2:
continue
if target_day1 == candidates[idx2].split("/")[1]:
is_unique = False
break
if is_unique:
unique_days.append(target_day1)

remove_months = []
for candidate in candidates:
if candidate.split("/")[1] in unique_days:
remove_months.append(candidate.split("/")[0])

remove_dates = []
for candidate in candidates:
if candidate.split("/")[0] in remove_months:
remove_dates.append(candidate)

for remove_date in remove_dates:
candidates.remove(remove_date)

# 重複している日を見つけて、その日を削除(step4)
overlap_days = []
for idx1 in range(0, len(candidates)):
is_overlap = False
target_day1 = candidates[idx1].split("/")[1]
for idx2 in range(0, len(candidates)):
if idx1 == idx2:
continue
if target_day1 == candidates[idx2].split("/")[1]:
is_overlap = True
break
if is_overlap:
overlap_days.append(target_day1)

remove_dates = []
for candidate in candidates:
if candidate.split("/")[1] in overlap_days:
remove_dates.append(candidate)

for remove_date in remove_dates:
candidates.remove(remove_date)

# 重複している月を見つけて、その月を削除(step5)
overlap_months = []
for idx1 in range(0, len(candidates)):
is_overlap = False
target_day1 = candidates[idx1].split("/")[0]
for idx2 in range(0, len(candidates)):
if idx1 == idx2:
continue
if target_day1 == candidates[idx2].split("/")[0]:
is_overlap = True
break
if is_overlap:
overlap_months.append(target_day1)

remove_dates = []
for candidate in candidates:
if candidate.split("/")[0] in overlap_months:
remove_dates.append(candidate)

for remove_date in remove_dates:
candidates.remove(remove_date)

# 結果出力
if len(candidates) == 1 and BIRTHDAY in candidates:
print("Answer: Success!!!")
else:
print("Answer: Failure...")
print(" expected: " + BIRTHDAY)
print(" actual : " + str(candidates))


結果

Answer: Success!!!

expected: 7/16
actual : ['7/16']




ご指摘、よろしくお願いいたします...