/
day_14.clj
72 lines (64 loc) · 1.86 KB
/
day_14.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
(ns advent-of-code-2015.day-14
(:gen-class))
(defn reindeer-distance
[speed fly-time rest-time t]
(let [phase-time (+ fly-time rest-time)
phase-dist (* speed fly-time)
n-phases (quot t phase-time)
delta-t (mod t phase-time)]
(+ (* n-phases phase-dist)
(if (<= delta-t fly-time)
(* delta-t speed)
phase-dist))))
(defn parse-reindeer
[line]
(let [[[speed _] [fly-time _] [rest-time _] _] (re-seq #"([\d]+)" line)]
{:speed (Long. speed)
:fly (Long. fly-time)
:rest (Long. rest-time)
:mode :fly
:time (Long. fly-time)
:dist 0
:points 0}))
(defn tick
[r]
(-> r
(update :dist (if (= (:mode r) :fly) (partial + (:speed r)) identity))
(update :time dec)
(#(if (= 0 (:time %))
(assoc %
:mode (condp = (:mode %) :fly :rest :rest :fly)
:time (condp = (:mode %) :fly (:rest %) :rest (:fly %)))
%))))
(defn race
([t-end rs]
(race 0 t-end rs))
([t t-end rs]
(if (= t t-end) rs
(recur (inc t) t-end
(let [rs' (map tick rs)
max-dist (:dist (apply max-key :dist rs'))]
(map #(update % :points (if (= max-dist (:dist %))
inc identity))
rs'))))))
(defn part-1
[input t]
(->> input
(clojure.string/split-lines)
(map parse-reindeer)
(map #(reindeer-distance (:speed %) (:fly %) (:rest %) t))
(apply max)))
(defn part-2
[input]
(->> input
(clojure.string/split-lines)
(map parse-reindeer)
(race 2503)
(apply max-key :points)
(:points)))
(defn day-14
[input-file]
(let [input (slurp input-file)]
(println "Day 14")
(println "Winning distance at t=2503: " (part-1 input 2503) "km")
(println "Winning points: " (part-2 input))))