do day 10
This commit is contained in:
parent
a2492b2b2a
commit
d379c21296
@ -9,5 +9,6 @@
|
||||
[org.clojure/math.combinatorics "0.3.0"]
|
||||
[babashka/fs "0.5.23"]
|
||||
[org.babashka/http-client "0.4.22"]
|
||||
[org.clojure/core.match "1.1.0"]]
|
||||
[org.clojure/core.match "1.1.0"]
|
||||
[clj-python/libpython-clj "2.026"]]
|
||||
:source-paths ["src" "../shared/clj/src"])
|
||||
|
||||
94
2025/src/day10.clj
Normal file
94
2025/src/day10.clj
Normal file
@ -0,0 +1,94 @@
|
||||
(ns day10
|
||||
(:require input-manager
|
||||
[core :refer [dbg]]
|
||||
[clojure.math.combinatorics :as combo]
|
||||
[clojure.string :as str]
|
||||
[libpython-clj2.require :refer [require-python]]
|
||||
[libpython-clj2.python :as py]))
|
||||
|
||||
(defn parse-line [line]
|
||||
{:indicators (->> line
|
||||
(drop 1)
|
||||
(take-while (complement #{\]}))
|
||||
(mapv (partial = \#)))
|
||||
:buttons (->> line
|
||||
(re-seq #"\([\d,]+\)")
|
||||
(map #(map parse-long (re-seq #"\d+" %))))
|
||||
:joltages (->> line
|
||||
(drop-while #(not= % \{))
|
||||
(drop 1)
|
||||
(take-while #(not= % \}))
|
||||
(apply str)
|
||||
(re-seq #"\d+")
|
||||
(mapv parse-long))})
|
||||
|
||||
(def input (map parse-line (input-manager/get-input 2025 10)))
|
||||
|
||||
(defn apply-ops [v ops]
|
||||
(reduce (fn [acc op]
|
||||
(reduce #(update %1 %2 not) acc op))
|
||||
v
|
||||
ops))
|
||||
|
||||
(defn minimum-button-mashing [{ops :buttons v :indicators}]
|
||||
(loop [i 0
|
||||
cnt 1]
|
||||
(if (>= i (combo/count-combinations ops cnt))
|
||||
(recur 0 (inc cnt))
|
||||
(let [v' (apply-ops v (combo/nth-combination ops cnt i))]
|
||||
(if (every? (complement identity) v')
|
||||
cnt
|
||||
(recur (inc i) cnt))))))
|
||||
|
||||
;; part 1
|
||||
(apply + (map minimum-button-mashing input))
|
||||
|
||||
;; clj-python setup
|
||||
(defmacro ! [self method & args] `(py/call-attr ~method ~self ~@args))
|
||||
(defmacro py= [self & args] `(! "__eq__" ~self ~@args))
|
||||
(defmacro py>= [self & args] `(! "__ge__" ~self ~@args))
|
||||
(defmacro pysubscript [self & args] `(! "__getitem__" ~self ~@args))
|
||||
|
||||
;; z3 stuff
|
||||
(require-python :from (str (System/getenv "HOME") "/.local/lib/python3.13/site-packages/") '[z3 :as z3])
|
||||
(def Int z3/Int)
|
||||
(def Optimize z3/Optimize)
|
||||
(def Sum z3/Sum)
|
||||
(defn apply-formulas [opt [f & fs]]
|
||||
(when f
|
||||
(! "add" opt f)
|
||||
(recur opt fs)))
|
||||
|
||||
;; part 2
|
||||
(->> input
|
||||
(map (fn [{:keys [joltages buttons]}]
|
||||
(let [opt (Optimize)
|
||||
bs (->> buttons
|
||||
count
|
||||
range
|
||||
(map #(Int (str "b" %))))
|
||||
js (->> joltages
|
||||
count
|
||||
range
|
||||
(map #(Int (str "j" %))))]
|
||||
(apply-formulas opt (for [idx (range (count joltages))]
|
||||
(let [jn (nth js idx)
|
||||
summation-args (->> buttons
|
||||
(map set)
|
||||
(map-indexed vector)
|
||||
(filter #(contains? (second %) idx))
|
||||
(map first)
|
||||
(map #(nth bs %)))]
|
||||
(py= jn (apply Sum summation-args)))))
|
||||
(apply-formulas opt (for [[idx joltage] (map-indexed vector joltages)]
|
||||
(let [jn (nth js idx)]
|
||||
(py= jn joltage))))
|
||||
(apply-formulas opt (for [b bs] (py>= b 0)))
|
||||
(! "minimize" opt (apply Sum bs))
|
||||
(! "check" opt)
|
||||
(let [model (! "model" opt)]
|
||||
(apply +
|
||||
(for [b bs]
|
||||
(! "as_long" (pysubscript model b))))))))
|
||||
(apply +))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user