bfs_brute_force 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ Dir.chdir(File.dirname(__FILE__))
4
+
5
+ basename = File.basename __FILE__
6
+
7
+ unless ARGV.size == 1
8
+ files = (Dir["*.rb"] - [basename]).join(" | ")
9
+ $stderr.puts "usage: #{basename} (#{files})"
10
+
11
+ exit 1
12
+ end
13
+
14
+ # Run against source in local git repo
15
+ require 'bundler/setup'
16
+
17
+ require File.join('.', ARGV.first)
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bfs_brute_force'
4
+
5
+ # This is a very simple 'puzzle' to show how to use the bfs_brute_force gem
6
+ #
7
+ # Puzzle:
8
+ #
9
+ # Using the moves "Add 10" and "Add 1," find the shortest number
10
+ # of moves from a starting number to a final number.
11
+
12
+ class AdditionPuzzleState < BfsBruteForce::State
13
+ def initialize(value, final)
14
+ @value = value
15
+ @final = final
16
+ end
17
+
18
+ # (see BfsBruteForce::State.solved?)
19
+ def solved?
20
+ @value == @final
21
+ end
22
+
23
+ # Call yield for every next state in your puzzle
24
+ # This puzzle has two legal moves from every state: Add 10, and Add 1
25
+ #
26
+ # (see BfsBruteForce::State.next_states)
27
+ def next_states(already_seen)
28
+ # If there are no more available states to analyze,
29
+ # {BfsBruteForce::Solver#solve} will throw a {BfsBruteForce::NoSolution}
30
+ # exception.
31
+ return if @value > @final
32
+
33
+ # already_seen is a set passed to every call of next_states.
34
+ # You can use this set to record which states you have previously
35
+ # visited, from a shorter path, avoiding having to visit that
36
+ # same state again.
37
+ #
38
+ # Set#add?(x) will return nil if x is already in the set
39
+ if already_seen.add?(@value + 10)
40
+ yield "Add 10", AdditionPuzzleState.new(@value + 10, @final)
41
+ end
42
+
43
+ if already_seen.add?(@value + 1)
44
+ yield "Add 1", AdditionPuzzleState.new(@value + 1, @final)
45
+ end
46
+ end
47
+ end
48
+
49
+ # Find shortest path from 0 to 42
50
+ initial_state = AdditionPuzzleState.new 0, 42
51
+
52
+ solver = BfsBruteForce::Solver.new
53
+ moves = solver.solve(initial_state).moves
54
+
55
+ moves.each_with_index do |move, index|
56
+ puts "Move %d) %s" % [index + 1, move]
57
+ end
58
+
59
+ # Running this code will produce the following output:
60
+ #
61
+ # Move 1) Add 10
62
+ # Move 2) Add 10
63
+ # Move 3) Add 10
64
+ # Move 4) Add 10
65
+ # Move 5) Add 1
66
+ # Move 6) Add 1
@@ -0,0 +1,627 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bfs_brute_force'
4
+
5
+ # Puzzle:
6
+ #
7
+ # Swap the white and black knights, using standard chess moves.
8
+ # This is the "two knights" puzzle from an old video game, The 11th Hour.
9
+ #
10
+ # Initial board layout:
11
+ #
12
+ # +----+
13
+ # 4 | BK |
14
+ # +----+----+----+----+
15
+ # 3 | | | | WK |
16
+ # +----+----+----+----+
17
+ # 2 | BK | WK | |
18
+ # +----+----+----+
19
+ # 1 | | |
20
+ # +----+----+
21
+ # a b c d
22
+ #
23
+ # BK = Black Knight
24
+ # WK = White Knight
25
+
26
+ class KnightsState < BfsBruteForce::State
27
+ # Legal moves: from_position => [to_position, ...]
28
+ @@moves = {
29
+ :a1 => [:b3, :c2],
30
+ :a2 => [:c3],
31
+ :a3 => [:b1, :c2],
32
+ :a4 => [:b2, :c3],
33
+ :b1 => [:a3, :c3],
34
+ :b2 => [:a4, :d3],
35
+ :b3 => [:a1],
36
+ :c2 => [:a1, :a3],
37
+ :c3 => [:a2, :a4, :b1],
38
+ :d3 => [:b2]
39
+ }
40
+
41
+ def initialize(knights = nil)
42
+ # State of the board: position => knight
43
+ @knights = knights || {
44
+ :a2 => :BK,
45
+ :a4 => :BK,
46
+ :b2 => :WK,
47
+ :d3 => :WK
48
+ }
49
+ end
50
+
51
+ # (see BfsBruteForce::State#solved)
52
+ def solved?
53
+ @knights == {
54
+ :a2 => :WK,
55
+ :a4 => :WK,
56
+ :b2 => :BK,
57
+ :d3 => :BK
58
+ }
59
+ end
60
+
61
+ # Yield all not previously seen states from the current state
62
+ # (see BfsBruteForce::State#next_states)
63
+ def next_states(already_seen)
64
+ @knights.each do |from, knight|
65
+ @@moves[from].reject do |to|
66
+ # Skip occupied positions
67
+ @knights[to]
68
+ end.each do |to|
69
+ new_knights = @knights.merge(to => knight)
70
+ new_knights.delete from
71
+
72
+ if already_seen.add?(new_knights)
73
+ state = KnightsState.new new_knights
74
+ move = "Move #{knight} from #{from} to #{to}\n#{state}"
75
+ yield move, state
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ def to_s
82
+ fmt = %q{
83
+ +----+
84
+ 4 | %s |
85
+ +----+----+----+----+
86
+ 3 | %s | %s | %s | %s |
87
+ +----+----+----+----+
88
+ 2 | %s | %s | %s |
89
+ +----+----+----+
90
+ 1 | %s | %s |
91
+ +----+----+
92
+ a b c d
93
+ }
94
+
95
+ fmt % [:a4, :a3, :b3, :c3, :d3, :a2, :b2, :c2, :a1, :b1].map do |index|
96
+ @knights[index] || ' '
97
+ end
98
+ end
99
+ end
100
+
101
+ solver = BfsBruteForce::Solver.new
102
+ moves = solver.solve(KnightsState.new).moves
103
+
104
+ puts moves
105
+
106
+ # Running this code will produce the following output:
107
+ #
108
+ # Move BK from a2 to c3
109
+ #
110
+ # +----+
111
+ # 4 | BK |
112
+ # +----+----+----+----+
113
+ # 3 | | | BK | WK |
114
+ # +----+----+----+----+
115
+ # 2 | | WK | |
116
+ # +----+----+----+
117
+ # 1 | | |
118
+ # +----+----+
119
+ # a b c d
120
+ #
121
+ # Move BK from c3 to b1
122
+ #
123
+ # +----+
124
+ # 4 | BK |
125
+ # +----+----+----+----+
126
+ # 3 | | | | WK |
127
+ # +----+----+----+----+
128
+ # 2 | | WK | |
129
+ # +----+----+----+
130
+ # 1 | | BK |
131
+ # +----+----+
132
+ # a b c d
133
+ #
134
+ # Move BK from a4 to c3
135
+ #
136
+ # +----+
137
+ # 4 | |
138
+ # +----+----+----+----+
139
+ # 3 | | | BK | WK |
140
+ # +----+----+----+----+
141
+ # 2 | | WK | |
142
+ # +----+----+----+
143
+ # 1 | | BK |
144
+ # +----+----+
145
+ # a b c d
146
+ #
147
+ # Move WK from b2 to a4
148
+ #
149
+ # +----+
150
+ # 4 | WK |
151
+ # +----+----+----+----+
152
+ # 3 | | | BK | WK |
153
+ # +----+----+----+----+
154
+ # 2 | | | |
155
+ # +----+----+----+
156
+ # 1 | | BK |
157
+ # +----+----+
158
+ # a b c d
159
+ #
160
+ # Move BK from b1 to a3
161
+ #
162
+ # +----+
163
+ # 4 | WK |
164
+ # +----+----+----+----+
165
+ # 3 | BK | | BK | WK |
166
+ # +----+----+----+----+
167
+ # 2 | | | |
168
+ # +----+----+----+
169
+ # 1 | | |
170
+ # +----+----+
171
+ # a b c d
172
+ #
173
+ # Move BK from c3 to b1
174
+ #
175
+ # +----+
176
+ # 4 | WK |
177
+ # +----+----+----+----+
178
+ # 3 | BK | | | WK |
179
+ # +----+----+----+----+
180
+ # 2 | | | |
181
+ # +----+----+----+
182
+ # 1 | | BK |
183
+ # +----+----+
184
+ # a b c d
185
+ #
186
+ # Move WK from a4 to c3
187
+ #
188
+ # +----+
189
+ # 4 | |
190
+ # +----+----+----+----+
191
+ # 3 | BK | | WK | WK |
192
+ # +----+----+----+----+
193
+ # 2 | | | |
194
+ # +----+----+----+
195
+ # 1 | | BK |
196
+ # +----+----+
197
+ # a b c d
198
+ #
199
+ # Move WK from c3 to a2
200
+ #
201
+ # +----+
202
+ # 4 | |
203
+ # +----+----+----+----+
204
+ # 3 | BK | | | WK |
205
+ # +----+----+----+----+
206
+ # 2 | WK | | |
207
+ # +----+----+----+
208
+ # 1 | | BK |
209
+ # +----+----+
210
+ # a b c d
211
+ #
212
+ # Move BK from b1 to c3
213
+ #
214
+ # +----+
215
+ # 4 | |
216
+ # +----+----+----+----+
217
+ # 3 | BK | | BK | WK |
218
+ # +----+----+----+----+
219
+ # 2 | WK | | |
220
+ # +----+----+----+
221
+ # 1 | | |
222
+ # +----+----+
223
+ # a b c d
224
+ #
225
+ # Move BK from a3 to b1
226
+ #
227
+ # +----+
228
+ # 4 | |
229
+ # +----+----+----+----+
230
+ # 3 | | | BK | WK |
231
+ # +----+----+----+----+
232
+ # 2 | WK | | |
233
+ # +----+----+----+
234
+ # 1 | | BK |
235
+ # +----+----+
236
+ # a b c d
237
+ #
238
+ # Move BK from c3 to a4
239
+ #
240
+ # +----+
241
+ # 4 | BK |
242
+ # +----+----+----+----+
243
+ # 3 | | | | WK |
244
+ # +----+----+----+----+
245
+ # 2 | WK | | |
246
+ # +----+----+----+
247
+ # 1 | | BK |
248
+ # +----+----+
249
+ # a b c d
250
+ #
251
+ # Move BK from b1 to c3
252
+ #
253
+ # +----+
254
+ # 4 | BK |
255
+ # +----+----+----+----+
256
+ # 3 | | | BK | WK |
257
+ # +----+----+----+----+
258
+ # 2 | WK | | |
259
+ # +----+----+----+
260
+ # 1 | | |
261
+ # +----+----+
262
+ # a b c d
263
+ #
264
+ # Move BK from a4 to b2
265
+ #
266
+ # +----+
267
+ # 4 | |
268
+ # +----+----+----+----+
269
+ # 3 | | | BK | WK |
270
+ # +----+----+----+----+
271
+ # 2 | WK | BK | |
272
+ # +----+----+----+
273
+ # 1 | | |
274
+ # +----+----+
275
+ # a b c d
276
+ #
277
+ # Move BK from c3 to a4
278
+ #
279
+ # +----+
280
+ # 4 | BK |
281
+ # +----+----+----+----+
282
+ # 3 | | | | WK |
283
+ # +----+----+----+----+
284
+ # 2 | WK | BK | |
285
+ # +----+----+----+
286
+ # 1 | | |
287
+ # +----+----+
288
+ # a b c d
289
+ #
290
+ # Move WK from a2 to c3
291
+ #
292
+ # +----+
293
+ # 4 | BK |
294
+ # +----+----+----+----+
295
+ # 3 | | | WK | WK |
296
+ # +----+----+----+----+
297
+ # 2 | | BK | |
298
+ # +----+----+----+
299
+ # 1 | | |
300
+ # +----+----+
301
+ # a b c d
302
+ #
303
+ # Move WK from c3 to b1
304
+ #
305
+ # +----+
306
+ # 4 | BK |
307
+ # +----+----+----+----+
308
+ # 3 | | | | WK |
309
+ # +----+----+----+----+
310
+ # 2 | | BK | |
311
+ # +----+----+----+
312
+ # 1 | | WK |
313
+ # +----+----+
314
+ # a b c d
315
+ #
316
+ # Move BK from a4 to c3
317
+ #
318
+ # +----+
319
+ # 4 | |
320
+ # +----+----+----+----+
321
+ # 3 | | | BK | WK |
322
+ # +----+----+----+----+
323
+ # 2 | | BK | |
324
+ # +----+----+----+
325
+ # 1 | | WK |
326
+ # +----+----+
327
+ # a b c d
328
+ #
329
+ # Move BK from b2 to a4
330
+ #
331
+ # +----+
332
+ # 4 | BK |
333
+ # +----+----+----+----+
334
+ # 3 | | | BK | WK |
335
+ # +----+----+----+----+
336
+ # 2 | | | |
337
+ # +----+----+----+
338
+ # 1 | | WK |
339
+ # +----+----+
340
+ # a b c d
341
+ #
342
+ # Move WK from d3 to b2
343
+ #
344
+ # +----+
345
+ # 4 | BK |
346
+ # +----+----+----+----+
347
+ # 3 | | | BK | |
348
+ # +----+----+----+----+
349
+ # 2 | | WK | |
350
+ # +----+----+----+
351
+ # 1 | | WK |
352
+ # +----+----+
353
+ # a b c d
354
+ #
355
+ # Move WK from b1 to a3
356
+ #
357
+ # +----+
358
+ # 4 | BK |
359
+ # +----+----+----+----+
360
+ # 3 | WK | | BK | |
361
+ # +----+----+----+----+
362
+ # 2 | | WK | |
363
+ # +----+----+----+
364
+ # 1 | | |
365
+ # +----+----+
366
+ # a b c d
367
+ #
368
+ # Move BK from c3 to b1
369
+ #
370
+ # +----+
371
+ # 4 | BK |
372
+ # +----+----+----+----+
373
+ # 3 | WK | | | |
374
+ # +----+----+----+----+
375
+ # 2 | | WK | |
376
+ # +----+----+----+
377
+ # 1 | | BK |
378
+ # +----+----+
379
+ # a b c d
380
+ #
381
+ # Move BK from a4 to c3
382
+ #
383
+ # +----+
384
+ # 4 | |
385
+ # +----+----+----+----+
386
+ # 3 | WK | | BK | |
387
+ # +----+----+----+----+
388
+ # 2 | | WK | |
389
+ # +----+----+----+
390
+ # 1 | | BK |
391
+ # +----+----+
392
+ # a b c d
393
+ #
394
+ # Move WK from b2 to a4
395
+ #
396
+ # +----+
397
+ # 4 | WK |
398
+ # +----+----+----+----+
399
+ # 3 | WK | | BK | |
400
+ # +----+----+----+----+
401
+ # 2 | | | |
402
+ # +----+----+----+
403
+ # 1 | | BK |
404
+ # +----+----+
405
+ # a b c d
406
+ #
407
+ # Move WK from a3 to c2
408
+ #
409
+ # +----+
410
+ # 4 | WK |
411
+ # +----+----+----+----+
412
+ # 3 | | | BK | |
413
+ # +----+----+----+----+
414
+ # 2 | | | WK |
415
+ # +----+----+----+
416
+ # 1 | | BK |
417
+ # +----+----+
418
+ # a b c d
419
+ #
420
+ # Move BK from b1 to a3
421
+ #
422
+ # +----+
423
+ # 4 | WK |
424
+ # +----+----+----+----+
425
+ # 3 | BK | | BK | |
426
+ # +----+----+----+----+
427
+ # 2 | | | WK |
428
+ # +----+----+----+
429
+ # 1 | | |
430
+ # +----+----+
431
+ # a b c d
432
+ #
433
+ # Move BK from c3 to b1
434
+ #
435
+ # +----+
436
+ # 4 | WK |
437
+ # +----+----+----+----+
438
+ # 3 | BK | | | |
439
+ # +----+----+----+----+
440
+ # 2 | | | WK |
441
+ # +----+----+----+
442
+ # 1 | | BK |
443
+ # +----+----+
444
+ # a b c d
445
+ #
446
+ # Move WK from a4 to c3
447
+ #
448
+ # +----+
449
+ # 4 | |
450
+ # +----+----+----+----+
451
+ # 3 | BK | | WK | |
452
+ # +----+----+----+----+
453
+ # 2 | | | WK |
454
+ # +----+----+----+
455
+ # 1 | | BK |
456
+ # +----+----+
457
+ # a b c d
458
+ #
459
+ # Move WK from c3 to a2
460
+ #
461
+ # +----+
462
+ # 4 | |
463
+ # +----+----+----+----+
464
+ # 3 | BK | | | |
465
+ # +----+----+----+----+
466
+ # 2 | WK | | WK |
467
+ # +----+----+----+
468
+ # 1 | | BK |
469
+ # +----+----+
470
+ # a b c d
471
+ #
472
+ # Move BK from b1 to c3
473
+ #
474
+ # +----+
475
+ # 4 | |
476
+ # +----+----+----+----+
477
+ # 3 | BK | | BK | |
478
+ # +----+----+----+----+
479
+ # 2 | WK | | WK |
480
+ # +----+----+----+
481
+ # 1 | | |
482
+ # +----+----+
483
+ # a b c d
484
+ #
485
+ # Move BK from a3 to b1
486
+ #
487
+ # +----+
488
+ # 4 | |
489
+ # +----+----+----+----+
490
+ # 3 | | | BK | |
491
+ # +----+----+----+----+
492
+ # 2 | WK | | WK |
493
+ # +----+----+----+
494
+ # 1 | | BK |
495
+ # +----+----+
496
+ # a b c d
497
+ #
498
+ # Move WK from c2 to a3
499
+ #
500
+ # +----+
501
+ # 4 | |
502
+ # +----+----+----+----+
503
+ # 3 | WK | | BK | |
504
+ # +----+----+----+----+
505
+ # 2 | WK | | |
506
+ # +----+----+----+
507
+ # 1 | | BK |
508
+ # +----+----+
509
+ # a b c d
510
+ #
511
+ # Move BK from c3 to a4
512
+ #
513
+ # +----+
514
+ # 4 | BK |
515
+ # +----+----+----+----+
516
+ # 3 | WK | | | |
517
+ # +----+----+----+----+
518
+ # 2 | WK | | |
519
+ # +----+----+----+
520
+ # 1 | | BK |
521
+ # +----+----+
522
+ # a b c d
523
+ #
524
+ # Move BK from b1 to c3
525
+ #
526
+ # +----+
527
+ # 4 | BK |
528
+ # +----+----+----+----+
529
+ # 3 | WK | | BK | |
530
+ # +----+----+----+----+
531
+ # 2 | WK | | |
532
+ # +----+----+----+
533
+ # 1 | | |
534
+ # +----+----+
535
+ # a b c d
536
+ #
537
+ # Move WK from a3 to b1
538
+ #
539
+ # +----+
540
+ # 4 | BK |
541
+ # +----+----+----+----+
542
+ # 3 | | | BK | |
543
+ # +----+----+----+----+
544
+ # 2 | WK | | |
545
+ # +----+----+----+
546
+ # 1 | | WK |
547
+ # +----+----+
548
+ # a b c d
549
+ #
550
+ # Move BK from a4 to b2
551
+ #
552
+ # +----+
553
+ # 4 | |
554
+ # +----+----+----+----+
555
+ # 3 | | | BK | |
556
+ # +----+----+----+----+
557
+ # 2 | WK | BK | |
558
+ # +----+----+----+
559
+ # 1 | | WK |
560
+ # +----+----+
561
+ # a b c d
562
+ #
563
+ # Move BK from c3 to a4
564
+ #
565
+ # +----+
566
+ # 4 | BK |
567
+ # +----+----+----+----+
568
+ # 3 | | | | |
569
+ # +----+----+----+----+
570
+ # 2 | WK | BK | |
571
+ # +----+----+----+
572
+ # 1 | | WK |
573
+ # +----+----+
574
+ # a b c d
575
+ #
576
+ # Move WK from b1 to c3
577
+ #
578
+ # +----+
579
+ # 4 | BK |
580
+ # +----+----+----+----+
581
+ # 3 | | | WK | |
582
+ # +----+----+----+----+
583
+ # 2 | WK | BK | |
584
+ # +----+----+----+
585
+ # 1 | | |
586
+ # +----+----+
587
+ # a b c d
588
+ #
589
+ # Move BK from b2 to d3
590
+ #
591
+ # +----+
592
+ # 4 | BK |
593
+ # +----+----+----+----+
594
+ # 3 | | | WK | BK |
595
+ # +----+----+----+----+
596
+ # 2 | WK | | |
597
+ # +----+----+----+
598
+ # 1 | | |
599
+ # +----+----+
600
+ # a b c d
601
+ #
602
+ # Move BK from a4 to b2
603
+ #
604
+ # +----+
605
+ # 4 | |
606
+ # +----+----+----+----+
607
+ # 3 | | | WK | BK |
608
+ # +----+----+----+----+
609
+ # 2 | WK | BK | |
610
+ # +----+----+----+
611
+ # 1 | | |
612
+ # +----+----+
613
+ # a b c d
614
+ #
615
+ # Move WK from c3 to a4
616
+ #
617
+ # +----+
618
+ # 4 | WK |
619
+ # +----+----+----+----+
620
+ # 3 | | | | BK |
621
+ # +----+----+----+----+
622
+ # 2 | WK | BK | |
623
+ # +----+----+----+
624
+ # 1 | | |
625
+ # +----+----+
626
+ # a b c d
627
+ #