(ns pokemon.selfweak (:require pokemon.types)) (defn alter-val "Change the value associated with k in the map by applying (f old-val & args). Uses nil as old-val if key is not found in map." [m k f & args] (assoc m k (apply f (get m k) args))) (def type-chart* pokemon.types/pokemon-gen-two) (def types (map (comp keyword first) type-chart*)) (def type-chart (into {} (map (fn [[atk & susceptibilities]] [(keyword atk) (zipmap types susceptibilities)]) type-chart* ))) (def half-effective (into {} (for [atk types] [atk (filter #(= 0.5 (get-in type-chart [atk %])) types)]))) (defn constrained-search [] (loop [agenda [{:open (sort-by (fn [t] (count (half-effective t))) types) :assignment nil}]] (when-let [state (first agenda)] (if-let [atk (first (:open state))] (recur (concat (for [possible-type-label (remove (set(vals (:assignment state))) (half-effective atk)) ] (-> state (alter-val :open rest) (alter-val :assignment #(assoc % atk possible-type-label)) )) (for [possible-type-label (when (= 1 (count (remove (-> state :assignment vals set) types) )) (remove (-> state :assignment vals set) types) )] (-> state (alter-val :open (constantly nil)) (alter-val :assignment #(assoc % atk possible-type-label)) )) (rest agenda))) (:assignment state))))) (defn constrained-search-all [] (loop [agenda [{:open (sort-by (fn [t] (count (half-effective t))) types) :assignment nil}] solutions [] ] (if-let [state (first agenda)] (if-let [atk (first (:open state))] (recur (concat (for [possible-type-label (remove (set(vals (:assignment state))) (half-effective atk)) ] (-> state (alter-val :open rest) (alter-val :assignment #(assoc % atk possible-type-label)) )) (for [possible-type-label (when (= 1 (count (remove (-> state :assignment vals set) types) )) (remove (-> state :assignment vals set) types) )] (-> state (alter-val :open (constantly nil)) (alter-val :assignment #(assoc % atk possible-type-label)) )) (rest agenda)) solutions ) (recur (rest agenda) (conj solutions (:assignment state))) ) solutions ))) ;; (map (comp count (partial filter (fn [[x y]] (= x y)))) (constrained-search-all)) ;; (if-let [atk (first (:open agenda))] ;; (:open agenda) ;; (:assignment agenda)