From 76a18ab7405d942e6d68f8b0b265a4fb3a12fc3c Mon Sep 17 00:00:00 2001 From: Aleh Suprunovich Date: Fri, 6 Dec 2024 14:21:44 +0300 Subject: [PATCH] day 6 --- src/day6.clj | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/day6.clj diff --git a/src/day6.clj b/src/day6.clj new file mode 100644 index 0000000..a83892e --- /dev/null +++ b/src/day6.clj @@ -0,0 +1,113 @@ +(ns day6 + (:require [clojure.string :as string] + [helpers :refer [get-input]])) + +(def example +"....#..... +.........# +.......... +..#....... +.......#.. +.......... +.#..^..... +........#. +#......... +......#...") + +(def input + (->> + ;example + (get-input 6) + string/split-lines + (mapv vec))) + +(def width (count (first input))) +(def height (count input)) + +(def initial-position + (first + (for [l (range height) + c (range width) + :when (= \^ (get-in input [l c]))] + [l c]))) + +(defn move [[l c] direction] + (case direction + :up [(dec l) c] + :right [l (inc c)] + :down [(inc l) c] + :left [l (dec c)])) + +(defn turn-right [direction] + (case direction + :up :right + :right :down + :down :left + :left :up)) + +(defn left? [[l c]] + (or (neg? l) (neg? c) (= width c) (= height l))) + +(defn obstructed? [pos map] + (= \# (get-in map pos))) + +(def area-map + (loop [lab (assoc-in input initial-position \X) + position initial-position + direction :up] + (if (left? position) + lab + (if (obstructed? (move position direction) input) + (recur (assoc-in lab position \X) position (turn-right direction)) + (recur (assoc-in lab position \X) (move position direction) direction))))) + +(time + (println "Guard will visit" + (->> + (apply concat area-map) + (filter (partial = \X)) + count) + "positions")) + +(def possible-obstructions + (for [l (range height) + c (range width) + :when (= \. (get-in input [l c]))] + [l c])) + +(defn has-loop? [xs] + (if (< (count xs) 3) false + (let [x (peek xs) + xs (reverse (pop xs)) + [a b] (split-with (partial not= x) xs)] + (if (empty? b) + false + (loop [a a b (rest b)] + (if (empty? a) + true + (if (not= (first a) (first b)) + false + (recur (rest a) (rest b))))))))) + +(defn stuck? [obstruction] + (let [map' (assoc-in input obstruction \#)] + (loop [position initial-position + direction :up + encountered-obstructions []] + (if (left? position) + false + (if (has-loop? encountered-obstructions) + true + (let [new-pos (move position direction)] + (if (obstructed? new-pos map') + (recur position + (turn-right direction) + (conj encountered-obstructions new-pos)) + (recur new-pos direction encountered-obstructions)))))))) + +(time + (println "Possible obstructions to make guard loop:" + (->> + (map stuck? possible-obstructions) + (filter true?) + count)))