Comment detail

トランプの和と積のパズル (Nested Flatten)
nkmrtksさんにこっそり教えてもらった#1610のロジックを咀嚼してから
再構築したつもりです。(ありがとうございます)
考え易さ第一ということで、速度とかはかなり遅くなってると思います^^;
正直難しかったです。特に爆弾発言部
(print (answer 13))
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
(defun number-A-knows (pair)
  (if (null pair) nil (* (car pair) (cdr pair))))

(defun number-B-knows (pair)
  (if (null pair) nil (+ (car pair) (cdr pair))))

(defun uniq-if (item fn lst)
  "itemが、lstのpairにfnを適応した結果中に1度だけ現れる場合に、itemを返す。それ以外はnil"
  (if (eql (loop for x in lst 
                 when (equal (funcall fn item)
                             (funcall fn x))
                 count t)
           1)
    item))
(defun uniq-if-not (item fn lst)
  "itemが、lstのpairにfnを適応した結果中に2度以上現れる場合に、itemを返す。それ以外はnil"
  (if (> (loop for x in lst
               when (equal (funcall fn item)
                           (funcall fn x))
               count t)
         1)
    item))

(defun pair-A-dosenot-know-lst (pairs)
  "Aさん「(この情報だけでは)分かりません」"
  (loop for pair in pairs
        when (uniq-if-not pair #'number-A-knows pairs)
        collect it))
(defun pair-B-dosenot-know-lst (pairs)
  "Bさん「私も分かりません.」"
  (loop for pair in pairs
        when (uniq-if-not pair #'number-B-knows pairs)
        collect it))
(defun pair-B-knows-A-dosenot-know-lst (pairs)
  "Bさん「ただ,Aさんが『分かりません』というのは分かっていました」"
  (let* ((pair-A-dosenot-know-lst (pair-A-dosenot-know-lst pairs))
         (number-A-knows-lst (remove-duplicates 
                               (mapcar #'number-B-knows (pair-B-dosenot-know-lst pairs))))
         (A-lst-lst-expected-by-B (loop for n in number-A-knows-lst
                                        collect (loop for pair in pairs
                                                      when (eql n (number-B-knows pair))
                                                      collect pair))))
    (apply #'nconc (remove-if 
                     #'(lambda (lst)
                         (notevery
                           #'(lambda (x)
                               (member x pair-A-dosenot-know-lst :test #'equal))
                           lst))
                     A-lst-lst-expected-by-B))))
(defun pair-A-finds-answer-lst (pairs)
  "それを聞いたAさん「それなら,分かりました」"
  (let ((lst (pair-B-knows-A-dosenot-know-lst pairs)))
    (loop for x in lst
          when (uniq-if x #'number-A-knows lst)
          collect it)))
(defun pair-B-finds-answer-lst (pairs)
  "それを聞いたBさん「それなら,私も分かりました」"
  (let ((lst (pair-A-finds-answer-lst pairs)))
    (loop for x in lst
          when (uniq-if x #'number-B-knows lst)
          collect it)))

(defun answer (n)
  (let ((pairs (loop for i from 1 to n
                     append (loop for j from 1 to n
                                  when (<= i j)
                                  collect (cons i j)))))
    (pair-B-finds-answer-lst pairs)))

Index

Feed

Other

Link

Pathtraq

loading...