LoginSignup
2
2

More than 5 years have passed since last update.

シェリルの誕生日

Last updated at Posted at 2018-01-03

追記: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']



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

2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2