sandbox/misc/anagram.lisp

42 lines
1.2 KiB
Common Lisp

;;; 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)))