Skip to content

Instantly share code, notes, and snippets.

@Solaxun
Created December 15, 2018 23:08
Show Gist options
  • Save Solaxun/1b4b7ada84b936d43fbee04ede0062f4 to your computer and use it in GitHub Desktop.
Save Solaxun/1b4b7ada84b936d43fbee04ede0062f4 to your computer and use it in GitHub Desktop.
2018 Advent of Code Day 13
(ns aoc2018-clj.day13
(:require [clojure.string :as str]
[clojure.java.io :as io]
[clojure.math.combinatorics :as combs]
[clojure.set :as set]))
(def track (str/split-lines (-> "day13.txt" io/resource slurp)))
(def race-track (mapv vec track))
(defn intersection-rule [{:keys [loc dir turn-count] :as car}]
(assoc car :dir
(case (mod turn-count 3)
0 ({\> \^ \< \v \v \> \^ \<} dir) ;; turn left
1 dir ;; straight
2 ({\> \v \< \^ \v \< \^ \>} dir)) ;; turn right
:turn-count (inc turn-count)))
(defn change-dir
[{:keys [loc dir turn-count] :as car} road-segment]
(case road-segment
\/ (update car :dir {\^ \> \v \< \> \^ \< \v})
\\ (update car :dir {\^ \< \v \> \> \v \< \^})
\+ (intersection-rule car)
car))
(defn drive [{:keys [loc dir turn-count] :as car}]
(let [from->to {\> [0 1] \< [0 -1] \^ [-1 0] \v [1 0]}
destination (mapv + (from->to dir) loc)
road-segment (get-in race-track destination)]
(-> (change-dir car road-segment)
(assoc :loc destination))))
(defn make-cars [initial-track]
(for [i (range (count initial-track))
j (range (count initial-track))
:let [dir (get-in initial-track [i j])]
:when (contains? #{\< \> \^ \v} dir)]
{:loc [i j] :dir dir :turn-count 0}))
(defn advance-cars [cars]
(let [cars (sort-by :loc cars)]
(reduce
(fn [[full? new-cars] car]
(let [next-car (drive car)
next-loc (:loc next-car)]
(if (full? next-loc)
(reduced [#{} [(assoc next-car :collision true)]])
[(conj (set/difference full? #{(:loc car)}) next-loc)
(conj new-cars next-car)])))
[(set (map :loc cars)) []]
(sort-by :loc cars))))
(defn collision? [cars]
(some #(when (contains? % :collision) %) cars))
(defn part1 []
(loop [[full? cars] [#{} (make-cars race-track)]]
;(show-track (place-cars (clear-track race-track) cars))
(if-let [collision (collision? cars)]
collision
(recur (advance-cars cars)))))
;;pt 2
(defn advance-cars2 [cars]
(loop [[c & cs] (sort-by :loc cars)
full? (set (map :locs cars))
new-cars []]
(if (empty? c)
new-cars
(let [new-car (drive c)
new-loc (:loc new-car)]
(if (full? new-loc)
(recur (remove #(= (:loc %) new-loc) cs) ;remove preserves sorted orer
(disj full? (:loc c) new-loc)
(remove #(= (:loc %) new-loc) new-cars))
(recur cs
(conj (disj full? (:loc c)) new-loc)
(conj new-cars new-car)))))))
(defn part2 []
(some #(when (= 1 (count %)) %)
(iterate advance-cars2 (make-cars race-track))))
(part1)
(part2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment