From da6af5f342fe81913ba229aa32ca5de1dafbc525 Mon Sep 17 00:00:00 2001 From: Adam Jeniski Date: Thu, 14 Dec 2023 12:36:34 -0500 Subject: [PATCH] push garbage code --- 2023/src/day12.clj | 59 +++++++++++++++++++++++ 2023/src/day13.clj | 117 +++++++++++++++++++++++++++++++++++++++++++++ 2023/src/day14.clj | 90 ++++++++++++++++++++++++++++++++++ 3 files changed, 266 insertions(+) create mode 100644 2023/src/day12.clj create mode 100644 2023/src/day13.clj create mode 100644 2023/src/day14.clj diff --git a/2023/src/day12.clj b/2023/src/day12.clj new file mode 100644 index 0000000..51a4dc8 --- /dev/null +++ b/2023/src/day12.clj @@ -0,0 +1,59 @@ +(ns day12 + (:require + [clojure.string :as str] + [core :refer [get-puzzle-input]])) + +(defn parse-line [line] (-> (str/split line #" ") + (update 1 #(->> (str/split % #",") + (mapv parse-long))))) + +(defn make-anso [] + (with-local-vars + [ans (memoize + (fn f [dots blocks i bi current] + (let [len-blocks (count blocks) + dot_i (when (< i (count dots)) (get dots i))] + (if (= i (count dots)) + (cond (and (= bi len-blocks) + (= current 0)) + 1 + (and (= bi (dec len-blocks)) + (= current (get blocks bi))) + 1 + :else + 0) + (->> [\. \#] + (map #(if (or (= dot_i %) + (= dot_i \?)) + (cond (and (= % \.) + (= current 0)) + (f dots blocks (inc i) bi 0) + + (and (= % \.) + (> current 0) + (< bi len-blocks) + (= (get blocks bi) current)) + (f dots blocks (inc i) (inc bi) 0) + + (= % \#) + (f dots blocks (inc i) bi (inc current)) + + :else 0) + 0)) + (reduce +))))))] + (.bindRoot ans @ans) + @ans)) + +(->> (get-puzzle-input 12) + (map parse-line) + (map #((make-anso) (first %) (second %) 0 0 0)) + (reduce +)) + +(->> (get-puzzle-input 12) + (map parse-line) + (mapv (fn [[s cnts]] + [(str/join (interpose "?" (repeat 5 s))) + (vec (apply concat (repeat 5 cnts)))])) + (pmap #((make-anso) (first %) (second %) 0 0 0)) + (reduce +)) + diff --git a/2023/src/day13.clj b/2023/src/day13.clj new file mode 100644 index 0000000..7f51d5a --- /dev/null +++ b/2023/src/day13.clj @@ -0,0 +1,117 @@ +(ns day13 + (:require + [clojure.string :refer [split-lines]] + [core :refer [get-puzzle-input]])) + +(def input (->> (get-puzzle-input 13) + (partition-by empty?) + (filter (comp not-empty first)))) + +(def sample-input (->> (split-lines "#.##..##. +..#.##.#. +##......# +##......# +..#.##.#. +..##..##. +#.#.##.#. + +#...##..# +#....#..# +..##..### +#####.##. +#####.##. +..##..### +#....#..#") + (partition-by empty?) + (filter (comp not-empty first)))) + +(defn get-col [m c] (->> m + (filter (fn [[[_ col]]] + (= c col))) + (map second))) + +(defn get-row [m r] (->> m + (filter (fn [[[row]]] (= r row))) + (map second))) + +(defn get-refl-value [m num-rows num-cols & [discriminator]] + (let [rows (range 0 num-rows) + cols (range 0 num-cols)] + (when discriminator + (println discriminator)) + (or (->> cols + (map #(for [c (range (min (inc %) (- (dec num-cols) %)))] + [(- % c) (inc (+ % c))])) + (filter not-empty) + (filter #(or (not= (second discriminator) :row) + (not= (first discriminator) %))) + (map (partial map (fn [[a b]] + ; (println a b :col discriminator) + (= (get-col m a) + (get-col m b))))) + (map-indexed vector) + (filter (comp (partial every? identity) + second)) + (filter second) + first + (#(when % + [(inc (first %)) :col]))) + (->> rows + (map #(for [r (range (min (inc %) (- (dec num-rows) %)))] + [(- % r) (inc (+ % r))])) + (filter not-empty) + (filter #(or (not= (second discriminator) :row) + (not= (first discriminator) %))) + (map (partial map (fn [[a b]] + ; (println a b :row discriminator) + (= (get-row m a) + (get-row m b))))) + (map-indexed vector) + (filter (comp (partial every? identity) + second)) + (filter second) + first + (#(when % + [(inc (first %)) :row])))))) + +(defn gen-map [input] + (->> input + (map-indexed (fn [row line] + (map-indexed (fn [col c] [[row col] c]) + line))) + (apply concat) + (into (sorted-map)))) + +;; part 1 +(->> input + (map #(get-refl-value (gen-map %) + (count %) + (count (first %)))) + (map #(update % 1 (fn [x] (condp = x + :col 1 + :row 100)))) + (map (partial apply *)) + (reduce +)) + +;; part 2 +(->> sample-input + (mapv #(let [num-rows (count %) + num-cols (count (first %)) + m (gen-map %) + smudge (get-refl-value m num-rows num-cols)] + (->> + (for [r (range num-rows) + c (range num-cols)] + (let [m-prime (update m [r c] (fn [c] (if (= c \#) \. \#))) + res (get-refl-value m-prime num-rows num-cols smudge)] + res)) + (filter identity) + first))) + ; (map get-refl-value) + ; (map #(update % 1 (fn [x] (condp = x + ; :col 1 + ; :row 100)))) + ; (map (partial apply *)) + ; (reduce +) + ) + diff --git a/2023/src/day14.clj b/2023/src/day14.clj new file mode 100644 index 0000000..c69ed38 --- /dev/null +++ b/2023/src/day14.clj @@ -0,0 +1,90 @@ +(ns day14 + (:require + [clojure.string :as str] + [core :refer [get-puzzle-input]])) + +(comment + + (def input (reverse (str/split-lines "O....#.... +O.OO#....# +.....##... +OO.#O....O +.O.....O#. +O.#..O.#.# +..O..#O..O +.......O.. +#....###.. +#OO..#...."))) + + (def input (reverse (get-puzzle-input 14)))) + +(defn sorting-fn [& args] + (apply compare (map (juxt #(* -1 (first %)) + #(second %)) + args))) + +(defn gen-map [input] + (->> input + (map-indexed (fn [row line] + (map-indexed (fn [col c] + [[(inc row) (inc col)] c]) + line))) + (apply concat) + (into (sorted-map-by sorting-fn)))) + +(def empty-space-chars #{\. \O}) + +(defn get-next-pos [[r c] dir] + (condp = dir + :north [(inc r) c] + :east [r (inc c)] + :south [(dec r) c] + :west [r (dec c)])) + +(defn next-os [m os dir] + (->> os + (map (fn [pos] + (let [next-pos (get-next-pos pos dir) + ch (m next-pos)] + (if (and ch + (empty-space-chars ch) + (not (os next-pos))) + next-pos + pos)))) + (into (sorted-set-by sorting-fn)))) + +(defn print-board [m os] + (println) + (doseq [line (->> m + (group-by ffirst) + (sort-by first) + (reverse) + (map second) + (map (partial map #(cond (os (first %)) \O + (= (second %) \O) \. + :else (second %)))) + (map #(str/join "" %)))] + (println line))) + +(->> (let [m (gen-map input)] + (loop [os (->> m + (filter #(= (second %) \O)) + (map first) + (into (sorted-set-by sorting-fn))) + dirs (take (* 1000 4) (cycle [:north :west :south :east])) + dbg 1] + (if (not-empty dirs) + (let [os' (next-os m os (first dirs))] + (if (= os os') + + (recur os (rest dirs) (if (= (first dirs) :east) + (do (println dbg (reduce + (map first os))) + (inc dbg)) + dbg)) + (recur os' dirs dbg))) + os))) + (map first) + (reduce +)) + +;; pushing garbage code. use prints to uncover cycles. use basic math to find p2 solution +