--- /dev/null
+(ns adventofcode2019.day03
+ [:require [adventofcode2019.lib :refer :all]
+ [clojure.string :as str]
+ [clojure.set :as set]
+ [clojure.math.combinatorics :as combo]])
+
+(defn parse-input [input]
+ (map #(str/split % #",") (str/split-lines (str/trim (slurp input)))))
+
+(defn spec->op [spec]
+ (let [direction (first spec)
+ distance (parse-int (str/join (rest spec)))]
+ (case direction
+ \U (fn [[x y]] [x (+ y distance)])
+ \D (fn [[x y]] [x (- y distance)])
+ \R (fn [[x y]] [(+ x distance) y])
+ \L (fn [[x y]] [(- x distance) y]))))
+
+
+(defn ints-between [x y]
+ (cond
+ (> x y) (range y (inc x))
+ (< x y) (range x (inc y))
+ :else [x]))
+
+(defn points-diff [pos-a pos-b]
+ (let [[a-x a-y] pos-a
+ [b-x b-y] pos-b]
+ (set (for [x (ints-between a-x b-x)
+ y (ints-between a-y b-y)]
+ [x y]))))
+
+(defn wire-spec->points [wire]
+ (let [wire-ops (map spec->op wire)
+ trace-reduction (fn [{:keys [pos points]} op]
+ (let [new-pos (op pos)
+ new-points (points-diff pos new-pos)]
+ {:pos new-pos :points (set/union points new-points)}))
+ trace (reduce trace-reduction {:pos [0 0], :points #{}} wire-ops)]
+ (:points trace)))
+
+(defn find-intersections [wires]
+ (let [wires-points (map wire-spec->points wires)]
+ (set/difference (apply set/intersection wires-points) #{[0 0]})))
+
+(defn day03 []
+ (let [wires (parse-input (input-file))
+ manhattan-distance (fn [[x y]] (+ (Math/abs x) (Math/abs y)))
+ intersections (find-intersections wires)]
+ (println (apply min (map manhattan-distance intersections)))))