aoc

ref: master

2020/src/aoc/day10.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
 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
130
131
132
133
134
135
136
(ns aoc.day10
  (:require [clojure.java.io :as io])
  (:gen-class))

;; (defn read-input []
;;   (line-seq
;;     (io/reader
;;       (io/resource "input10.txt"))))

(def example "16
10
15
5
1
11
7
19
6
12
4")

(def example2 "28
33
18
42
31
14
46
20
48
47
24
23
49
45
19
38
39
11
1
32
25
35
8
17
7
9
4
2
34
10
3")

(defn read-input []
  (->>
       (io/resource "input10.txt")
       io/reader
       line-seq

       ;; example2
       ;; clojure.string/split-lines

       (map read-string)))

(defn builtin [ratings]
  (->> (apply max ratings)
       (+ 3)))

(defn jolts [input]
  (let [device (builtin input)
        input (conj input device)
        input (sort input)]
    (reduce (fn [acc adap]
              (let [prev (:i acc)
                    diff (- adap prev)]
                (if (= 3 diff)
                  (assoc acc :i adap :j3 (inc (:j3 acc)))
                  (assoc acc :i adap :j1 (inc (:j1 acc))))))
            {:i 0 :j1 0 :j3 0}
            input)))

(defn next-coll [[n & coll]]
  (filter #(and
              (> % n)
               (<= 1 (- % n) 3))
          coll))

(declare jp)

(defn jolt-possibilities [coll]
  (let [nexts (next-coll coll)]
    (if-not (seq nexts)
      coll
      (mapcat (fn [next]
                (jp
                (filter #(>= % next) coll))) nexts))))

(def jp (memoize jolt-possibilities))

(defn jolt-possibilities-2 [coll]
  (loop [acc #{}
         current 0]
    (let [nexts (next-coll coll)]
      )))

;; the recursive solution didn't work on the puzzle input because memory :(
;; the `part-2` fn is someone else's

(defn part-2 [adapters]
  (let [device (+ (apply max adapters) 3)
        ;; The number of routes to each adapter is the sum of the number of
        ;; routes to each of the possible previous adapters (it's like a messy
        ;; Pascal's triangle) so we can get the solution in one pass.
        routes (reduce
                 (fn [r a]
                   (assoc r a
                     (apply + (map #(get r % 0) (range (- a 3) a)))))
                 {0 1}
                 (sort (conj adapters device)))]
    (get routes device)))

(defn compute-1 [input]
  (let [{:keys [j1 j3]} (jolts input)]
    (* j1 j3)))

(defn compute-2 [input]
  (let [input (cons 0 input)
        device (builtin input)
        input (conj input device)
        input (sort input)]
    (count (jp input))))

(defn main []
  (let [input (read-input)]
    (println (compute-1 input))
    (println (part-2 input))))