Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (ns day06
- (:require [clojure.java.io :as io]))
- (defn parse-map [matrix]
- (let [X (count matrix)
- Y (count (first matrix))]
- (reduce (fn [acc [x y]]
- (let [cur-ch (aget matrix x y)]
- (case cur-ch
- \^ (assoc acc :soldier {:x x :y y :dir :n})
- \# (update acc :barriers conj {:x x :y y})
- \. acc)))
- {:X (count matrix)
- :Y (count (first matrix))
- :matrix matrix
- :barriers #{}
- :soldier nil}
- (for [x (range X)
- y (range Y)]
- [x y]))))
- (defn input-map
- ([]
- (input-map "./src/day06/input"))
- ([input-file]
- (->> input-file
- io/reader
- line-seq
- to-array-2d
- parse-map)))
- (defn turn-soldier [pos]
- "returns the next direction of the soldier after a 90 degrees turn."
- (update pos :dir {:n :e
- :e :s
- :s :w
- :w :n}))
- (defn update-pos [{:keys [dir] :as pos}]
- (case dir
- :n (update pos :x dec)
- :s (update pos :x inc)
- :w (update pos :y dec)
- :e (update pos :y inc)))
- (defn blocked? [{:keys [barriers]} pos]
- (let [next-pos (select-keys (update-pos pos) [:x :y])]
- (barriers next-pos)))
- (defn final-pos? [{:keys [X Y]} {:keys [x y dir]}]
- (case dir
- :n (= 0 x)
- :s (= x (dec X))
- :w (= 0 y)
- :e (= y (dec Y))))
- (defn move-soldier
- [soldier-map pos]
- (cond
- (blocked? soldier-map pos)
- (turn-soldier pos)
- (final-pos? soldier-map pos)
- nil
- :else
- (update-pos pos)))
- (defn move-generator
- ([{:keys [soldier] :as m}]
- (move-generator m soldier))
- ([soldier-map pos]
- (lazy-seq
- (when pos
- (cons pos
- (move-generator soldier-map (move-soldier soldier-map pos)))))))
- (comment
- (= 41 (->> (input-map "./src/day06/input-redux")
- (move-generator)
- (seq)
- (map #(select-keys % [:x :y]))
- (set)
- (count)))
- (= 4752 (->> (input-map "./src/day06/input")
- (move-generator)
- (seq)
- (map #(select-keys % [:x :y]))
- (set)
- (count))))
- (defn corner-generator
- [soldier-map]
- (->> soldier-map
- (move-generator)
- (partition-by :dir)
- (map last)))
- (comment
- (->> (input-map "./src/day06/input-redux")
- (corner-generator)
- (seq)))
- (defn add-barrier [soldier-map barrier]
- (update soldier-map :barriers conj barrier))
- (defn will-cycle?
- ([soldier-map barrier]
- (will-cycle? (add-barrier soldier-map barrier)))
- ([soldier-map]
- (= :cycle
- (reduce
- (fn [corners next-corner]
- (if (corners next-corner)
- (reduced :cycle)
- (conj corners next-corner)))
- #{}
- (corner-generator soldier-map)))))
- (defn blocking-positions
- [soldier-map]
- (reduce
- (fn [blocks pos]
- (let [next-barrier (select-keys pos [:x :y])]
- (if (will-cycle? soldier-map next-barrier)
- (conj blocks next-barrier)
- blocks)))
- #{}
- (move-generator soldier-map)))
- (->> (or (first *command-line-args*) "input.txt")
- (input-map)
- (blocking-positions)
- (count))
- (comment
- @(def soldier-map (input-map "./src/day06/input-redux"))
- (def correct-blocks
- #{{:x 6 :y 3}
- {:x 7 :y 6}
- {:x 7 :y 7}
- {:x 8 :y 1}
- {:x 8 :y 3}
- {:x 9 :y 7}})
- (blocking-positions soldier-map)
- (= 6 (count (blocking-positions soldier-map))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement