mirror of
https://github.com/Ajetski/advent-of-code.git
synced 2025-09-30 05:23:17 -09:00
day 21 part 1
This commit is contained in:
parent
a18e813f94
commit
48f409b6a5
120
2024/src/day21.clj
Normal file
120
2024/src/day21.clj
Normal file
@ -0,0 +1,120 @@
|
||||
(ns day21
|
||||
(:require
|
||||
[clojure.math :as math]
|
||||
[clojure.string :as str]
|
||||
[core :as c :refer :all]
|
||||
[input-manager :as i]
|
||||
[clojure.math.combinatorics :as combo]))
|
||||
|
||||
(def input (i/get-input 2024 21))
|
||||
|
||||
(def pad-1-data [[nil \0 \A]
|
||||
[\1 \2 \3]
|
||||
[\4 \5 \6]
|
||||
[\7 \8 \9]])
|
||||
(def pad-locs (-> pad-1-data map-to-coords (dissoc nil)))
|
||||
(def pad-locs-by-coords (-> pad-1-data map-by-coords (dissoc [0 0])))
|
||||
|
||||
(def pad-2-data [[\< \v \>]
|
||||
[nil \^ \A]])
|
||||
(def pad-locs-2 (-> pad-2-data map-to-coords (dissoc nil)))
|
||||
(def pad-locs-2-by-coords (-> pad-2-data map-by-coords (dissoc [1 0])))
|
||||
|
||||
(def start (pad-locs \A))
|
||||
(def start-2 (pad-locs-2 \A))
|
||||
|
||||
(defn manhattan-distance [[row1 col1] [row2 col2]]
|
||||
(+ (abs (- row1 row2))
|
||||
(abs (- col1 col2))))
|
||||
|
||||
(defn char->step-fn [c]
|
||||
(fn [[row col]]
|
||||
({\> [row (inc col)]
|
||||
\< [row (dec col)]
|
||||
\^ [(inc row) col]
|
||||
\v [(dec row) col]} c)))
|
||||
|
||||
(defn progressive-steps [[row col :as pos] [target-row target-col] grid]
|
||||
(->> [(when (> target-row row)
|
||||
\^)
|
||||
(when (< target-row row)
|
||||
\v)
|
||||
(when (> target-col col)
|
||||
\>)
|
||||
(when (< target-col col)
|
||||
\<)]
|
||||
(filter identity)
|
||||
(filter #(grid ((char->step-fn %) pos)))))
|
||||
|
||||
(defn shortest-walks
|
||||
"returns list of all minimal length list keypresses (arrow chars)"
|
||||
[start-pos target-pos grid]
|
||||
(loop [n 0
|
||||
walks #{[start-pos []]}]
|
||||
(or (and (or (->> walks
|
||||
(map first)
|
||||
(filter #(= % target-pos))
|
||||
not-empty)
|
||||
(empty? walks))
|
||||
(->> walks
|
||||
(map second)
|
||||
(map #(conj % \A))))
|
||||
(->> walks
|
||||
(mapcat (fn [[loc keystrokes]]
|
||||
(let [steps (progressive-steps loc target-pos grid)]
|
||||
(->> steps
|
||||
(map #(vector ((char->step-fn %) loc)
|
||||
(conj keystrokes %)))))))
|
||||
set
|
||||
(recur (inc n))))))
|
||||
|
||||
(defn generate-robot-subwalks [start-pos walk]
|
||||
(->> walk
|
||||
(map pad-locs-2)
|
||||
((juxt identity rest))
|
||||
(apply map vector)
|
||||
(#(conj % [start-pos (pad-locs-2 (first walk))]))
|
||||
(map #(shortest-walks (first %) (second %) pad-locs-2-by-coords))))
|
||||
|
||||
(defn generate-all-subwalk-options [depth code]
|
||||
(loop [n 1
|
||||
acc (->> code
|
||||
(reduce (fn [{:keys [pos w]}
|
||||
el]
|
||||
(let [pos' (pad-locs el)
|
||||
walks (shortest-walks pos pos' pad-locs-by-coords)]
|
||||
{:pos pos'
|
||||
:w (conj w walks)}))
|
||||
{:pos start
|
||||
:w []})
|
||||
:w)]
|
||||
(if (= n depth)
|
||||
acc
|
||||
(recur (inc n)
|
||||
(n-map (* n 2) #(generate-robot-subwalks (pad-locs-2 \A) %) acc)))))
|
||||
|
||||
(defn get-count-from-subwalks [depth all-walks]
|
||||
(loop [n (dec depth)
|
||||
acc (n-map (* depth 2) count all-walks)]
|
||||
(if (neg? n)
|
||||
acc
|
||||
(recur (dec n)
|
||||
(->> acc
|
||||
(n-map (inc (* n 2))
|
||||
(partial apply min))
|
||||
(n-map (* n 2)
|
||||
(partial reduce +)))))))
|
||||
|
||||
(defn get-ans-for-code [depth code]
|
||||
(let [c (->> (generate-all-subwalk-options depth code)
|
||||
(get-count-from-subwalks depth))
|
||||
n (parse-long (->> code
|
||||
drop-last
|
||||
str/join))]
|
||||
(* c n)))
|
||||
|
||||
;; part 1
|
||||
(->> input
|
||||
(map (partial get-ans-for-code 3))
|
||||
(reduce +)
|
||||
println)
|
Loading…
x
Reference in New Issue
Block a user