blob: 02e65509a49133c9be2820dea6e4cda38b2ca12b (
plain) (
blame)
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
69
70
|
#lang racket
(define occupied
(list->mutable-set
(for*/list ([(line row) (in-indexed (file->lines "day23"))]
[(char col) (in-indexed line)]
#:when (equal? char #\#))
(vector col row))))
; (set-count occupied)
; occupied
(define adjs (list (list #(0 -1) #(1 -1) #(-1 -1))
(list #(0 1) #(1 1) #(-1 1))
(list #(-1 0) #(-1 1) #(-1 -1))
(list #( 1 0) #( 1 1) #( 1 -1))))
(define dirs (list #(0 -1)
#(0 1)
#(-1 0)
#( 1 0)))
(let loop ((rounds 1))
(define next (make-hash))
(for ([elf occupied])
(unless (for*/and ([dx '(-1 0 1)]
[dy '(-1 0 1)]
#:unless (= dx dy 0))
(not (set-member? occupied (vector-map + elf (vector dx dy)))))
(for/or ([adj adjs]
[dir dirs])
(if (for/and ([p adj])
(not (set-member? occupied (vector-map + elf p))))
(begin
(hash-update! next
(vector-map + elf dir)
(lambda (l) (cons elf l))
'())
#t) ;; break
#f))))
(set! adjs (append (cdr adjs) (list (car adjs))))
(set! dirs (append (cdr dirs) (list (car dirs))))
(define moved #f)
(for ([(cand elf) next])
(when (= (length elf) 1)
(set-remove! occupied (first elf))
(set-add! occupied cand)
(set! moved #t)))
(when (= rounds 10)
(displayln (for/fold ([min-x 9999]
[max-x -9999]
[min-y 9999]
[max-y -9999]
#:result (- (* (- max-x min-x -1)
(- max-y min-y -1))
(set-count occupied))
)
([elf occupied])
(values (min min-x (vector-ref elf 0))
(max max-x (vector-ref elf 0))
(min min-y (vector-ref elf 1))
(max max-y (vector-ref elf 1))))))
;; 3940
(if moved
(loop (+ rounds 1))
(displayln rounds)))
;; 990
|