http://ja.doukaku.org/34/ 挑戦しましたが、難しくて解けませんでした。AさんにもBさんにもなれません。 nkmrtksさんが、Common Lispで解いてます。(すごいです) 読んでも、理解できたようなできないような。
|-`)【こんにちは】ナカノヒトです。
解り難いコードでごめんなさい(ー人ー)
#1610 を解説してみます。
まず(dotimes)のネストでカードの組み合わせリストを作ります。
ついでに積、和の計算結果もくっつけてます。
最初のsetfでは、
下の(mapcar)で積が単一のものを、答えになりえない組み合わせとしてnilにしてます。
上の(mapcar)で和が単一のものを、答えになりえない組み合わせと判定してます。
#解説してて内部関数pluralpが真逆の名前になってることに気づきましたorz ダメスギル
#このせいで混乱させていたとしたらゴメンナサイorz
これは積や和が単一だと、組み合わせが一意に決まって
> Aさん「(この情報だけでは)分かりません」
> Bさん「私も分かりません.
とならないからです。
次のsetfでは、Bさんの爆弾発言を処理しています。
単一でない和のリスト(実際は1+1,1+2,12+13,13+13を除いた4~24の連番)を作り
それを元に、和が同じカードの組み合わせのリストのリストを作ります。
そして和が同じ組み合わせの中で、ひとつでも積がnilのリストを除外します。
これは、「Aさんが『分かりません』というのは分かってい」るためには
自分(B)が知っている和になり得る組み合わせの積の、全てが一意であってはいけないからです。
一意であったら、Aさんは最初の段階で組み合わせが分かってしまうのです。
そしてそれを聞いたAさんが「それなら,分かりました」となるには
この段階のリストでの和が一意でなければならないのです。
和が複数であった場合、考えられる積が複数あることを示し、つまりは組み合わせの可能性が複数あるからです。
そして、同様に積が一意のものを見つければ晴れて解答である(1 4)という組み合わせのみが残ります。
…長文の上、解り難くてゴメンナサイorz