You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.5 KiB
Clojure
91 lines
2.5 KiB
Clojure
3 years ago
|
(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])
|
||
|
|
||
3 years ago
|
(defn do-slot [[field energy] idx]
|
||
3 years ago
|
(let [slot (get field idx)]
|
||
|
(cond
|
||
|
; Moving value out of a room
|
||
3 years ago
|
(and (seq? slot)
|
||
|
(not (empty? slot))
|
||
|
(not (every? #(= % ({2 :a 4 :b 6 :c 8 :d} idx)) slot)))
|
||
3 years ago
|
(let [open-slots
|
||
|
(filterv
|
||
|
#(contains? #{0 1 3 5 7 9 10} %)
|
||
|
(concat
|
||
3 years ago
|
(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)))]
|
||
3 years ago
|
(when-not (empty? open-slots)
|
||
|
(map
|
||
|
(fn [os]
|
||
|
[(-> field
|
||
|
(assoc os (first slot))
|
||
|
(update idx rest))
|
||
3 years ago
|
(+ energy (* ({:a 1 :b 10 :c 100 :d 1000} (first slot))
|
||
|
(+ (inc (- 4 (count slot))) (Math/abs (- os idx)))))])
|
||
3 years ago
|
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))
|
||
3 years ago
|
(+ energy (* ({:a 1 :b 10 :c 100 :d 1000} slot)
|
||
|
(+ (Math/abs (- idx our-room)) (- 4 (count room)))))])))))))
|
||
3 years ago
|
|
||
|
(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]
|
||
3 years ago
|
(into #{}
|
||
3 years ago
|
(r/fold
|
||
|
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])))))
|
||
|
|
||
|
(defn play-games [turns tc]
|
||
|
(println "Games:" (count turns) "Turn:" tc)
|
||
3 years ago
|
(let [new-turns (do-turns turns)
|
||
|
winners (filter winner? new-turns)]
|
||
|
(if (seq winners)
|
||
|
(map second winners)
|
||
|
(recur new-turns (inc tc)))))
|
||
3 years ago
|
|
||
3 years ago
|
(->> (play-games #{[init-field 0]} 0)
|
||
|
sort
|
||
|
first
|
||
|
((partial println "Lowest energy:")))
|
||
3 years ago
|
|