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']



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

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.