use java deps for z3

This commit is contained in:
Adam Jeniski 2025-12-22 17:55:11 -05:00
parent d55ca4c019
commit 8fa11862e1
2 changed files with 51 additions and 56 deletions

View File

@ -10,5 +10,6 @@
[babashka/fs "0.5.23"] [babashka/fs "0.5.23"]
[org.babashka/http-client "0.4.22"] [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"]] [clj-python/libpython-clj "2.025"]
[tools.aqua/z3-turnkey "4.14.1"]]
:source-paths ["src" "../shared/clj/src"]) :source-paths ["src" "../shared/clj/src"])

View File

@ -1,10 +1,7 @@
(ns day10 (ns day10
(:require input-manager (:require [clojure.math.combinatorics :as combo]
[core :refer [dbg]] [input-manager])
[clojure.math.combinatorics :as combo] (:import (com.microsoft.z3 BoolExpr Context Expr IntNum Optimize Optimize$Handle)))
[clojure.string :as str]
[libpython-clj2.require :refer [require-python]]
[libpython-clj2.python :as py]))
(defn parse-line [line] (defn parse-line [line]
{:indicators (->> line {:indicators (->> line
@ -39,51 +36,48 @@
;; part 1 ;; part 1
(apply + (map minimum-button-mashing input)) (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 add-formulas! [opt [f & fs]]
(when f
(! "add" opt f)
(recur opt fs)))
;; part 2 ;; part 2
(->> input (->> input
(map (fn [{:keys [joltages buttons]}] (map (fn [{:keys [joltages buttons]}]
(let [opt (Optimize) (let [ctx (Context.)
^Optimize opt (.mkOptimize ctx)
bs (->> buttons bs (->> buttons
count count
range range
(map #(Int (str "b" %)))) (map #(.mkIntConst ctx (str "b" %))))
js (->> joltages js (->> joltages
count count
range range
(map #(Int (str "j" %))))] (map #(.mkIntConst ctx (str "j" %))))]
(add-formulas! opt (for [idx (range (count joltages))] (.Add
opt
(into-array
BoolExpr
(for [idx (range (count joltages))]
(let [jn (nth js idx) (let [jn (nth js idx)
summation-args (->> buttons summation-args (->> buttons
(map set) (map set)
(map-indexed vector) (map-indexed vector)
(filter #(contains? (second %) idx)) (filter #(contains? (second %) idx))
(map first) (map first)
(map #(nth bs %)))] (map #(nth bs %))
(py= jn (apply Sum summation-args))))) (into-array Expr)
(add-formulas! opt (for [[idx joltage] (map-indexed vector joltages)] (.mkAdd ctx))]
(.mkEq ctx jn summation-args)))))
(.Add
opt
(into-array
Expr
(for [[idx joltage] (map-indexed vector joltages)]
(let [jn (nth js idx)] (let [jn (nth js idx)]
(py= jn joltage)))) (.mkEq ctx jn (.mkInt ctx (long joltage)))))))
(add-formulas! opt (for [b bs] (py>= b 0))) (.Add
(! "minimize" opt (apply Sum bs)) opt
(! "check" opt) (into-array
(let [model (! "model" opt)] Expr
(->> (for [b bs] (! "as_long" (pysubscript model b))) (for [b bs]
(apply +)))))) (.mkGe ctx b (.mkInt ctx (long 0))))))
(let [^Optimize$Handle mx (.MkMinimize opt (.mkAdd ctx (into-array Expr bs)))]
(.Check opt (into-array Expr []))
(.getInt ^IntNum (.getLower mx))))))
(apply +)) (apply +))