Created
March 20, 2014 20:40
-
-
Save brehaut/9673354 to your computer and use it in GitHub Desktop.
monster allocation via logic
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 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