aoc

ref: master

2020/src/aoc/day13.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
(ns aoc.day13
  (:require [clojure.java.io :as io]))

(def example "939
7,13,x,x,59,x,31,19")

(defn parse-input [[earliest timetable]]
  {:earliest (read-string earliest)
   :timetable (->> (clojure.string/split timetable #",")
                   (remove #{"x"})
                   (map read-string))})

(defn parse-input-2 [[_ timetable]]
   (->> (clojure.string/split timetable #",")
        (map read-string)))

(defn read-input []
  (->>
   ;; (io/resource "input13.txt")
   ;; slurp

       example
       clojure.string/split-lines
       parse-input
   ))

(defn short-example [s]
  (->> (clojure.string/split s #",")
       (map read-string)))

(defn read-input-2 []
  (->>
   ;; (io/resource "input13.txt")
   ;; slurp

       example
       clojure.string/split-lines
       parse-input-2
   ))

(defn tt [earliest t]
  (->> (iterate #(+ t %) 0)
       (drop-while #(< % earliest))
       first
       (conj [t])
       reverse
       vec))

(defn infinite-timetables-by-id [timetable]
  (->> timetable
       (remove symbol?)
       (map (fn [t] [t (iterate #(+ t %) 0)]))
       (into {})))

(defn compute-1 [{:keys [earliest timetable]}]
  (let [
        tts (map (partial tt earliest) timetable)
        tts (into {} tts)
        departure (apply min (keys tts))
        minutes (- departure earliest)
        bus-id (tts departure)]
    (* minutes bus-id)))

(defn bus-valid [m t bus]
  (cond
    (nil? bus) :end
    (= bus "x") true
    (symbol? bus) true
    (zero? t) true
    :else
    (let [i (get m bus)]
      (->> (drop-while #(< % t) i)
           first
           (= t)))))

(let [tts (infinite-timetables-by-id [6])
      t 5]
  (bus-valid tts t nil)
  )


(defn run-2 [tts timetable start-t]
  (loop [t start-t
         buses timetable]
    (let [bus (first buses)
          res (bus-valid tts t bus)]
      (if (contains? #{:end false} res)
          start-t
          (recur (inc t) (rest buses))))))

(defn compute-2 [timetable]
  (let [tts (infinite-timetables-by-id timetable)]
    (loop [t 100000000000000]
      (println "computing" t)
      (let [res (run-2 tts timetable t)]
        (if (contains? #{:end} res)
          t
          (recur (inc t)))))))


(defn compute-example [timetable t]
  (= (run-2 (infinite-timetables-by-id timetable)
            timetable
            t)
     t))

(comment
(compute-example (short-example "67,7,59,61") 754018)
(compute-example (short-example "17,x,13,19") 3417)
(compute-example (short-example "67,x,7,59,61") 779210)
(compute-example (short-example "67,7,x,59,61") 1261476)
(compute-example (short-example "1789,37,47,1889") 1202161486)
  )

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

;; (main)