Palindrome detection: Difference between revisions
Content added Content deleted
imported>Rowsety Moid No edit summary |
|||
Line 218: | Line 218: | ||
(equal (rest xs) ys) |
(equal (rest xs) ys) |
||
(equal xs ys)))))</syntaxhighlight> |
(equal xs ys)))))</syntaxhighlight> |
||
=={{header|Acornsoft Lisp}}== |
|||
This is a small Lisp that doesn't have strings; symbols are used instead. <code>Explode</code> takes a symbol and returns a list of single-character symbols, one for each character in the symbol's name. <code>Implode</code> does the reverse. |
|||
Since the exact palindrome tests compares two symbols, it can use <code>eq</code>, and <code>equal</code> isn't needed. |
|||
The character set is ASCII. Given a symbol, <code>ordinal</code> returns the numeric ASCII code of the the first character in the symbol's name. <code>Character</code> goes in the other direction and returns a single-character symbol. |
|||
The peculiar definition of <code>digit-p</code> is because it's not possible to type a symbol that has a digit character as its name, and so the ''between'' comparison has to be defined using the character before '0' and the one after '9'. |
|||
<syntaxhighlight lang="lisp"> |
|||
(defun palindrome-type (text) |
|||
(cond ((exact-palindrom-p text) 'exact) |
|||
((inexact-palindrome-p text) 'inexact) |
|||
(t 'not-a-palindrome))) |
|||
(defun exact-palindrom-p (text) |
|||
(eq text (implode (reverse (explode text))))) |
|||
(defun inexact-palindrome-p (text) |
|||
(exact-palindrom-p (implode (normalise (explode text))))) |
|||
(defun reverse (list (result . ())) |
|||
(map '(lambda (e) (setq result (cons e result))) |
|||
list) |
|||
result) |
|||
(defun normalise (chars) |
|||
(cond ((null chars) |
|||
nil) |
|||
((not (alphanumeric-p (car chars))) |
|||
(normalise (cdr chars))) |
|||
((upper-case-p (car chars)) |
|||
(cons (to-lower-case (car chars)) |
|||
(normalise (cdr chars)))) |
|||
(t |
|||
(cons (car chars) (normalise (cdr chars)))))) |
|||
(defun between-p (lowest-value n highest-value) |
|||
(not (or (lessp n lowest-value) |
|||
(greaterp n highest-value)))) |
|||
(defun alphanumeric-p (ch) |
|||
(or (lower-case-p ch) (upper-case-p ch) (digit-p ch))) |
|||
(defun digit-p (ch) |
|||
(between-p (add1 (ordinal '/)) |
|||
(ordinal ch) |
|||
(sub1 (ordinal ':)))) |
|||
(defun upper-case-p (ch) |
|||
(between-p (ordinal 'A) (ordinal ch) (ordinal 'Z))) |
|||
(defun lower-case-p (ch) |
|||
(between-p (ordinal 'a) (ordinal ch) (ordinal 'z))) |
|||
(defun to-lower-case (ch) |
|||
(character (plus (ordinal ch) |
|||
(difference (ordinal 'a) (ordinal 'A))))) |
|||
(defun examples () |
|||
(map '(lambda (text) |
|||
(printc '!" text '!" |
|||
'! is! (palindrome-type text))) |
|||
'(a |
|||
abba Abba |
|||
abcba |
|||
baba |
|||
Able! was! I! ere! I! saw! Elba!! |
|||
In! girum! imus! nocte,! et! consumimur! igni))) |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
Calling <code>(examples)</code> will output: |
|||
<pre> |
|||
"a" is exact |
|||
"abba" is exact |
|||
"Abba" is inexact |
|||
"abcba" is exact |
|||
"baba" is not-a-palindrome |
|||
"Able was I ere I saw Elba!" is inexact |
|||
"In girum imus nocte, et consumimur igni" is inexact |
|||
<pre> |
|||
=={{header|Action!}}== |
=={{header|Action!}}== |