-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday11.rkt
111 lines (86 loc) · 3.59 KB
/
day11.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
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#lang racket
(require point-free "utils.rkt")
(provide part1 part2)
(define/compose get-input (curry map string->list) file->lines)
(define input (get-input "input/d11"))
(define num-rows (length input))
(define num-cols (length (first input)))
; TODO optimize
(define (part1)
(let ([final-grid (step1-until-unchanged input)])
(apply + ((count-occupied-over-grid) final-grid))))
(define (part2)
(let ([final-grid (step2-until-unchanged input)])
(apply + (( count-value-over-grid #\# ) final-grid))))
(define (count-occupied-over-grid) (count-value-over-grid #\#))
(define (count-value-over-grid value) (curry map (curry count-value value)))
(define (step1-until-unchanged grid)
(let ([next-grid (step1 grid)])
(if (equal? next-grid grid) next-grid (step1-until-unchanged next-grid))))
(define (step1 grid)
(map-grid-cells
grid
(lambda (row col) (let ([seat (grid-ref grid row col)]
[adj-occ (count-adjacent-occupied grid row col)])
(match seat
[#\L (if (= adj-occ 0) #\# seat)]
[#\# (if (>= adj-occ 4) #\L seat)]
[_ seat]) ))))
(define (step2-until-unchanged grid)
(let ([next-grid (step2 grid)])
(if (equal? next-grid grid) next-grid (step2-until-unchanged next-grid))))
(define (step2 grid)
(map-grid-cells
grid
(lambda (row col) (let ([seat (grid-ref grid row col)]
[vis-occ (count-visible-occupied grid row col)])
(match seat
[#\L (if (= vis-occ 0) #\# seat)]
[#\# (if (>= vis-occ 5) #\L seat)]
[_ seat]) ))))
(define (map-grid-cells grid func)
(map (lambda (row)
(map (lambda (col) (func row col))
(range 0 num-cols)))
(range 0 num-rows)))
(define directions '(top-left
top
top-right
left
right
bottom-left
bottom
bottom-right))
(define (count-adjacent-occupied grid row col)
(count-value #\# (adjacent-seats grid row col)))
(define (adjacent-seats grid row col)
(map (lambda (direction) (grid-ref grid
(get-row-to-check row direction)
(get-col-to-check col direction)))
directions))
(define (count-visible-occupied grid row col)
(count-value #t (map (curry visible-occupied? grid row col) directions)))
(define (visible-occupied? grid row col direction)
(let* ([row-to-check (get-row-to-check row direction)]
[col-to-check (get-col-to-check col direction)])
(if (outside-grid? grid row-to-check col-to-check)
#f
(match (grid-ref grid row-to-check col-to-check)
[#\# #t]
[#\L #f]
[_ (visible-occupied? grid row-to-check col-to-check direction)]))))
(define (get-row-to-check row direction)
(+ row (match direction
[(or 'top-left 'top 'top-right) -1]
[(or 'left 'right) 0]
[(or 'bottom-left 'bottom 'bottom-right) +1])))
(define (get-col-to-check col direction)
(+ col (match direction
[(or 'top-left 'left 'bottom-left) -1]
[(or 'top 'bottom) 0]
[(or 'top-right 'right 'bottom-right) +1])))
; Treat positions outside the grid as floor
(define (grid-ref grid row col)
(if (outside-grid? grid row col) #\. (list-ref (list-ref grid row) col)))
(define (outside-grid? grid row col)
(or (< row 0) (>= row num-rows) (< col 0) (>= col num-cols)))