Add correct day3pt2 solution
[adventofcode2019.git] / src / adventofcode2019 / day03.clj
CommitLineData
3887e35c
JK
1(ns adventofcode2019.day03
2 [:require [adventofcode2019.lib :refer :all]
3 [clojure.string :as str]
4 [clojure.set :as set]
5 [clojure.math.combinatorics :as combo]])
6
7(defn parse-input [input]
8 (map #(str/split % #",") (str/split-lines (str/trim (slurp input)))))
9
10(defn spec->op [spec]
11 (let [direction (first spec)
12 distance (parse-int (str/join (rest spec)))]
13 (case direction
14 \U (fn [[x y]] [x (+ y distance)])
15 \D (fn [[x y]] [x (- y distance)])
16 \R (fn [[x y]] [(+ x distance) y])
17 \L (fn [[x y]] [(- x distance) y]))))
18
19
20(defn ints-between [x y]
21 (cond
1d6c8034 22 (> x y) (reverse (range y (inc x)))
3887e35c
JK
23 (< x y) (range x (inc y))
24 :else [x]))
25
26(defn points-diff [pos-a pos-b]
27 (let [[a-x a-y] pos-a
28 [b-x b-y] pos-b]
1d6c8034
JK
29 (rest (for [x (ints-between a-x b-x)
30 y (ints-between a-y b-y)]
31 [x y]))))
3887e35c
JK
32
33(defn wire-spec->points [wire]
34 (let [wire-ops (map spec->op wire)
35 trace-reduction (fn [{:keys [pos points]} op]
36 (let [new-pos (op pos)
37 new-points (points-diff pos new-pos)]
1d6c8034
JK
38 {:pos new-pos :points (concat points new-points)}))
39 trace (reduce trace-reduction {:pos [0 0], :points []} wire-ops)]
3887e35c
JK
40 (:points trace)))
41
42(defn find-intersections [wires]
1d6c8034
JK
43 (let [wires-points (map wire-spec->points wires)
44 intersections (apply set/intersection (map set wires-points))
45 find-steps (fn [i pos] (when (intersections pos) {pos (inc i)}))
46 step-counts (map #(map-indexed find-steps %) wires-points)]
47 (apply (partial merge-with +) (flatten step-counts))))
3887e35c
JK
48
49(defn day03 []
50 (let [wires (parse-input (input-file))
51 manhattan-distance (fn [[x y]] (+ (Math/abs x) (Math/abs y)))
52 intersections (find-intersections wires)]
1d6c8034
JK
53 (println (apply min (map manhattan-distance (keys intersections))))
54 (println (apply min (vals intersections)))))