Skip to content

Instantly share code, notes, and snippets.

@llasram
Created November 27, 2012 10:58
Show Gist options
  • Save llasram/4153629 to your computer and use it in GitHub Desktop.
Save llasram/4153629 to your computer and use it in GitHub Desktop.
Secret Santra in core.logic
(ns secret-santa.logic
(:refer-clojure :exclude [==])
(:require [clojure.core.logic :refer :all]))
(defrel cannot-give ^:index p1 ^:index p2)
(fact cannot-give 'adam 'ashley)
(fact cannot-give 'bill 'brandon)
(fact cannot-give 'carl 'cynthia)
(def people '[adam ashley bill brandon carl cynthia])
(defn cangiveo
[p1 p2]
(conda
[(cannot-give p1 p2) fail]
[(cannot-give p2 p1) fail]
[succeed succeed]))
(defn giveringo
[q]
(fresh [p1 l1]
(conso p1 l1 q)
(conde
[(emptyo l1)]
[(fresh [p2 l2]
(conso p2 l2 l1)
(cangiveo p1 p2)
(giveringo l1))])))
(defn secret-santa
[people]
(let [options (vec (repeatedly (count people) lvar))
ring (conj options (first options))]
(run 1 [q]
(== q options)
(distincto options)
(everyg #(membero % people) options)
(giveringo ring))))
(secret-santa people)
;; => ([adam bill ashley carl brandon cynthia])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment