年齢あてパズル on EmacsLisp
たまたま以下のパズルを見かけて、忙しかったのでといてみた:
最初は封筒裏で何とかなるかと思ったが、組み合わせが多くて面倒くさくなったので *scratch* での計算だ。何しろ編集しながらの計算なので、途中結果がすべて保全されているわけじゃないが、ご容赦:
2人の金髪の女性が通り沿いのカフェで座っていた。最初の女性は、彼女には3人の娘達がいると言った。3人の娘達の年齢を、それぞれ全て掛け合わせると36になること、それぞれ全て加えると、丁度、(そこからみえる)通りの向こう側の家の番号になるのだと言った。2番目の金髪の女性は、それだけの情報では3人の娘達のそれぞれの年齢は判らないと応えた。すると最初の女性はそのことを肯定し、さらに情報を付け加えて『一番上の娘は美しい青い目をしているのよ』と応じた。すると2番目の女性は3人の娘達のそれぞれの年齢が判ったと言う。あなたにも判る筈だがどうですか?
; 2を3つの非負の整数に分ける方法。これは面倒くさいので天下り的 (setq ss '((0 1 1) (1 0 1) (1 1 0) (2 0 0) (0 2 0) (0 0 2))) ; べき乗のリストのリストを作る (defun ppow (b ss) (mapcar '(lambda (s) (mapcar '(lambda (f) (expt b f)) s)) ss)) ppow (ppow 3 ss) ; テスト。うまくいってる ((1 3 3) (3 1 3) (3 3 1) (9 1 1) (1 9 1) (1 1 9)) ; 年齢の組み合わせの可能性を求めようと思ったけど.. ; mapcar* (zipWith相当) だとうまくいかん。直積にしなきゃ.. (mapcar* '(lambda (f2s f3s) (mapcar* '* f2s f3s)) (ppow 2 ss) (ppow 3 ss)) ((1 6 6) (6 1 6) (6 6 1) (36 1 1) (1 36 1) (1 1 36)) ; リストの直積。以前書いたものから (defun list-product (&rest lists) (if (null lists) '(()) (let ((list0 (car lists)) (prod (apply #'list-product (cdr lists)))) (apply #'append (mapcar #'(lambda (elem) (mapcar #'(lambda (seq) (cons elem seq)) prod)) list0))))) ; 2のべきと3のべきの直積を求めて (setq combs (list-product (ppow 2 ss) (ppow 3 ss))) ; 一応長さ確認 (length combs) 36 ; ありうる年齢の組み合わせを求める。でも重複ありだからまだみにくい (setq years (mapcar* '(lambda (comb) (sort (mapcar* '* (car comb) (cadr comb)) '<=)) combs)) ; listの listを sortするために。最初は elispに closureがないのわすれて ; defunして、"cmpなんて知らん" っていわれてしまった (defmacro list-cmp (cmp) `(lambda (l0 l1) (let ((r 0)) (while (and l0 l1 (= (setq r (funcall ,cmp (car l0) (car l1))) 0)) (setq l0 (cdr l0) l1 (cdr l1))) r))) (funcall (list-cmp '-) '() '()) ; 当然テスト。 0 ; sort | uniq。uniqは mewにそれらしきものがあったので拝借。 (mew-uniq-list (sort years '(lambda (ys0 ys1) (< (funcall (list-cmp '-) ys0 ys1) 0)))) ; あるうる可能性がわかったので、それを cut&yankして sumを求めてみる (mapcar (lambda (ys) (apply '+ ys)) '((1 1 36) (1 2 18) (1 3 12) (1 4 9) (1 6 6) (2 2 9) (2 3 6) (3 3 4))) (38 21 16 14 13 13 11 10)
つまり、番号を教えてもらってもわからなかったんだから、その番号は 13だ。で、「一番上の娘」という表現ができるには、上が双子じゃ駄目。よって2,2,9が正解。
いや、でももしかして上の二人は年は同じでも 10ヶ月違いとかいうことも考えられるじゃないか。その場合、1,6,6でもありえる。よって問題に不備があるともいえる。われながら重箱の隅だ。
追記: よく見ると次の日の日記で解答がしてあって、俺とおんなじことを突っ込んでるのであった。みんな同じだなあ。
さらに深読みしてあって、生き別れ説とか..これはよくわからん :-)