シェリルの誕生日

追記：2018/06/26

誕生日から問題を作成するプログラムも書きました。
https://qiita.com/hnkyi/items/43459e72c19348b322e6

----

Twitterで見かけたツイート。
https://twitter.com/izakayanotenin/status/947705747852337152

パッと見た感じ分からず、
リプ欄で確認して納得したんですが、
プログラムに落とし込めないかなと思い、書いてみました。

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

- アルバートとバーナードが消え去ってしまった...
    - どこかで使ってあげたい...
- Listを何回も二重ループしてるのでパフォーマンス悪そうだし、見た目も格好悪い
    - イケてるコードをさらっと書けるようになりたい...
    - 誰かご指摘お願いいたします。申し訳ありません...

###コード
今回は`Python3`で書きました。

```py3
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#
# 『シェリルの誕生日』
#
# 出題元：
# 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']
```

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