(ns edition2022.day9
(:require [clojure.string :as str]))
(def example "R 4\nU 4\nL 3\nD 1\nR 4\nD 1\nL 5\nR 2")
(def example-lines (str/split-lines example))
(def example-lines2 (str/split-lines "R 5\nU 8\nL 8\nD 3\nR 17\nD 10\nL 25\nU 20\n"))
(defn expand-move [[direction times]]
(->> (cond
(= direction "R") [1 0]
(= direction "L") [-1 0]
(= direction "U") [0 1]
(= direction "D") [0 -1])
(iterate identity)
(take (Integer/parseInt times))))
(defn expand-moves [lines]
(->> lines
(map #(str/split % #" "))
(map expand-move)
(apply concat)
))
(defn update-position [pos move]
[(+ (first move) (first pos)) (+ (second move) (second pos))])
(defn tail-head-distance [tail head]
(->> (interleave head tail)
(partition 2)
(map #(reduce - %))
(into [])))
(defn update-tail [tail new-head]
(let [new-distance (tail-head-distance tail new-head)]
(cond
(or (= [2 1] new-distance) (= [1 2] new-distance) (= [2 2] new-distance)) (update-position tail [1 1])
(or (= [-2 1] new-distance) (= [-1 2] new-distance) (= [-2 2] new-distance)) (update-position tail [-1 1])
(or (= [2 -1] new-distance) (= [1 -2] new-distance) (= [2 -2] new-distance)) (update-position tail [1 -1])
(or (= [-2 -1] new-distance) (= [-1 -2] new-distance) (= [-2 -2] new-distance)) (update-position tail [-1 -1])
(= [2 0] new-distance) (update-position tail [1 0])
(= [0 2] new-distance) (update-position tail [0 1])
(= [-2 0] new-distance) (update-position tail [-1 0])
(= [0 -2] new-distance) (update-position tail [0 -1])
:else tail)))
(defn move-rope
([rope move] (move-rope rope move 0))
([rope move knot]
(if (= (count rope) (inc knot))
rope
(let [head (nth rope knot)
tail (nth rope (inc knot))
new-head (if (= knot 0) (update-position head move) head)
new-tail (update-tail tail new-head)
]
(recur (assoc rope knot new-head (inc knot) new-tail) move (inc knot))))
))
(defn execute-moves ([lines] (execute-moves lines 2))
([lines rope-length]
(loop [moves (expand-moves lines)
rope (into [] (repeat rope-length [0 0]))
tail-visited (vector)]
(if (empty? moves)
tail-visited
(let [next-move (first moves)
new-rope (move-rope rope next-move)]
(recur (rest moves) new-rope (conj tail-visited (last new-rope))))))))
(comment
(tail-head-distance [0 1] [0 3])
(tail-head-distance [-2 -1] [-1 -2])
(expand-move ["U" 3])
(expand-moves example-lines)
(count (set (execute-moves example-lines)))
(count (set (execute-moves (str/split-lines (slurp "resources/day9.in")))))
(count (set (execute-moves example-lines2 10)))
(count (set (execute-moves (str/split-lines (slurp "resources/day9.in")) 10)))
(set (execute-moves example-lines2 10))
(execute-moves ["R 4" "U 4"] 10)
(execute-moves [(first example-lines2) (second example-lines2) (nth example-lines2 3)] 10)
(execute-moves ["R 5" "U 8" "L 8" "D 3" "R 17"] 10)
example-lines2
(move-rope [[5 2] [5 1] [3 0] [2 0] [1 0] [0 0] [0 0] [0 0] [0 0] [0 0]] [0 1])
)