diff options
-rw-r--r-- | day21 | 2 | ||||
-rw-r--r-- | day21.bqn | 19 | ||||
-rw-r--r-- | day21.clj | 56 |
3 files changed, 77 insertions, 0 deletions
diff --git a/day21 b/day21 new file mode 100644 index 0000000..fc17973 --- /dev/null +++ b/day21 @@ -0,0 +1,2 @@ +Player 1 starting position: 3 +Player 2 starting position: 10 diff --git a/day21.bqn b/day21.bqn new file mode 100644 index 0000000..c19e7f3 --- /dev/null +++ b/day21.bqn @@ -0,0 +1,19 @@ +#start ← 4‿8 +start ← 3‿10 + +scores ← +` {𝕩+10×𝕩=0} 10| start +` (+´)⎉1 200‿2‿3 ⥊ 1+↕100 +end ← ⊑ / (»⊸<∨`) «⥊scores≥1000 +loser ← end ⊑ ⥊scores +roll ← 3×2+ end +•Show loser × roll + +Move ← { ⟨roll,player,⟨pos,score⟩⟩: + pos2 ← {1+10|roll+𝕩-1}⌾(player⊸⊑) pos + ⟨pos2, score + pos2 × player=↕≠pos2⟩ +} +f ← 3↓<˘⍉(↕∘≠ ≍ ⊣) ≠¨⊔+˝⍉>⥊1+↕3⥊3 +Play ← { + ⟨player,⟨pos,score⟩⟩: ∨´score ≥ 21 ? score ≥ 21 ; + ⟨player,st⟩: +´ { ⟨val,frq⟩: frq × Play (¬player)‿(Move val‿player‿st) }¨ f +} +•Show ⌈´ Play 0‿⟨start,⟨0,0⟩⟩ diff --git a/day21.clj b/day21.clj new file mode 100644 index 0000000..d286dfe --- /dev/null +++ b/day21.clj @@ -0,0 +1,56 @@ +(ns org.vuxu.aoc2021.day21 + (:require [clojure.string :as str])) + +(def data + (->> (slurp "day21") + str/split-lines + (map (partial re-find #"\d+$")) + (mapv parse-long))) + +(def freqs + (frequencies + (for [a [1 2 3] + b [1 2 3] + c [1 2 3]] + (+ a b c)))) + +(defn move [roll player state] + (let [state + (update-in state [:pos player] #(inc (mod (dec (+ % roll)) 10)))] + (update-in state [:score player] + (get-in state [:pos player])))) + +(def state {:pos data + :score [0 0]}) + +(def part1 + (let [game (take-while (fn [state] + (every? #(< % 1000) (:score state))) + (reductions + (fn [state [player val]] + (move val player state)) + state + (map vector + (cycle [0 1]) + (map (partial apply +) + (partition 3 (cycle (range 1 101)))))))] + (* (* 3 (count game)) + (apply min (:score (last game)))))) +;; => 713328 + +(def play + (memoize + (fn [player state] + (cond + (>= (get-in state [:score 0]) 21) [1 0] + (>= (get-in state [:score 1]) 21) [0 1] + :else + (reduce (fn [result [val freq]] + (mapv + result + (mapv (partial * freq) + (play (- 1 player) (move val player state))))) + [0 0] + freqs))))) + +(def part2 + (apply max (play 0 state))) +;; => 92399285032143 |