rlm@3
|
1 (ns rlm.qotd)
|
rlm@3
|
2
|
rlm@4
|
3 ;;; There is a pair of integers, 1 < m < n, whose sum is
|
rlm@4
|
4 ;;; less than 100.
|
rlm@3
|
5
|
rlm@4
|
6 ;; These constraints makes a triangular sort of pattern.
|
rlm@4
|
7 (defn generate-valid-numbers
|
rlm@4
|
8 [n]
|
rlm@4
|
9 (filter (fn [[a b]] (< a b))
|
rlm@4
|
10 (map #(vector % n) (range 2 (- 150 n)))))
|
rlm@3
|
11
|
rlm@4
|
12 (def squish (partial reduce concat))
|
rlm@4
|
13
|
rlm@4
|
14 (def p0 (squish (map generate-valid-numbers (range 2 149))))
|
rlm@3
|
15
|
rlm@3
|
16 ;;; Person S knows their sum, but nothing else about them.
|
rlm@3
|
17 ;;; Person P knows their product, but nothing else about
|
rlm@3
|
18 ;;; them.
|
rlm@3
|
19
|
rlm@4
|
20 ;;; Now, Persons S and P know the above information, and
|
rlm@4
|
21 ;;; each one knows that the other one knows it. They have
|
rlm@4
|
22 ;;; the following conversation:
|
rlm@3
|
23
|
rlm@3
|
24 ;;; P: I can't figure out what the numbers are.
|
rlm@3
|
25
|
rlm@3
|
26 ;; Eliminate pairs with a unique product.
|
rlm@3
|
27
|
rlm@3
|
28 (defn group-by
|
rlm@3
|
29 "Split coll into groups where the f maps each element in a
|
rlm@3
|
30 group to the same value in O(n*log(n)) time."
|
rlm@3
|
31 [f coll]
|
rlm@3
|
32 (partition-by f (sort-by f coll)))
|
rlm@3
|
33
|
rlm@3
|
34 (defn unique-by
|
rlm@3
|
35 "Remove all elements a,b of coll that for which
|
rlm@3
|
36 (= (f a) (f b)) in O(n*log(n)) time."
|
rlm@3
|
37 [f coll]
|
rlm@4
|
38 (squish (filter #(= (count %) 1) (group-by f coll))))
|
rlm@3
|
39
|
rlm@3
|
40 (defn multiple-by
|
rlm@4
|
41 "Keep all elements a,b of coll for which
|
rlm@3
|
42 (= (f a) (f b)) in O(n*log(n)) time."
|
rlm@3
|
43 [f coll]
|
rlm@4
|
44 (squish (filter #(> (count %) 1) (group-by f coll))))
|
rlm@3
|
45
|
rlm@3
|
46 (defn prod [[a b]] (* a b))
|
rlm@3
|
47
|
rlm@3
|
48 (def p1 (multiple-by prod p0))
|
rlm@3
|
49
|
rlm@3
|
50 ;;; S: I was sure you couldn't.
|
rlm@3
|
51
|
rlm@3
|
52 ;; Each possible sum s has a set of possible pairs [a b]
|
rlm@4
|
53 ;; where (= s (+ a b)). Partition p0 (since S *was* sure) by
|
rlm@4
|
54 ;; sum, and keep those pairs that belong in partitions where
|
rlm@4
|
55 ;; each pair in that partition is in p1. (since the only way
|
rlm@4
|
56 ;; he could be *sure*, is if every possibility for a given
|
rlm@4
|
57 ;; sum had an ambiguous product.
|
rlm@3
|
58
|
rlm@3
|
59 (defn sum [[a b]] (+ a b))
|
rlm@3
|
60
|
rlm@3
|
61 (def p2
|
rlm@4
|
62 (squish
|
rlm@3
|
63 (filter
|
rlm@3
|
64 (partial every? (set p1))
|
rlm@3
|
65 (group-by sum p0))))
|
rlm@3
|
66
|
rlm@3
|
67
|
rlm@3
|
68 ;;; P: Then I have.
|
rlm@3
|
69
|
rlm@3
|
70 ;; Keep those pairs that have a unique product out of the
|
rlm@3
|
71 ;; ones that are left.
|
rlm@3
|
72
|
rlm@3
|
73 (def p3
|
rlm@3
|
74 (unique-by prod p2))
|
rlm@3
|
75
|
rlm@3
|
76
|
rlm@3
|
77 ;;; S: Then I have, too.
|
rlm@3
|
78
|
rlm@4
|
79 ;; Keep those pairs that have a unique sum out of the
|
rlm@4
|
80 ;; ones that are left.
|
rlm@4
|
81
|
rlm@4
|
82 (def p4 (unique-by sum p3))
|
rlm@4
|
83
|
rlm@4
|
84
|
rlm@4
|
85 (defn solve [limit]
|
rlm@4
|
86 (let [generate-valid-numbers
|
rlm@4
|
87 (fn
|
rlm@4
|
88 [n]
|
rlm@4
|
89 (filter (fn [[a b]] (< a b))
|
rlm@4
|
90 (map #(vector % n)
|
rlm@4
|
91 (range 2 (- limit n)))))
|
rlm@4
|
92 p0
|
rlm@4
|
93 (squish (map generate-valid-numbers
|
rlm@4
|
94 (range 2 (dec limit))))
|
rlm@4
|
95 p2
|
rlm@4
|
96 (squish
|
rlm@4
|
97 (filter
|
rlm@4
|
98 (partial every? (set p1))
|
rlm@4
|
99 (group-by sum p0)))
|
rlm@4
|
100
|
rlm@4
|
101 p3 (unique-by prod p2)]
|
rlm@4
|
102 (unique-by sum p3)))
|
rlm@4
|
103
|
rlm@4
|
104 ;;; Dylan START!
|
rlm@4
|
105 (defn results [beez]
|
rlm@4
|
106 (let
|
rlm@4
|
107 [
|
rlm@4
|
108 pairs
|
rlm@4
|
109 (for [m (range 2 beez)
|
rlm@4
|
110 n (range (inc m) beez)]
|
rlm@4
|
111 [m n])
|
rlm@4
|
112
|
rlm@4
|
113 singleton? (comp zero? dec count)
|
rlm@4
|
114
|
rlm@4
|
115 sum (fn [[x y]] (+ x y))
|
rlm@4
|
116 product (fn [[x y]] (* x y))
|
rlm@4
|
117
|
rlm@4
|
118 inverse-sum
|
rlm@4
|
119 (fn [s]
|
rlm@4
|
120 (filter #(= s (sum %)) pairs))
|
rlm@4
|
121
|
rlm@4
|
122 inverse-product
|
rlm@4
|
123 (fn [p]
|
rlm@4
|
124 (filter #(= p (product %)) pairs))
|
rlm@4
|
125 ]
|
rlm@4
|
126
|
rlm@4
|
127
|
rlm@4
|
128 (->>
|
rlm@4
|
129 pairs
|
rlm@4
|
130
|
rlm@4
|
131 (filter #(< (sum %) beez))
|
rlm@4
|
132
|
rlm@4
|
133 ;; P: I cannot find the numbers.
|
rlm@4
|
134 (remove (comp singleton?
|
rlm@4
|
135 inverse-product
|
rlm@4
|
136 product))
|
rlm@4
|
137 set
|
rlm@4
|
138
|
rlm@4
|
139 ;; S: I was sure you couldn't.
|
rlm@4
|
140 ((fn [coll]
|
rlm@4
|
141 (filter
|
rlm@4
|
142 (comp (partial every? coll)
|
rlm@4
|
143 inverse-sum
|
rlm@4
|
144 sum)
|
rlm@4
|
145 coll)))
|
rlm@4
|
146 set
|
rlm@4
|
147
|
rlm@4
|
148 ;;P: Then I have.
|
rlm@4
|
149 ((fn [coll]
|
rlm@4
|
150 (filter
|
rlm@4
|
151 (comp singleton?
|
rlm@4
|
152 (partial filter coll)
|
rlm@4
|
153 inverse-product
|
rlm@4
|
154 product)
|
rlm@4
|
155 coll)))
|
rlm@4
|
156 set
|
rlm@4
|
157
|
rlm@4
|
158 ;;S: Then I have, too.
|
rlm@4
|
159 ((fn [coll]
|
rlm@4
|
160 (filter
|
rlm@4
|
161 (comp singleton?
|
rlm@4
|
162 (partial filter coll)
|
rlm@4
|
163 inverse-sum
|
rlm@4
|
164 sum)
|
rlm@4
|
165 coll)))
|
rlm@4
|
166
|
rlm@4
|
167 ))) |