-
Notifications
You must be signed in to change notification settings - Fork 0
/
773-sliding-puzzle.rkt
38 lines (31 loc) · 1.03 KB
/
773-sliding-puzzle.rkt
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
#lang racket
(require data/queue)
(define (sliding-puzzle board)
(define visited (mutable-set))
(define visited? (curry set-member? visited))
(define solved? (curry equal? #(1 2 3 4 5 0)))
(define initial (list->vector (flatten board)))
(let search ([states (list initial)])
(match states
['() -1]
[(list (cons state depth) rst)
(cond [(visited? state) (search rst)]
[(solved? state) depth]
[else
(set-add! visited state)
(search
(append states
(map (λ (s) (cons s (add1 depth)))
(slide state))))])])))
(define neighbors
#((1 3) (0 2 4) (1 5) (0 4) (1 3 5) (2 4)))
(define (slide state)
(define x (index-of (vector->list state) 0 =))
(for/list ([y (in-list (vector-ref neighbors x))])
(vector-swap state x y)))
(define (vector-swap v x y)
(let ([x-val (vector-ref v x)]
[y-val (vector-ref v y)]
[new-v (vector-copy v)])
(vector-set*! new-v x y-val y x-val)
new-v))