Skip to content

Instantly share code, notes, and snippets.

@joinr
Created January 12, 2023 18:30
Show Gist options
  • Save joinr/b82add2692ca1fb9993cffb8441eac27 to your computer and use it in GitHub Desktop.
Save joinr/b82add2692ca1fb9993cffb8441eac27 to your computer and use it in GitHub Desktop.
minor mods to optimize some aoc submissions
(ns day19
(:require aoc))
(set! *warn-on-reflection* true)
(set! *unchecked-math* :warn-on-boxed)
(defrecord Blueprint [prices max-resources])
(defn line->blueprint [line]
(let [[_ ore-ore clay-ore obs-ore obs-clay geode-ore geode-obs] line
prices {:ore {:ore ore-ore}
:clay {:ore clay-ore}
:obs {:ore obs-ore , :clay obs-clay}
:geode {:ore geode-ore , :obs geode-obs}}
max-resources {:ore (max ore-ore clay-ore obs-ore geode-ore)
:clay obs-clay , :obs geode-obs , :geode 9999}]
(->Blueprint prices max-resources)))
(defn best-case [resource bot time]
(+ resource
(* bot time)
(/ (* time (inc time)) 2)))
(defn build-bot [resources price]
(reduce-kv (fn [rscs k p] (assoc rscs k (- ^long (resources k) ^long p)))
resources
price))
(defn all-positive? [resources]
(reduce-kv (fn [acc _ v]
(if (neg? (long v))
(reduced false)
acc))
true resources))
(defn geodes [t bp]
(let [types [:ore :clay :obs :geode]
times {:ore 0 , :clay 4 , :obs 2 , :geode 0}
state {:t t
:bots {:ore 1 , :clay 0 , :obs 0 , :geode 0}
:resources {:ore 0 , :clay 0 , :obs 0 , :geode 0}
:skipped #{}}
{:keys [prices max-resources]} bp
collect (fn [resources bots t]
(->> resources
(reduce-kv (fn [acc res v]
(assoc! acc res
(min (* (max-resources res) t)
(+ v (bots res)))))
(transient resources))
persistent!))]
(loop [stack [state]
seen (transient #{})
score 0]
(if-let [m (peek stack)]
(let [t (m :t)
bots (m :bots)
resources (m :resources)
skipped (m :skipped)
state-hash [t bots resources]
stack' (pop stack)]
(if (or (zero? t)
(seen state-hash)
(< (best-case (resources :geode) (bots :geode) t) score))
(recur stack' (conj! seen state-hash) (max score (resources :geode)))
(let [[stack'' skipped]
(reduce (fn [[stack can-build] bot]
(let [rscs (build-bot resources (prices bot))]
(if (and (not (skipped bot))
(> t (times bot))
#_(not-any? neg? (vals rscs))
(all-positive? rscs)
(< (bots bot) (max-resources bot))
(< (resources bot) (* 1.5 (max-resources bot))))
[(conj stack {:t (dec t) , :resources (collect rscs bots t)
:bots (update bots bot inc) , :skipped #{}})
(conj can-build bot)]
[stack can-build])))
[stack' #{}]
types)
,
stack
(if (or (< (resources :ore) (max-resources :ore))
(and (pos? (bots :clay))
(< (resources :clay) (max-resources :clay)))
(and (pos? (bots :obs))
(< (resources :obs) (max-resources :obs))))
(conj stack'' {:t (dec t) , :resources (collect resources bots t)
:bots bots , :skipped skipped})
stack'')]
(recur stack (conj! seen state-hash) score))))
score))))
(defn part-1 [blueprints]
(->> blueprints
(pmap (partial geodes 24))
(mapv * (iterate inc 1))
(reduce +)))
(defn part-2 [blueprints]
(->> blueprints
(take 3)
(pmap (partial geodes 32))
(reduce *)))
(defn parse-input [input]
(->> input
aoc/read-input
(mapv aoc/integers)
(mapv line->blueprint)))
(defn solve
([] (solve 19))
([input]
(let [blueprints (parse-input input)
p1 (future (part-1 blueprints))
p2 (future (part-2 blueprints))]
[@p1 @p2])))
(solve)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment