From dcdacde8312c98dc5832f952fd005e2d8fc66588 Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Wed, 31 Jan 2018 14:14:34 -0800 Subject: [PATCH] Add anagram.lisp. --- misc/anagram.lisp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 misc/anagram.lisp diff --git a/misc/anagram.lisp b/misc/anagram.lisp new file mode 100644 index 0000000..33d23db --- /dev/null +++ b/misc/anagram.lisp @@ -0,0 +1,41 @@ +;;; anagram.lisp +;;; 2018-01-31 +;;; +;;; Lisp implementation of this tweet: +;;; https://twitter.com/fermatslibrary/status/958700402647674880. +;;; +;;; Fun fact: this uses the prime list generated by +;;; (prime-numbers 26 3) +;;; using prime.rkt in the par/ toplevel directory. Why start at 3? It +;;; was a typo. + +(defpackage #:anagram + (:use #:cl) + (:export #:anagram-p)) +(in-package #:anagram) + +(defun deconstruct (w) + "Convert a string into a list of characters (instead of an array of +characters)." + (loop for c across w collect c)) + +(defparameter *mapping* + (pairlis + (deconstruct "abcdefghijklmnopqrstuvwxyz") + '(3 5 7 11 13 17 19 23 29 31 37 41 43 47 + 53 59 61 67 71 73 79 83 89 97 101 103))) + +(defun lookup (c) + "A hack to convert a character to its relevant prime." + (cdr (assoc c *mapping*))) + +(defun word-number (word) + "Convert a word to a number by multiplying the associated prime +number for all the letters in the word." + (apply #'* (mapcar #'lookup + (deconstruct (string-downcase word))))) + +(defun anagram-p (&rest words) + "Given a list of words, return T if they are all anagrams of each +other." + (apply #'= (mapcar #'word-number words)))