|
| 1 | +;; -*- coding: utf-8 -*- |
| 2 | +;; |
| 3 | +;; Copyright (c) 2010-2015 Tuukka Turto |
| 4 | +;; |
| 5 | +;; Permission is hereby granted, free of charge, to any person obtaining a copy |
| 6 | +;; of this software and associated documentation files (the "Software"), to deal |
| 7 | +;; in the Software without restriction, including without limitation the rights |
| 8 | +;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 9 | +;; copies of the Software, and to permit persons to whom the Software is |
| 10 | +;; furnished to do so, subject to the following conditions: |
| 11 | +;; |
| 12 | +;; The above copyright notice and this permission notice shall be included in |
| 13 | +;; all copies or substantial portions of the Software. |
| 14 | +;; |
| 15 | +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 16 | +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 17 | +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 18 | +;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 19 | +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 20 | +;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 21 | +;; THE SOFTWARE. |
| 22 | + |
| 23 | +(require hy.contrib.anaphoric) |
| 24 | +(require pyherc.macros) |
| 25 | + |
| 26 | +(import [pyherc.utils [group]] |
| 27 | + [pyherc.markov [chain-factory]]) |
| 28 | + |
| 29 | +(setv male-names |
| 30 | + ["acacius" "achaikos" "aeschylus" "aesop" "agapetos" "agapetus" "agapios" |
| 31 | + "agathon" "akakios" "alcaeus" "alcibiades" "alexander" "alexandros" "alexios" |
| 32 | + "alexis" "alexius" "alkaios" "alkibiades" "ambrosios" "ambrosius" "ampelios" |
| 33 | + "ampelius" "amyntas" "anacletus" "anakletos" "anastasios" "anastasius" |
| 34 | + "anatolios" "anatolius" "anaxagoras" "andreas" "androcles" "androkles" |
| 35 | + "andronicus" "andronikos" "anicetus" "aniketos" "antigonos" "antigonus" |
| 36 | + "antiochos" "antiochus" "antipater" "antipatros" "aphrodisios" "apollinaris" |
| 37 | + "apollodoros" "apollonios" "arcadius" "archelaos" "archelaus" "archimedes" |
| 38 | + "archippos" "argyros" "aristarchos" "aristarchus" "aristeides" "aristides" |
| 39 | + "aristocles" "aristodemos" "aristokles" "ariston" "aristophanes" "aristoteles" |
| 40 | + "aristotle" "arkadios" "arsenios" "arsenius" "artemidoros" "artemios" |
| 41 | + "artemisios" "artemius" "artemon" "asklepiades" "athanas" "athanasios" |
| 42 | + "athanasius" "auxentios" "auxentius" "basileios" "basilius" "bion" "callias" |
| 43 | + "cassander" "chares" "chariton" "chrysanthos" "cleisthenes" "cleitus" |
| 44 | + "cleon" "clitus" "cosmas" "cyrillus" "cyrus" "damianos" "damianus" |
| 45 | + "dareios" "demetrios" "demetrius" "democritus" "demokritos" "demon" |
| 46 | + "demosthenes" "diocles" "diodoros" "diodorus" "diodotos" "diodotus" |
| 47 | + "diogenes" "diokles" "dion" "dionysios" "dionysius" "dionysodoros" "draco" |
| 48 | + "drakon" "eirenaios" "epaphras" "epaphroditos" "epiktetos" "epiphanes" |
| 49 | + "epiphanios" "epiphanius" "erasmos" "erastos" "euaristos" "euclid" |
| 50 | + "eugenios" "eugenius" "eukleides" "euphemios" "euphranor" "euripides" |
| 51 | + "eusebios" "eusebius" "eustachys" "eustathios" "eustathius" "eustorgios" |
| 52 | + "eustorgius" "euthymios" "euthymius" "eutropios" "eutropius" "eutychios" |
| 53 | + "eutychius" "eutychos" "evaristus" "gaios" "galenos" "gennadios" |
| 54 | + "gennadius" "georgios" "georgius" "heliodoros" "heracleitus" |
| 55 | + "heraclius" "herakleides" "herakleios" "herakleitos" "hermes" "hermogenes" |
| 56 | + "hermokrates" "hermolaos" "hero" "herodes" "herodion" "herodotos" |
| 57 | + "herodotus" "heron" "hesiod" "hesiodos" "hesperos" "hieronymos" "hieronymus" |
| 58 | + "hilarion" "hippocrates" "hippokrates" "hippolytos" "homer" "homeros" |
| 59 | + "hyacinthus" "hyakinthos" "hyginos" "hyginus" "hypatos" "iason" "irenaeus" |
| 60 | + "ireneus" "isidoros" "isocrates" "isokrates" "kallias" "kallikrates" |
| 61 | + "kallistos" "karpos" "kassandros" "kleisthenes" "kleitos" "kleon" |
| 62 | + "kleopatros" "kosmas" "kyriakos" "kyrillos" "kyros" "leon" "leonidas" |
| 63 | + "leontios" "leontius" "linos" "linus" "loukianos" "loukios" "lycurgus" |
| 64 | + "lycus" "lykos" "lykourgos" "lysander" "lysandros" "lysimachos" |
| 65 | + "lysimachus" "markos" "melanthios" "meliton" "methodios" "methodius" |
| 66 | + "metrophanes" "miltiades" "mnason" "myron" "neophytos" "nereus" "nicanor" |
| 67 | + "nicolaus" "nicomedes" "nicostratus" "nikandros" "nikanor" "nikephoros" |
| 68 | + "niketas" "nikias" "nikodemos" "nikolaos" "nikomachos" "nikomedes" |
| 69 | + "nikon" "nikostratos" "olympiodoros" "olympos" "onesimos" "onesiphoros" |
| 70 | + "origenes" "pamphilos" "pancratius" "pankratios" "pantaleon" "panther" |
| 71 | + "pantheras" "paramonos" "pelagios" "pelagius" "pericles" "perikles" |
| 72 | + "phaedrus" "phaidros" "philandros" "philippos" "philo" "philokrates" |
| 73 | + "philon" "philotheos" "phocas" "phoibos" "phokas" "photios" "plato" |
| 74 | + "platon" "ploutarchos" "polycarp" "polykarpos" "porphyrios" "praxiteles" |
| 75 | + "prochoros" "prokopios" "ptolemaios" "pyrrhos" "pyrrhus" "pythagoras" |
| 76 | + "seleucus" "seleukos" "simonides" "socrates" "sokrates" "solon" "sophocles" |
| 77 | + "sophokles" "sophos" "sophus" "sosigenes" "stephanos" "straton" |
| 78 | + "telesphoros" "telesphorus" "thales" "themistocles" "themistokles" |
| 79 | + "theocritus" "theodoros" "theodorus" "theodosios" "theodosius" "theodotos" |
| 80 | + "theodotus" "theodoulos" "theodulus" "theokritos" "theophanes" "theophilos" |
| 81 | + "theophilus" "theophylaktos" "theron" "thoukydides" "thucydides" |
| 82 | + "timaeus" "timaios" "timon" "timoteus" "timotheos" "tryphon" "tycho" |
| 83 | + "tychon" "xanthippos" "xenocrates" "xenokrates" "xenon" "xenophon" "zeno" |
| 84 | + "zenobios" "zenon" "zephyros" "zopyros" "zosimos" "zosimus" "zoticus" |
| 85 | + "zotikos"]) |
| 86 | + |
| 87 | +(setv female-names |
| 88 | + ["agape" "agatha" "agathe" "agnes" "aikaterine" "alexandra" "alexis" |
| 89 | + "ambrosia" "anastasia" "anthousa" "aphrodisia" "apollonia" "aristomache" |
| 90 | + "artemisia" "aspasia" "athanasia" "athenais" "berenice" "berenike" |
| 91 | + "charis" "charmion" "chloe" "chrysanthe" "cleopatra" "corinna" "demetria" |
| 92 | + "demostrate" "doris" "eirene" "elpis" "euanthe" "eudocia" "eudokia" |
| 93 | + "eudoxia" "eugeneia" "eugenia" "eulalia" "eumelia" "eunike" "euphemia" |
| 94 | + "euphrasia" "eupraxia" "euthalia" "euthymia" "eutropia" "eutychia" |
| 95 | + "gaiana" "gaiane" "galene" "hagne" "helena" "helene" "hypatia" "irene" |
| 96 | + "isidora" "kallisto" "kallistrate" "kassandra" "kleopatra" "korinna" |
| 97 | + "ligeia" "lysandra" "lysistrata" "lysistrate" "melissa" "melitta" |
| 98 | + "menodora" "metrodora" "myrrine" "nike" "nikephoros" "nymphodora" |
| 99 | + "olympias" "pelagia" "pherenike" "phile" "phoibe" "photina" "photine" |
| 100 | + "ptolemais" "rhode" "roxana" "roxane" "sappho" "sophia" "sostrate" |
| 101 | + "syntyche" "thais" "theodora" "theodosia" "theokleia" "theophania" |
| 102 | + "theophila" "timo" "timothea" "tryphaina" "tryphosa" "xanthe" "xanthippe" |
| 103 | + "xenia" "xeno" "zenais" "zenobia" "zoe" "zosime"]) |
| 104 | + |
| 105 | +(defn split-into-parts [name length] |
| 106 | + "split name into parts of given length" |
| 107 | + (list (ap-map (.join "" it) (group name length)))) |
| 108 | + |
| 109 | +(defn add-to-links [links parts-list] |
| 110 | + "add list of chain parts into links, each with same frequency" |
| 111 | + (when parts-list |
| 112 | + (let [[first-item (first parts-list)] |
| 113 | + [second-item (ap-if (second parts-list) |
| 114 | + #t (it 0 10) |
| 115 | + #t (nil 0 10))] |
| 116 | + [tail (list (rest parts-list))]] |
| 117 | + (if (not (in first-item links)) |
| 118 | + (assoc links first-item [second-item]) |
| 119 | + (when (not (in second-item (get links first-item))) |
| 120 | + (.append (get links first-item) second-item))) |
| 121 | + (when tail (add-to-links links tail))))) |
| 122 | + |
| 123 | +(defn add-starting-link [starting-links parts-list] |
| 124 | + "add starting link using standard frequency" |
| 125 | + (let [[first-item #t ((first parts-list) 0 10)]] |
| 126 | + (when (not (in first-item starting-links)) |
| 127 | + (.append starting-links first-item)))) |
| 128 | + |
| 129 | +(defn add-names [links starting-links length names] |
| 130 | + "process a list of names and prepape configuration for markov chain factory" |
| 131 | + (ap-each names (do (add-starting-link starting-links (split-into-parts it length)) |
| 132 | + (add-to-links links (split-into-parts it length))))) |
| 133 | + |
| 134 | +(defn create-name-generator [examples] |
| 135 | + "create and configure markov chain factory to create names based on examples" |
| 136 | + (let [[links {}] |
| 137 | + [starting-links []]] |
| 138 | + (add-names links starting-links 2 examples) |
| 139 | + (chain-factory starting-links links (fn [item] (not (is item nil)))))) |
| 140 | + |
| 141 | +(def greek-males (create-name-generator male-names)) |
| 142 | +(def greek-females (create-name-generator female-names)) |
| 143 | + |
| 144 | +(defn generate-name [factory] |
| 145 | + "generate a name" |
| 146 | + (.capitalize (.join "" (list (factory))))) |
| 147 | + |
| 148 | +(defn generate-male-name [] |
| 149 | + "generate name for male" |
| 150 | + (generate-name greek-males)) |
| 151 | + |
| 152 | +(defn generate-female-name [] |
| 153 | + "generate name for female" |
| 154 | + (generate-name greek-females)) |
0 commit comments