Advertisement
Guest User

Untitled

a guest
Jan 15th, 2025
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Clojure 3.63 KB | Source Code | 0 0
  1. (ns day06
  2.   (:require [clojure.java.io :as io]))
  3.  
  4. (defn parse-map [matrix]
  5.   (let [X (count matrix)
  6.         Y (count (first matrix))]
  7.     (reduce (fn [acc [x y]]
  8.               (let [cur-ch (aget matrix x y)]
  9.                 (case cur-ch
  10.                   \^ (assoc acc :soldier {:x x :y y :dir :n})
  11.                   \# (update acc :barriers conj {:x x :y y})
  12.                   \. acc)))
  13.             {:X        (count matrix)
  14.              :Y        (count (first matrix))
  15.              :matrix   matrix
  16.              :barriers #{}
  17.              :soldier  nil}
  18.             (for [x (range X)
  19.                   y (range Y)]
  20.               [x y]))))
  21.  
  22. (defn input-map
  23.   ([]
  24.    (input-map "./src/day06/input"))
  25.   ([input-file]
  26.    (->> input-file
  27.         io/reader
  28.         line-seq
  29.         to-array-2d
  30.         parse-map)))
  31.  
  32. (defn turn-soldier [pos]
  33.   "returns the next direction of the soldier after a 90 degrees turn."
  34.   (update pos :dir {:n :e
  35.                     :e :s
  36.                     :s :w
  37.                     :w :n}))
  38.  
  39. (defn update-pos [{:keys [dir] :as pos}]
  40.   (case dir
  41.     :n (update pos :x dec)
  42.     :s (update pos :x inc)
  43.     :w (update pos :y dec)
  44.     :e (update pos :y inc)))
  45.  
  46. (defn blocked? [{:keys [barriers]} pos]
  47.   (let [next-pos (select-keys (update-pos pos) [:x :y])]
  48.     (barriers next-pos)))
  49.  
  50. (defn final-pos? [{:keys [X Y]} {:keys [x y dir]}]
  51.   (case dir
  52.     :n (= 0 x)
  53.     :s (= x (dec X))
  54.     :w (= 0 y)
  55.     :e (= y (dec Y))))
  56.  
  57. (defn move-soldier
  58.   [soldier-map pos]
  59.   (cond
  60.     (blocked? soldier-map pos)
  61.     (turn-soldier pos)
  62.  
  63.     (final-pos? soldier-map pos)
  64.     nil
  65.  
  66.     :else
  67.     (update-pos pos)))
  68.  
  69. (defn move-generator
  70.   ([{:keys [soldier] :as m}]
  71.    (move-generator m soldier))
  72.   ([soldier-map pos]
  73.    (lazy-seq
  74.      (when pos
  75.        (cons pos
  76.              (move-generator soldier-map (move-soldier soldier-map pos)))))))
  77.  
  78. (comment
  79.  
  80.   (= 41 (->> (input-map "./src/day06/input-redux")
  81.              (move-generator)
  82.              (seq)
  83.              (map #(select-keys % [:x :y]))
  84.              (set)
  85.              (count)))
  86.  
  87.   (= 4752 (->> (input-map "./src/day06/input")
  88.                (move-generator)
  89.                (seq)
  90.                (map #(select-keys % [:x :y]))
  91.                (set)
  92.                (count))))
  93.  
  94. (defn corner-generator
  95.   [soldier-map]
  96.   (->> soldier-map
  97.        (move-generator)
  98.        (partition-by :dir)
  99.        (map last)))
  100.  
  101. (comment
  102.  
  103.   (->> (input-map "./src/day06/input-redux")
  104.        (corner-generator)
  105.        (seq)))
  106.  
  107. (defn add-barrier [soldier-map barrier]
  108.   (update soldier-map :barriers conj barrier))
  109.  
  110. (defn will-cycle?
  111.   ([soldier-map barrier]
  112.    (will-cycle? (add-barrier soldier-map barrier)))
  113.   ([soldier-map]
  114.    (= :cycle
  115.       (reduce
  116.         (fn [corners next-corner]
  117.           (if (corners next-corner)
  118.             (reduced :cycle)
  119.             (conj corners next-corner)))
  120.         #{}
  121.         (corner-generator soldier-map)))))
  122.  
  123. (defn blocking-positions
  124.   [soldier-map]
  125.   (reduce
  126.     (fn [blocks pos]
  127.       (let [next-barrier (select-keys pos [:x :y])]
  128.         (if (will-cycle? soldier-map next-barrier)
  129.           (conj blocks next-barrier)
  130.           blocks)))
  131.     #{}
  132.     (move-generator soldier-map)))
  133.  
  134. (->> (or (first *command-line-args*) "input.txt")
  135.      (input-map)
  136.      (blocking-positions)
  137.      (count))
  138.  
  139. (comment
  140.  
  141.   @(def soldier-map (input-map "./src/day06/input-redux"))
  142.  
  143.   (def correct-blocks
  144.     #{{:x 6 :y 3}
  145.       {:x 7 :y 6}
  146.       {:x 7 :y 7}
  147.       {:x 8 :y 1}
  148.       {:x 8 :y 3}
  149.       {:x 9 :y 7}})
  150.  
  151.   (blocking-positions soldier-map)
  152.  
  153.   (= 6 (count (blocking-positions soldier-map))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement