-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday23.clj
81 lines (71 loc) · 8.61 KB
/
day23.clj
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
(ns aoc.day23
(:require [clojure.string :as str]
[clojure.set :as set]))
(def input "#.....###.....#.###....#.#..#...###..#..#....#.#.......#.##.###.####.#...#\n##.#..#.#.#.#..##.##......####.##.##...#...##..#.....####..#.#..###...#..#\n.#.###...##.#.###.#..##.#..#.###..#.###..#..##.##.########....#...#...##..\n##.#...#.##..#...############.#..#..##.#.#.#.####....#.##....#...##.####..\n##.#.###....#.##.##.#.####....####.###.#..#...#####.#..###.#.###.....#.#..\n.#..#####.#...###..#..#..###..#.#...#.###.###.#.##.#.....#.#.##.##.#.....#\n#.#...##..#.###.##.##.##........#.#.##....#..##...#..#####..##..#....#.##.\n###....###..#..#.....#..####...###.#.#....#.#.#.#..##.###.#..#..######....\n#..#..#...#.#.#.#....#.#.##.#.#.#.#######..#.##...##..####.###.##.#.###.#.\n###.##...#...##..#...#.##.##.##.#.#.#.#..#.#.#...###....#.#.##.....###....\n....##...##.#.##.#..#...#..#...#.##.#...##..#...#.##...##..#.#.##..#.#....\n##.....#.##....##...###.#.#####...####.###....#######.#.....##.#.#..#.##..\n.......#####..#.###.#...###..##.##..#.#.###...#..#..##..##.#..#.#..#..##..\n#.#..###.#.#.#..#####....###.#..#.#.###...##....#.#.####.##...#....#.#.#..\n..#.....##.#.#..###.#...######.##....#####.###...####.#####.##..#...###.#.\n.#.####.......##.###.#..#####.#######...##.#.###..#......##..#...#.#.#.#..\n##.###.....#.##..#.#.#.#.#..##....####.#...#.###...#.####..#.#......#..#.#\n####.......##....######.#.#.#.#..#.##.###.....#...#.#..#.#.###..#.###..##.\n##..###..###...##...#.#..##.#..#.#.#.#...#..##..#.#..#....#...##...##.###.\n#....#.....####..##.#........#.#..#...#...##...##.#..#..#.#.#.#..#......##\n#.#.#..#..##.####......#..#####.#.##..##..##...####.###..#####...#.#..##.#\n####.#.##.....#..####.##.####.#####...#####.#....##....#..#..#.###.#.##.#.\n..#.##.##.##.#.#...#.###..#.##.######..#..#...#.###..###.###.#.#.#..#.#.#.\n..##..##..#..#####...##.###...###.###########.#..#######..#.#.#....#######\n#.###.#.##..######.###..##...#..##.#.###..##..#..#.#.#..#.##.#.#..#.#.####\n#....#.##...##..#.#.####.......#.#.###.#......###......#..##...#..#.####..\n##.####..######.####....#.###.##..#.#.##.#.#..##.#..##.#.##.#.##.#####..#.\n#######.####.#.##.########..#..###.###.###...##......#..##.#.#####...#...#\n#..##.#.#..######.##.##..#....#..##.#.#####.##..#.##.##..#..###.#.##..##.#\n..#.#.#..##...####....##.#.#..####..#.#####.###.#..##.....#..##..##.#.#..#\n#.###..####....####..###.#.####.#.##....#.##.###.##.###########..#..###.##\n..##.##.##.#.####......####...##..#....#####...#.#....#####..#.#####..##.#\n#..##...#...###.#..#.##.##.#.#.#....#..##.###.###.##........#..####.##...#\n...#####.####..###........#.##...##....#...#..#...##..###..#####...######.\n..#..##..#.......##.#....###..######.##.####.##..##.....##.###.#.#####.#.#\n..#.#...#.......##.##.###..#.#.#...#########..###...#....#...#.###.#..#.##\n#.#..#..######..#........##..###.##..#.##.#.#..#.#....##.#.#..#.#...#.#.#.\n#....#.#.#####.###......#..#..##.##...#......##..#.###..##.####.######.#..\n#..#.....#..####.#...##.####..######.#.#.###..##.....##.#.##.######.#.####\n....###.#######..#.##..########.....#.#..##..#.#..#.##....#.#..#..#..##.#.\n#..#.##.#.#.#.##.#.#.....#..#..#...#..##..##.#..#.##.#.#.#...##.##.#...#.#\n.#.######.#..##.#.##.....##.#.##.#.#....######..##..##.#...#...#.#.###..##\n.#.#..#..#..#..##.#.####.#.####.#....#.#.###.###.#..###..##.#...#.###.###.\n##.#.##..###.####.#.#.###.#......#####.###.######.#..######.#...#.#.####..\n###.####..#.###....#.....#.#.##.#.##.#####...##.#...#####.#.###.#..##.....\n##..#.#..#.####.#.####...###.#.##..#####.#..###...#####.####..#...#.##.#.#\n..##.#####..##.#####..#..#..#..#...##..#.###..##.#....##...#...#.#.##...##\n##...#.##..#.##...#.#.####..#.#...####..#.##.#.#...#####.##..#######.##...\n.#..####.##...#.#...##..#..###.#####.#.#.#.#..##..##.###.....#...#..####..\n.##..#...#.###.####.#.#...#...#####..#..#.#.##...#...##..#.#..#.#.#.###..#\n###.##.####.##....#.#..#.##.##..###.####..##..#.####.....#.#.###..#.######\n#.##.#.##.#..#..#.#......##.#.##.#..#.#.#.....###.....#......###....#..###\n.#..#..#....#..#.#...#..#..##......##...###.###.##...#...#.....#...###.###\n#..##..#..##.#....###...#......#.######..#.###..#.#....#......#.##..#.####\n.#...##.#..#####..##...#####.#....#######....#.....###....#..###.##..#..#.\n.###.#.##..#..#..##..#....#...#.##.##.##.#..#...##..#..##...##..######.###\n#....#.#####.###..#.#.......##..##...##..#.###..#####.#..#..##.#..#....##.\n##..#......#######...#.##.###..#.....##..#.####.###.##.#..####.#.#####.##.\n..#....###.#........#..######.#...##.......##.#.###.##.#...#.##....##.#...\n###.....#..##.####.#..###..#..#####.##.##.#######.#.####.####......#.##.##\n..#...#...#######.#.####....#.####..#..#..##.#.#.###..#.#####.##.#.....#.#\n###.#.#..#.####.##...#.#####.##.####..#.#.###.#..#...#..#########.###.#.##\n..######.########..###.#.#.###.#.#.#.#.####.#...#..##...##.#####..##...#.#\n...#.#...##.#....####.###..#..#..#..##..###.##..#.#....#..#...######.##.##\n#####.##..#..##..#####.#..#..#..###.##..##...###....#.###.#.#.##...###..##\n..#.##.#....####..#.#..###.#.#..##...#..##....####.............#.#.#..#.##\n.###...#.#....#..#.######....###.....#..#...##..##.#....##...#.###....###.\n.#.####..#.#.###..###.#..###.#..#..#######....###.......#....###.#...#.###\n###.#.###.#..#.#..###.#.....#.##..#.#.####..###...#...#####...####...##...\n.#..##..#.##..#..##..######.###.##.....##..#..#.##...####.#...#####..###.#\n..##...######.#.#...#.#.#####.##.##...##.##....#.#####...###....#.#.#.#..#\n##..#.#.#....##.####.#.##.##.#.#.##......#...##..##...##.#####...#..#..##.\n...####.#..###....#.###.#.#.........#....####..#........#.###..####.##...#\n.##.##.#####...##.....##.#..#####..##.....#....##......#.#..###..###..##..\n")
(defn find-indexes [s value]
(loop [from-index 0, indexes []]
(if-let [idx (str/index-of s value from-index)]
(recur (inc idx) (conj indexes idx))
indexes)))
(defn parse-input [input]
{:order [:N :S :W :E]
:elves (set (for [[row s] (map-indexed vector (str/split-lines input))
col (find-indexes s \#)]
[row col]))})
(defn move [[row col] direction]
(case direction
:N [(dec row) col]
:NE (-> [row col] (move :N) (move :E))
:E [row (inc col)]
:SE (-> [row col] (move :S) (move :E))
:S [(inc row) col]
:SW (-> [row col] (move :S) (move :W))
:W [row (dec col)]
:NW (-> [row col] (move :N) (move :W))))
(defn need-move? [state elf]
(let [coords (map move (repeat elf) [:N :NE :E :SE :S :SW :W :NW])]
(boolean (some (:elves state) coords))))
(defn proposals [state]
(into {} (for [elf (:elves state)
:let [[proposed-coord & _] (keep (fn [direction]
(let [coords (map move
(repeat elf)
(case direction
:N [:N :NE :NW]
:S [:S :SE :SW]
:W [:W :NW :SW]
:E [:E :NE :SE]))]
(if (some (:elves state) coords)
nil
(move elf direction))))
(:order state))]
:when (and (need-move? state elf)
(not= proposed-coord nil))]
[elf proposed-coord])))
(defn next-round [state]
(let [proposals (proposals state)
moves (->> (group-by second proposals)
(vals)
(filter #(= (count %) 1))
(map first))]
(-> state
(update :elves #(set/difference % (map first moves)))
(update :elves #(into % (map second moves)))
(update :order #(concat (rest %) [(first %)])))))
(defn empty-tiles [state]
(let [min-row (->> (:elves state) (map first) (reduce min))
max-row (->> (:elves state) (map first) (reduce max))
min-col (->> (:elves state) (map second) (reduce min))
max-col (->> (:elves state) (map second) (reduce max))]
(- (* (inc (- max-row min-row))
(inc (- max-col min-col)))
(count (:elves state)))))
(defn part1 []
(let [state (parse-input input)]
(empty-tiles (nth (iterate next-round state) 10))))
(defn part2 []
(loop [state (parse-input input), round 1]
(let [state' (next-round state)]
(if (= (:elves state) (:elves state'))
round
(recur state' (inc round))))))