-
Notifications
You must be signed in to change notification settings - Fork 0
/
day24.el
130 lines (107 loc) · 2.81 KB
/
day24.el
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
;; -*- lexical-binding: t -*-
(setq problem1 '(".#.##"
".#.#."
"##.#."
"####."
"#.###"))
(setq example '("....#"
"#..#."
"#..##"
"..#.."
"#...."))
(defun new-grid () (make-hash-table :test 'equal))
(cl-loop
for row being the elements of example
using (index i) do
(print (list i row)))
(defun make-grid (data)
(let ((grid (new-grid)))
(cl-loop
for row being the elements of data
using (index i) do
(cl-loop
for cell being the elements of row
using (index j) do
(puthash (cons i j) cell grid)))
grid))
(defun print-grid (grid)
(cl-loop
for i from 0 below height do
(progn
(cl-loop
for j from 0 below width do
(princ (string (gethash (cons i j) grid))))
(princ "\n"))))
(setq grid (new-grid))
(defun is-alive (pos grid)
(eq (gethash pos grid) ?#))
(defun pos-above (pos)
(cons (1- (car pos)) (cdr pos)))
(defun pos-below (pos)
(cons (1+ (car pos)) (cdr pos)))
(defun pos-left (pos)
(cons (car pos) (1- (cdr pos))))
(defun pos-right (pos)
(cons (car pos) (1+ (cdr pos))))
(defun live-neighbors (pos grid)
(+ (if (is-alive (pos-above pos) grid) 1 0)
(if (is-alive (pos-below pos) grid) 1 0)
(if (is-alive (pos-right pos) grid) 1 0)
(if (is-alive (pos-left pos) grid) 1 0)))
(defun next-live (pos grid)
(if (= (live-neighbors pos grid) 1)
?#
?.))
(defun next-dead (pos grid)
(let ((neighbors (live-neighbors pos grid)))
(if (or (= neighbors 1) (= neighbors 2))
?#
?.)))
(defun next-state (pos grid)
(if (is-alive pos grid)
(next-live pos grid)
(next-dead pos grid)))
(defun generation (grid)
(let ((new-grid (new-grid)))
(cl-loop
for i from 0 below height do
(cl-loop
for j from 0 below width do
(let ((pos (cons i j)))
(puthash pos (next-state pos grid) new-grid))))
new-grid))
(defun biodiversity-rating (grid)
(let ((total 0))
(cl-loop
for i from 0 below height do
(cl-loop
for j from 0 below width do
(if (is-alive (cons i j) grid)
(setq total (+ total (expt 2 (+ j (* i width))))))))
total))
(defun find-repeat (grid)
(let ((seen-ratings (make-hash-table))
(current-rating (biodiversity-rating grid))
(num 0))
(while (not (gethash current-rating seen-ratings))
(puthash current-rating t seen-ratings)
(setq grid (generation grid))
(setq current-rating (biodiversity-rating grid))
(setq num (1+ num)))
(print-grid grid)
(list current-rating num)))
find-repeat
(find-repeat (make-grid example))
.....
.....
.....
#....
.#...
;; => (2129920 86)
(find-repeat (make-grid problem1))
###.#
....#
..#.#
....#
#...#
;; => (18371095 25)