From 78f92480fd5eb975dd0a9e7bafc21ae2f721fdea Mon Sep 17 00:00:00 2001 From: Nikita Hasert Date: Fri, 22 Dec 2023 21:42:11 +0100 Subject: [PATCH] Day 21: Solve part 1 and look up a solutions for part 2 --- src/advent_of_code_2023/day21.clj | 58 +++++++++++++++++++++++-- test/advent_of_code_2023/day21_test.clj | 26 ++++++----- 2 files changed, 68 insertions(+), 16 deletions(-) diff --git a/src/advent_of_code_2023/day21.clj b/src/advent_of_code_2023/day21.clj index 04278bb..282702b 100644 --- a/src/advent_of_code_2023/day21.clj +++ b/src/advent_of_code_2023/day21.clj @@ -1,9 +1,59 @@ (ns advent-of-code-2023.day21 (:require - [advent-of-code-2023.utils.string :as u])) + [advent-of-code-2023.utils.graph :as g])) -(defn parse-input [input]) +(defn parse-input [input] + (let [{:keys [positions] :as garden} (g/parse-positional-map input identity)] + (assoc garden :start + (first (mapv first (filterv (fn [[p v]] (= v \S)) positions)))))) -(defn day21-1 [parsed-input]) +(defn- neighbours [p] + [(update p 0 inc) + (update p 0 dec) + (update p 1 inc) + (update p 1 dec)]) -(defn day21-2 [parsed-input]) \ No newline at end of file +(defn- garden-positions-step-fn [positions adjusted-pos] + (fn [garden-positions] + (persistent! + (transduce + (comp + (mapcat neighbours) + (filter (comp #{\. \S} positions adjusted-pos)) + (distinct)) + conj! (transient []) garden-positions)))) + +(defn- day21 [{:keys [positions]} starts ^long steps adjusted-pos] + (let [garden-positions-step (garden-positions-step-fn positions adjusted-pos)] + (loop [steps ^long steps + current-positions starts] + (if (pos? steps) + (let [new-positions (garden-positions-step current-positions)] + (recur (dec steps) + new-positions)) + current-positions)))) + +(defn day21-1 [{:keys [start] :as garden} steps] + (count (day21 garden [start] steps identity))) + +(defn- adjust-infinity-fn [^long height ^long width] + (fn [[^long x ^long y]] + [(mod (if (<= 0 x) x (+ x width)) width) + (mod (if (<= 0 y) y (+ y width)) height)])) + +;; Monkey see, monkey do: +;; https://github.com/goggle/AdventOfCode2023.jl/blob/main/src/day21.jl#L44 +(defn day21-2 [{:keys [^long height ^long width start] :as garden} ^long steps] + (let [adjust-infinity (adjust-infinity-fn height width) + w width + w2 (quot width 2) + pos1 (day21 garden [start] w2 adjust-infinity) + pos2 (day21 garden pos1 w adjust-infinity) + r1 (count pos1) + r2 (count pos2) + r3 (count (day21 garden pos2 w adjust-infinity)) + a ^long (quot (- (+ r3 r1) (* 2 r2)) 2) + b ^long (quot (- (- (* 4 r2) (* 3 r1)) r3) 2) + c r1 + x ^long (quot (- steps w2) w)] + (+ (* a x x) (* b x) c))) \ No newline at end of file diff --git a/test/advent_of_code_2023/day21_test.clj b/test/advent_of_code_2023/day21_test.clj index 0493c84..8bbff58 100644 --- a/test/advent_of_code_2023/day21_test.clj +++ b/test/advent_of_code_2023/day21_test.clj @@ -4,26 +4,28 @@ [advent-of-code-2023.day21 :refer :all] [advent-of-code-2023.test-utils :as tu])) -(defonce ^:private example-input (parse-input "")) +(defonce ^:private example-input (parse-input "........... +.....###.#. +.###.##..#. +..#.#...#.. +....#.#.... +.##..S####. +.##..#...#. +.......##.. +.##.#.####. +.##..##.##. +...........")) (def ^:private input (parse-input (tu/slurp-input "resources/day21.txt"))) (deftest day21-1-example-test (testing "day21-1 example" - (is (= nil - (day21-1 example-input))))) + (is (= 16 (day21-1 example-input 6))))) (deftest day21-1-test (testing "day21-1" - (is (= nil - (day21-1 input))))) - -(deftest day21-2-example-test - (testing "day21-2 example" - (is (= nil - (day21-2 example-input))))) + (is (= 3733 (day21-1 input 64))))) (deftest day21-2-test (testing "day21-2" - (is (= nil - (day21-2 input))))) + (is (= 617729401414635 (day21-2 input 26501365)))))