From d13c4e6b075afefe98b6629ca9b1230fc2eaa81e Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Thu, 23 Dec 2021 12:33:45 -0500 Subject: [PATCH] add day 23 --- day23/core.clj | 108 +++++++++++++++++++++++++++++++++++++++ day23/part1-done-by-hand | 0 2 files changed, 108 insertions(+) create mode 100644 day23/core.clj create mode 100644 day23/part1-done-by-hand diff --git a/day23/core.clj b/day23/core.clj new file mode 100644 index 0000000..3459065 --- /dev/null +++ b/day23/core.clj @@ -0,0 +1,108 @@ +; +; Place in new leiningen 'app' template project +; +; Run with `java -Xmx8G -jar ...` +; + +(ns hah.core + (:gen-class)) + +(require '[clojure.core.reducers :as r]) + +(def init-field + [nil + nil + (seq [:b :d :d :d]) + nil + (seq [:b :c :b :a]) + nil + (seq [:c :b :a :a]) + nil + (seq [:d :a :c :c]) + nil + nil]) + +(defn do-slot [[field q s] idx] + (let [slot (get field idx)] + (cond + ; Moving value out of a room + (and (seq? slot) (not (empty? slot)) (not (every? #(= % ({2 :a 4 :b 6 :c 8 :d} idx)) slot))) + (let [open-slots + (filterv + #(contains? #{0 1 3 5 7 9 10} %) + (concat + (for [i (reverse (range 0 idx)) :while (or (nil? (get field i)) (seq? (get field i)))] i) + (for [i (range idx (count field)) :while (or (nil? (get field i)) (seq? (get field i)))] i)))] + (when-not (empty? open-slots) + (map + (fn [os] + [(-> field + (assoc os (first slot)) + (update idx rest)) + (conj q [idx os]) + (+ s (* ({:a 1 :b 10 :c 100 :d 1000} (first slot)) (+ (inc (- 4 (count slot))) (Math/abs (- os idx)))))]) + open-slots))) + ; Moving value into a room + (and (not (seq? slot)) (some? slot)) + (let [our-room ({:a 2 :b 4 :c 6 :d 8} slot)] + (if (every? #(or (nil? (get field %)) (seq? (get field %))) + (range (inc (min our-room idx)) (max our-room idx))) + (let [room (get field our-room)] + (when (or (empty? room) (every? #(= slot %) room)) + [(-> field + (assoc idx nil) + (update our-room conj slot)) + (conj q [idx our-room]) + (+ s (* ({:a 1 :b 10 :c 100 :d 1000} slot) (+ (Math/abs (- idx our-room)) (- 4 (count room)))))]))))))) + +(defn winner? [[field q s]] + (= field + [nil + nil + (seq [:a :a :a :a]) + nil + (seq [:b :b :b :b]) + nil + (seq [:c :c :c :c]) + nil + (seq [:d :d :d :d]) + nil + nil])) + +(defn do-turns [fields] + (into [] + (r/fold + 1024 + r/cat + #(if-let [t (apply do-slot %2)] + (if (seq? t) + (reduce r/append! %1 t) + (r/append! %1 t)) + %1) + (into [] (for [f fields i (range 0 11)] [f i]))))) + +(def wins (atom #{})) + +(defn play-games [turns tc] + (println "Games:" (count turns) "Turn:" tc) + (if (< 500000 (count turns)) + (do + (println "Splitting...") + (doseq [p (partition 100000 turns) + :let [r (play-games (into [] p) tc)]] nil)) + (do + (let [new-turns (do-turns turns) + winners (filter winner? new-turns)] + (if (pos? (count winners)) + (do + (println "Winner! Turns:" tc) + (swap! wins #(reduce conj % (map last winners)))) + (when (pos? (count new-turns)) + (recur new-turns (inc tc)))))))) + +(defn -main + "I don't do a whole lot ... yet." + [& args] + (play-games [[init-field [] 0]] 0) + (println (first (sort @wins)))) + diff --git a/day23/part1-done-by-hand b/day23/part1-done-by-hand new file mode 100644 index 0000000..e69de29