Skip to content

Instantly share code, notes, and snippets.

@brehaut
Created March 20, 2014 20:40
Show Gist options
  • Save brehaut/9673354 to your computer and use it in GitHub Desktop.
Save brehaut/9673354 to your computer and use it in GitHub Desktop.
monster allocation via logic
;; Sorry about the horrible code. This is my first shot at a core.logic program.
;;
;; Basically this is a change calculator that returns all possible combinations of change for a given
;; total. Instead of being about money its about monsters for tabletop RPGs.
(require '[clojure.core.logic :as l]
'[clojure.core.logic.fd :as fd])
(defn allocate-monsterso [points monsters out]
"This relation finds all the allocations of monsters for the given points.
"
(l/conde
;; if we have no points left, then we get an empty list
[(fd/<= points 0)
(l/== out [])]
[(l/fresh [head
cost
tail
remaining-points
rest]
;; find the current monster and the tail list.
(l/conso [head cost] tail monsters)
(l/conde
;; branch one: add one of the current monsters to the list
;; subtracting its cost from the points
[(fd/- points cost remaining-points)
(fd/<= 0 remaining-points)
(allocate-monsterso remaining-points monsters rest)
(l/conso head rest out)]
;; branch two: move on to the next monster in the list
[(allocate-monsterso points tail out)]
;; branch three: skip the next monster in the list
[(l/fresh [_ ttail]
(l/conso _ ttail tail)
(allocate-monsterso points ttail out))]))]))
(l/run 10 [q]
(allocate-monsterso 3
[[:a 1] [:b 2] [:c 1]]
q))
; => ((:a :a :a) (:a :b) (:c :c :c) (:a :a :a) (:b :c) (:a :c :c) (:c :c :c) (:a :a :a) (:a :a :c) (:b :c))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment