-
-
Save zerokarmaleft/3219448 to your computer and use it in GitHub Desktop.
AA = Rickard Stark (M) AB = Eddard Stark (M) AC = Catelyn Tully (F) | |
AD = Brandon Stark (M) AE = Benjen Stark (M) AF = Jon Snow (M) | |
AG = Robb Stark (M) AH = Sansa Stark (F) AI = Arya Stark (F) | |
AJ = Bran Stark (M) AK = Rickon Stark (M) AL = Hoster Tully (M) | |
AM = Minisa Whent (F) AN = Edmure Tully (M) AO = Lysa Tully (F) | |
AP = Jon Arryn (M) AQ = Robert Arryn (M) AR = Tytos Lannister (M) | |
AS = Tywin Lannister (M) AT = Joanna Lannister (F) AU = Kevan Lannister (M) | |
AV = Cersei Lannister (F) AW = Jamie Lannister (M) AX = Tyrion Lannister (M) | |
AY = Robert Baratheon (M) AZ = Joffrey Baratheon (M) BA = Myrcella Baratheon (F) | |
BB = Tommen Baratheon (M) BC = Lancel Lannister (M) BD = Steffon Baratheon (M) | |
BE = Stannis Baratheon (M) BF = Selyse Florent (F) BG = Shireen Baratheon (F) | |
BH = Renly Baratheon (M) BI = Jaehaerys Targaryen (M) BJ = Aerys Targaryen (M) | |
BK = Rhaella Targaryen (F) BL = Rhaegar Targaryen (M) BM = Elia Martell (F) | |
BN = Rhaenys Targaryen (F) BO = Aegon Targaryen (M) BP = Viserys Targaryen (M) | |
BQ = Daenerys Targaryen (F) BR = Quellon Greyjoy (M) BS = Balon Greyjoy (M) | |
BT = Euron Greyjoy (M) BU = Victarion Greyjoy (M) BV = Urrigon Greyjoy (M) | |
BW = Aeron Greyjoy (M) BX = Rodrik Greyjoy (M) BY = Maron Greyjoy (M) | |
BZ = Asha Greyjoy (F) CA = Theon Greyjoy (M) CB = Alannys Harlaw (F) | |
--------------------------------------------------------------------------------------- | |
AA->AB, AA->AD, AA->AE, AB->AF, AB->AG, AB->AH, AB->AI, AB->AJ, AB->AK, AC->AG, | |
AC->AH, AC->AI, AC->AJ, AC->AK, AL->AC, AL->AN, AL->AO, AM->AC, AM->AN, AM->AO, | |
AO->AQ, AP->AQ, AR->AS, AR->AU, AS->AV, AS->AW, AS->AX, AT->AV, AT->AW, AT->AX, | |
AU->BC, AV->AZ, AV->BA, AV->BB, AY->AZ, AY->BA, AY->BB, BD->AY, BD->BE, BD->BH, | |
BE->BG, BF->BG, BI->BJ, BI->BK, BJ->BL, BJ->BP, BJ->BQ, BK->BL, BK->BP, BK->BQ, | |
BL->BN, BL->BO, BM->BN, BM->BO, BR->BS, BR->BT, BR->BU, BR->BV, BR->BW, BS->BX, | |
BS->BY, BS->BZ, BS->CA, CB->BX, CB->BY, CB->BZ, CB->CA |
(ns familytree.core | |
(:refer-clojure :exclude [==]) | |
(:use clojure.core.logic)) | |
(defrel parent p c) | |
(defn child [c p] (parent p c)) | |
(defrel male p) | |
(defrel female p) | |
(defn ancestor [x z] | |
(conde | |
[(parent x z)] | |
[(fresh [y] | |
(parent x y) | |
(ancestor y z))])) | |
(defn descendant [x z] | |
(conde | |
[(child z x)] | |
[(fresh [y] | |
(child y x) | |
(descendant y z))])) | |
(defn father [f c] | |
(all | |
(parent f c) | |
(male f))) | |
(defn mother [m c] | |
(all | |
(parent m c) | |
(female m))) | |
(defn son [s p] | |
(all | |
(child s p) | |
(male s))) | |
(defn daughter [d p] | |
(all | |
(child d p) | |
(female d))) | |
(defn grandfather [gp c] | |
(fresh [p] | |
(father gp p) | |
(parent p c))) | |
(defn grandmother [gp c] | |
(fresh [p] | |
(mother gp p) | |
(parent p c))) | |
(defn grandson [gs gp] | |
(fresh [p] | |
(child p gp) | |
(son gs p))) | |
(defn granddaughter [gd gp] | |
(fresh [p] | |
(child p gp) | |
(daughter gd gp))) | |
(defn sibling [x y] | |
(fresh [p] | |
(parent p x) | |
(parent p y) | |
(!= x y))) | |
(defn brother [b x] | |
(all | |
(sibling b x) | |
(male b))) | |
(defn sister [s x] | |
(all | |
(sibling s x) | |
(female s))) | |
(defn uncle [u n] | |
(fresh [p] | |
(brother u p) | |
(parent p n))) | |
(defn aunt [a n] | |
(fresh [p] | |
(sister a p) | |
(parent p n))) | |
(defn nephew [n s] | |
(fresh [p] | |
(sibling s p) | |
(child n p) | |
(male n))) | |
(defn niece [n s] | |
(fresh [p] | |
(sibling s p) | |
(child n p) | |
(female n))) | |
(defn cousin [c x] | |
(fresh [cp xp] | |
(parent cp c) | |
(parent xp x) | |
(sibling cp xp))) | |
(defn -main | |
[& args] | |
(let [tree-file (slurp "family-trees.txt") | |
matches (re-seq #"([A-Z][A-Z]) = ([a-zA-Z]+ [a-zA-Z]+) \(([MF])\)" | |
tree-file) | |
people (zipmap (map #(nth % 1) matches) | |
(map #(nth % 2) matches)) | |
relations (->> (re-seq #"([A-Z][A-Z])->([A-Z][A-Z])" tree-file) | |
(map #(map people %)))] | |
(doseq [[_ p c] relations] (fact parent p c)) | |
(doseq [[_ _ p g] matches] (fact ({"M" male "F" female} g) p)) | |
(do | |
(println "The parents of Arya Stark:\n" | |
(distinct (run* [q] (parent q "Arya Stark")))) | |
(println "The complete ancestry of Asha Greyjoy:\n" | |
(distinct (run* [q] (ancestor q "Asha Greyjoy")))) | |
(println "The complete ancestry of Daenerys Targaryen:\n" | |
(distinct (run* [q] (ancestor q "Daenerys Targaryen")))) | |
(println "The children of Jaehaerys Targaryen:\n" | |
(distinct (run* [q] (child q "Jaehaerys Targaryen")))) | |
(println "The complete descendants of Jaehaerys Targaryen:\n" | |
(distinct (run* [q] (descendant "Jaehaerys Targaryen" q)))) | |
(println "The siblings of Arya Stark:\n" | |
(distinct (run* [q] (sibling "Arya Stark" q)))) | |
(println "The father of Tyrion Lannister:\n" | |
(distinct (run* [q] (father q "Tyrion Lannister")))) | |
(println "The children whose mother is Catelyn Tully:\n" | |
(distinct (run* [q] (mother "Catelyn Tully" q)))) | |
(println "The people whose sister is Cersei Lannister:\n" | |
(distinct (run* [q] (sister "Cersei Lannister" q)))) | |
(println "The uncles of Joffrey Baratheon:\n" | |
(distinct (run* [q] (uncle q "Joffrey Baratheon")))) | |
(println "The aunt of Robb Stark:\n" | |
(distinct (run* [q] (aunt q "Robb Stark")))) | |
(println "The cousin of Robb Stark:\n" | |
(distinct (run* [q] (cousin q "Robb Stark")))) | |
(println "The nephew of Catelyn Tully:\n" | |
(distinct (run* [q] (nephew q "Catelyn Tully"))))))) |
I like the simplicity of the rules. Would be interesting to see someone whack up something in Prolog :)
This is a solution for Daily Programmer #65 (without an implementation for the bonus...yet) by way of Brian Taylor's blog.
Very nice solution. I'm impressed at how little code it took to ingest the text and build the relations.
Perhaps zipmap can be used instead of the apply hash-map interleave thing?
(zipmap (map #(nth % 1) matches)
(map #(nth % 2) matches))
And perhaps change the:
flatten
(map people)
(partition 2)
to:
(map #(map people %))
Nice, thanks for the suggestions, Ulsa.
You could also change:
(defn sister [s x]
(fresh []
(sibling s x)
(female s)))
to:
(defn sister [s x]
(all
(sibling s x)
(female s)))
and the brother
function as well.
Basically you can apply the same change I wrote on every function where you create logic variables that are not used. For example, father
, mother
, etc.
Gist updated. Thanks Carlos!
I did a try here for Prolog : https://github.com/antoinelyset/GoT_Prolog
I love the pragmatism of slurping in the text file and digesting it with regexps.