z3 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,370 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/z3"
4
+
5
+ class SelfRefPuzzleSolver
6
+ attr_reader :q, :a
7
+ attr_reader :a_answers, :b_answers, :c_answers, :d_answers, :e_answers, :cons_answers
8
+ def initialize
9
+ @solver = Z3::Solver.new
10
+ @q = {}
11
+ @a = {}
12
+ (1..20).each do |i|
13
+ @q[i] = Z3::Ast.int("q#{i}")
14
+ assert @q[i] >= 1
15
+ assert @q[i] <= 5
16
+ @a[i] = {}
17
+ (1..5).each do |j|
18
+ @a[i][j] = Z3::Ast.int("a#{i},#{' ABCDE'[j]}")
19
+ assert (@a[i][j] == 0) == (@q[i] != j)
20
+ assert (@a[i][j] == 1) == (@q[i] == j)
21
+ end
22
+ end
23
+ end
24
+
25
+ def assert(ast)
26
+ @solver.assert(ast)
27
+ end
28
+
29
+ def cons_in(*ary)
30
+ Z3::Ast.or(*ary.map{|i| cons_answers == i})
31
+ end
32
+
33
+ def solve!
34
+ @a_answers = Z3::Ast.add(*(1..20).map{|i| @a[i][1]})
35
+ @b_answers = Z3::Ast.add(*(1..20).map{|i| @a[i][2]})
36
+ @c_answers = Z3::Ast.add(*(1..20).map{|i| @a[i][3]})
37
+ @d_answers = Z3::Ast.add(*(1..20).map{|i| @a[i][4]})
38
+ @e_answers = Z3::Ast.add(*(1..20).map{|i| @a[i][5]})
39
+ @cons_answers = b_answers + c_answers + d_answers
40
+
41
+ # Question 1
42
+ assert (q[1] == 1) == (q[1] == 2)
43
+ assert (q[1] == 2) == Z3::Ast.and(q[1] != 2, q[2] == 2)
44
+ assert (q[1] == 3) == Z3::Ast.and(q[1] != 2, q[2] != 2, q[3] == 2)
45
+ assert (q[1] == 4) == Z3::Ast.and(q[1] != 2, q[2] != 2, q[3] != 2, q[4] == 2)
46
+ assert (q[1] == 5) == Z3::Ast.and(q[1] != 2, q[2] != 2, q[3] != 2, q[4] != 2, q[5] == 2)
47
+
48
+ # Question 2
49
+ assert q[ 1] != q[ 2]
50
+ assert q[ 2] != q[ 3]
51
+ assert q[ 3] != q[ 4]
52
+ assert q[ 4] != q[ 5]
53
+ assert q[ 5] != q[ 6]
54
+ assert (q[ 6] == q[ 7]) == (q[2] == 1)
55
+ assert (q[ 7] == q[ 8]) == (q[2] == 2)
56
+ assert (q[ 8] == q[ 9]) == (q[2] == 3)
57
+ assert (q[ 9] == q[10]) == (q[2] == 4)
58
+ assert (q[10] == q[11]) == (q[2] == 5)
59
+ assert q[11] != q[12]
60
+ assert q[12] != q[13]
61
+ assert q[13] != q[14]
62
+ assert q[14] != q[15]
63
+ assert q[15] != q[16]
64
+ assert q[16] != q[17]
65
+ assert q[17] != q[18]
66
+ assert q[18] != q[19]
67
+ assert q[19] != q[20]
68
+
69
+ # Question 3
70
+ assert (e_answers == 0) == (q[3] == 1)
71
+ assert (e_answers == 1) == (q[3] == 2)
72
+ assert (e_answers == 2) == (q[3] == 3)
73
+ assert (e_answers == 3) == (q[3] == 4)
74
+ assert (e_answers == 4) == (q[3] == 5)
75
+
76
+ # Question 4
77
+ assert (a_answers == 4) == (q[4] == 1)
78
+ assert (a_answers == 5) == (q[4] == 2)
79
+ assert (a_answers == 6) == (q[4] == 3)
80
+ assert (a_answers == 7) == (q[4] == 4)
81
+ assert (a_answers == 8) == (q[4] == 5)
82
+
83
+ # Question 5
84
+ assert Z3::Ast.implies(q[5] == 1, q[5] == q[1])
85
+ assert Z3::Ast.implies(q[5] == 2, q[5] == q[2])
86
+ assert Z3::Ast.implies(q[5] == 3, q[5] == q[3])
87
+ assert Z3::Ast.implies(q[5] == 4, q[5] == q[4])
88
+ assert Z3::Ast.implies(q[5] == 5, q[5] == q[5])
89
+
90
+ # Question 6
91
+ assert (q[17] == 3) == (q[6] == 1)
92
+ assert (q[17] == 4) == (q[6] == 2)
93
+ assert (q[17] == 5) == (q[6] == 3)
94
+ assert Z3::Ast.or(q[17] == 1, q[17] == 2) == (q[6] == 4)
95
+ assert q[6] != 5
96
+
97
+ # Question 7
98
+ assert Z3::Ast.or(q[7] - q[8] == 4, q[8] - q[7] == 4) == (q[7] == 1)
99
+ assert Z3::Ast.or(q[7] - q[8] == 3, q[8] - q[7] == 3) == (q[7] == 2)
100
+ assert Z3::Ast.or(q[7] - q[8] == 2, q[8] - q[7] == 2) == (q[7] == 3)
101
+ assert Z3::Ast.or(q[7] - q[8] == 1, q[8] - q[7] == 1) == (q[7] == 4)
102
+ assert Z3::Ast.or(q[7] - q[8] == 0, q[8] - q[7] == 0) == (q[7] == 5)
103
+
104
+ # Question 8
105
+ assert (a_answers + e_answers == 4) == (q[8] == 1)
106
+ assert (a_answers + e_answers == 5) == (q[8] == 2)
107
+ assert (a_answers + e_answers == 6) == (q[8] == 3)
108
+ assert (a_answers + e_answers == 7) == (q[8] == 4)
109
+ assert (a_answers + e_answers == 8) == (q[8] == 5)
110
+
111
+ # Question 9
112
+ assert (q[10] == q[9]) == (q[9] == 1)
113
+ assert Z3::Ast.and(q[10] != q[9], q[11] == q[9]) == (q[9] == 2)
114
+ assert Z3::Ast.and(q[10] != q[9], q[11] != q[9], q[12] == q[9]) == (q[9] == 3)
115
+ assert Z3::Ast.and(q[10] != q[9], q[11] != q[9], q[12] != q[9], q[13] == q[9]) == (q[9] == 4)
116
+ assert Z3::Ast.and(q[10] != q[9], q[11] != q[9], q[12] != q[9], q[13] != q[9], q[14] == q[9]) == (q[9] == 5)
117
+
118
+ # Question 10
119
+ assert (q[16] == 4) == (q[10] == 1)
120
+ assert (q[16] == 1) == (q[10] == 2)
121
+ assert (q[16] == 5) == (q[10] == 3)
122
+ assert (q[16] == 2) == (q[10] == 4)
123
+ assert (q[16] == 3) == (q[10] == 5)
124
+
125
+ # Question 11
126
+ prec_b_answers = Z3::Ast.add(*(1..10).map{|i| @a[i][2]})
127
+ assert (prec_b_answers == 0) == (q[11] == 1)
128
+ assert (prec_b_answers == 1) == (q[11] == 2)
129
+ assert (prec_b_answers == 2) == (q[11] == 3)
130
+ assert (prec_b_answers == 3) == (q[11] == 4)
131
+ assert (prec_b_answers == 4) == (q[11] == 5)
132
+
133
+ # Question 12
134
+ assert Z3::Ast.implies(q[12] == 1, cons_in(2,4,6,8,10,12,14,16,18,20))
135
+ assert Z3::Ast.implies(q[12] == 2, cons_in(1,3,5,7,9,11,13,15,17,19))
136
+ assert Z3::Ast.implies(q[12] == 3, cons_in(1,4,9,16))
137
+ assert Z3::Ast.implies(q[12] == 4, cons_in(2,3,5,7,11,13,17,19))
138
+ assert Z3::Ast.implies(q[12] == 5, cons_in(5,10,15,20))
139
+
140
+ # Question 13
141
+ assert q[1] != 1
142
+ assert q[3] != 1
143
+ assert q[5] != 1
144
+ assert q[7] != 1
145
+ assert (q[ 9] == 1) == (q[13] == 1)
146
+ assert (q[11] == 1) == (q[13] == 2)
147
+ assert (q[13] == 1) == (q[13] == 3)
148
+ assert (q[15] == 1) == (q[13] == 4)
149
+ assert (q[17] == 1) == (q[13] == 5)
150
+ assert q[19] != 1
151
+
152
+ # Question 14
153
+ assert (d_answers == 6) == (q[4] == 1)
154
+ assert (d_answers == 7) == (q[4] == 2)
155
+ assert (d_answers == 8) == (q[4] == 3)
156
+ assert (d_answers == 9) == (q[4] == 4)
157
+ assert (d_answers == 10) == (q[4] == 5)
158
+
159
+ # Question 15
160
+ assert q[15] == q[12]
161
+
162
+ # Question 16
163
+ assert (q[10] == 4) == (q[16] == 1)
164
+ assert (q[10] == 3) == (q[16] == 2)
165
+ assert (q[10] == 2) == (q[16] == 3)
166
+ assert (q[10] == 1) == (q[16] == 4)
167
+ assert (q[10] == 5) == (q[16] == 5)
168
+
169
+ # Question 17
170
+ assert (q[6] == 3) == (q[17] == 1)
171
+ assert (q[6] == 4) == (q[17] == 2)
172
+ assert (q[6] == 5) == (q[17] == 3)
173
+ assert Z3::Ast.and(q[6] != 3, q[6] != 4, q[6] != 5) == (q[17] == 4)
174
+ assert q[17] != 5
175
+
176
+ # Question 18
177
+ assert (a_answers == b_answers) == (q[18] == 1)
178
+ assert (a_answers == c_answers) == (q[18] == 2)
179
+ assert (a_answers == d_answers) == (q[18] == 3)
180
+ assert (a_answers == e_answers) == (q[18] == 4)
181
+ assert Z3::Ast.and(
182
+ a_answers != b_answers,
183
+ a_answers != c_answers,
184
+ a_answers != d_answers,
185
+ a_answers != e_answers
186
+ ) == (q[18] == 5)
187
+
188
+ # Question 19
189
+ assert q[19] == q[19]
190
+
191
+ # Question 20
192
+ assert q[20] == 5
193
+
194
+ # Print solutions
195
+ if @solver.check == :sat
196
+ model = @solver.model
197
+ (1..20).each do |i|
198
+ a = model[q[i]].to_s.to_i
199
+ puts "Q%2d: %s" % [i, " ABCDE"[a]]
200
+ end
201
+ else
202
+ puts "failed to solve"
203
+ end
204
+ end
205
+ end
206
+
207
+
208
+ SelfRefPuzzleSolver.new.solve!
209
+
210
+ __END__
211
+ http://faculty.uml.edu/jpropp/srat-Q.txt
212
+
213
+ SELF-REFERENTIAL APTITUDE TEST, by Jim Propp (jimpropp at gmaildotcom)
214
+
215
+ The solution to the following puzzle is unique; in some cases the
216
+ knowledge that the solution is unique may actually give you a short-cut
217
+ to finding the answer to a particular question. (Thanks to Andy Latto
218
+ for bringing this subtlety to my attention.)
219
+
220
+ I should mention that if you don't agree with me about the answer to #20,
221
+ you will get a different solution to the puzzle than the one I had in mind.
222
+ But I should also mention that if you don't agree with me about the answer
223
+ to #20, you are just plain wrong. :-)
224
+
225
+ You may now begin work.
226
+
227
+
228
+ 1. The first question whose answer is B is question
229
+ (A) 1
230
+ (B) 2
231
+ (C) 3
232
+ (D) 4
233
+ (E) 5
234
+
235
+ 2. The only two consecutive questions with identical answers are questions
236
+ (A) 6 and 7
237
+ (B) 7 and 8
238
+ (C) 8 and 9
239
+ (D) 9 and 10
240
+ (E) 10 and 11
241
+
242
+ 3. The number of questions with the answer E is
243
+ (A) 0
244
+ (B) 1
245
+ (C) 2
246
+ (D) 3
247
+ (E) 4
248
+
249
+ 4. The number of questions with the answer A is
250
+ (A) 4
251
+ (B) 5
252
+ (C) 6
253
+ (D) 7
254
+ (E) 8
255
+
256
+ 5. The answer to this question is the same as the answer to question
257
+ (A) 1
258
+ (B) 2
259
+ (C) 3
260
+ (D) 4
261
+ (E) 5
262
+
263
+ 6. The answer to question 17 is
264
+ (A) C
265
+ (B) D
266
+ (C) E
267
+ (D) none of the above
268
+ (E) all of the above
269
+
270
+ 7. Alphabetically, the answer to this question and the answer to the
271
+ following question are
272
+ (A) 4 apart
273
+ (B) 3 apart
274
+ (C) 2 apart
275
+ (D) 1 apart
276
+ (E) the same
277
+
278
+ 8. The number of questions whose answers are vowels is
279
+ (A) 4
280
+ (B) 5
281
+ (C) 6
282
+ (D) 7
283
+ (E) 8
284
+
285
+ 9. The next question with the same answer as this one is question
286
+ (A) 10
287
+ (B) 11
288
+ (C) 12
289
+ (D) 13
290
+ (E) 14
291
+
292
+ 10. The answer to question 16 is
293
+ (A) D
294
+ (B) A
295
+ (C) E
296
+ (D) B
297
+ (E) C
298
+
299
+ 11. The number of questions preceding this one with the answer B is
300
+ (A) 0
301
+ (B) 1
302
+ (C) 2
303
+ (D) 3
304
+ (E) 4
305
+
306
+ 12. The number of questions whose answer is a consonant is
307
+ (A) an even number
308
+ (B) an odd number
309
+ (C) a perfect square
310
+ (D) a prime
311
+ (E) divisible by 5
312
+
313
+ 13. The only odd-numbered problem with answer A is
314
+ (A) 9
315
+ (B) 11
316
+ (C) 13
317
+ (D) 15
318
+ (E) 17
319
+
320
+ 14. The number of questions with answer D is
321
+ (A) 6
322
+ (B) 7
323
+ (C) 8
324
+ (D) 9
325
+ (E) 10
326
+
327
+ 15. The answer to question 12 is
328
+ (A) A
329
+ (B) B
330
+ (C) C
331
+ (D) D
332
+ (E) E
333
+
334
+ 16. The answer to question 10 is
335
+ (A) D
336
+ (B) C
337
+ (C) B
338
+ (D) A
339
+ (E) E
340
+
341
+ 17. The answer to question 6 is
342
+ (A) C
343
+ (B) D
344
+ (C) E
345
+ (D) none of the above
346
+ (E) all of the above
347
+
348
+ 18. The number of questions with answer A equals the number of questions
349
+ with answer
350
+ (A) B
351
+ (B) C
352
+ (C) D
353
+ (D) E
354
+ (E) none of the above
355
+
356
+ 19. The answer to this question is:
357
+ (A) A
358
+ (B) B
359
+ (C) C
360
+ (D) D
361
+ (E) E
362
+
363
+ 20. Standardized test is to intelligence as barometer is to
364
+ (A) temperature (only)
365
+ (B) wind-velocity (only)
366
+ (C) latitude (only)
367
+ (D) longitude (only)
368
+ (E) temperature, wind-velocity, latitude, and longitude
369
+
370
+ ( to go to the main SRAT page, go to jamespropp.org/srat.html )
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/z3"
4
+
5
+ class SudokuSolver
6
+ def initialize(data)
7
+ @data = data
8
+ @solver = Z3::Solver.new
9
+ end
10
+
11
+ def solve!
12
+ @cells = (0..8).map do |j|
13
+ (0..8).map do |i|
14
+ cell_var(@data[j][i], i, j)
15
+ end
16
+ end
17
+
18
+ @cells.each do |row|
19
+ @solver.assert Z3::Ast.distinct(*row)
20
+ end
21
+ @cells.transpose.each do |column|
22
+ @solver.assert Z3::Ast.distinct(*column)
23
+ end
24
+ @cells.each_slice(3) do |rows|
25
+ rows.transpose.each_slice(3) do |square|
26
+ @solver.assert Z3::Ast.distinct(*square.flatten)
27
+ end
28
+ end
29
+
30
+ if @solver.check == :sat
31
+ @model = @solver.model
32
+ print_answer!
33
+ else
34
+ puts "failed to solve"
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def cell_var(cell, i, j)
41
+ v = Z3::Ast.int("cell[#{i+1},#{j+1}]")
42
+ @solver.assert v >= 1
43
+ @solver.assert v <= 9
44
+ @solver.assert v == cell if cell != nil
45
+ v
46
+ end
47
+
48
+ def print_answer!
49
+ @cells.each do |row|
50
+ puts row.map{|v| @model[v]}.join(" ")
51
+ end
52
+ end
53
+ end
54
+
55
+ _ = nil
56
+ sudoku = SudokuSolver.new([
57
+ [_, 6, _, 5, _, 9, _, 4, _],
58
+ [9, 2, _, _, _, _, _, 7, 6],
59
+ [_, _, 1, _, _, _, 9, _, _],
60
+ [7, _, _, 6, _, 3, _, _, 9],
61
+ [_, _, _, _, _, _, _, _, _],
62
+ [3, _, _, 4, _, 1, _, _, 7],
63
+ [_, _, 6, _, _, _, 7, _, _],
64
+ [2, 4, _, _, _, _, _, 6, 5],
65
+ [_, 9, _, 1, _, 8, _, 3, _],
66
+ ])
67
+ sudoku.solve!
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/z3"
4
+
5
+ class VerbalArithmetic
6
+ def initialize(a, b, c)
7
+ @solver = Z3::Solver.new
8
+ @vars = Hash.new do |ht,name|
9
+ v = Z3::Ast.int(name)
10
+ @solver.assert v >= 0
11
+ @solver.assert v <= 9
12
+ ht[name] = v
13
+ end
14
+ @a = a.chars.map{|v| @vars[v]}
15
+ @b = b.chars.map{|v| @vars[v]}
16
+ @c = c.chars.map{|v| @vars[v]}
17
+ end
18
+
19
+ def solve!
20
+ @solver.assert @a[0] != 0
21
+ @solver.assert @b[0] != 0
22
+ @solver.assert @c[0] != 0
23
+ @solver.assert word_value(@a) + word_value(@b) == word_value(@c)
24
+ @solver.assert Z3::Ast.distinct(*@vars.values)
25
+
26
+ if @solver.check == :sat
27
+ @model = @solver.model
28
+ print_answer!
29
+ else
30
+ puts "failed to solve"
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def word_value(word)
37
+ word.inject(0){|x,y| 10*x+y}
38
+ end
39
+
40
+ def print_answer!
41
+ [@a,@b,@c].each do |word|
42
+ p word.map{|v| [v.to_s, @model[v].to_s.to_i]}
43
+ end
44
+ end
45
+ end
46
+
47
+ VerbalArithmetic.new("SEND", "MORE", "MONEY").solve!