追記: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']
ご指摘、よろしくお願いいたします...