Palindrome detection: Difference between revisions
→{{header|langur}}
(Added Z80 Assembly version) |
Langurmonkey (talk | contribs) |
||
(22 intermediate revisions by 17 users not shown) | |||
Line 218:
(equal (rest xs) ys)
(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!}}==
Line 1,116 ⟶ 1,202:
palindrome
</pre>
=={{header|Bruijn}}==
<syntaxhighlight lang="bruijn">
:import std/String .
main [<~>0 =? 0]
:test (main "tacocat") ([[1]])
:test (main "bruijn") ([[0]])
</syntaxhighlight>
=={{header|Burlesque}}==
Line 1,779 ⟶ 1,875:
return true
}</syntaxhighlight>
=={{header|EasyLang}}==
<syntaxhighlight lang="easylang">
func$ reverse s$ .
a$[] = strchars s$
for i = 1 to len a$[] div 2
swap a$[i] a$[len a$[] - i + 1]
.
return strjoin a$[]
.
func palin s$ .
if s$ = reverse s$
return 1
.
return 0
.
for s$ in [ "rotor" "rosetta" "step on no pets" "été" "🦊😀🦊" ]
if palin s$ = 1
print s$ & " is a palindrome"
else
print s$ & " is not a palindrome"
.
.
</syntaxhighlight>
=={{header|EchoLisp}}==
Line 1,898 ⟶ 2,018:
<syntaxhighlight lang="lisp">(defun palindrome (s)
(string= s (reverse s)))</syntaxhighlight>
The version below will work correctly with inexact palindromes, as defined in this exercise:
<syntaxhighlight lang="lisp">
(defun test-if-palindrome (text)
(setq text (replace-regexp-in-string "[[:space:][:punct:]]" "" text)) ; remove spaces and punctuation, by replacing them with nothing
(string-equal-ignore-case text (reverse text))) ; ignore case when looking at reversed text
</syntaxhighlight>
{{out}}
<pre>
(test-if-palindrome "A man, a plan, a canal, Panama")
t
</pre>
=={{header|Erlang}}==
Line 2,490 ⟶ 2,624:
=={{header|Fōrmulæ}}==
{{FormulaeEntry|page=https://formulae.org/?script=examples/Palindrome_detection}}
'''Solution'''
[[File:Fōrmulæ - Palindrome detection 01.png]]
[[File:Fōrmulæ - Palindrome detection 02.png]]
'''Test cases'''
[[File:Fōrmulæ - Palindrome detection 03.png]]
[[File:Fōrmulæ - Palindrome detection 04.png]]
=={{header|GAP}}==
Line 2,601 ⟶ 2,743:
return true
}</syntaxhighlight>
=={{header|GolfScript}}==
===Recursive===
<syntaxhighlight lang="golfscript">{.,1>{(\)@={pal}0if}1if\;}:pal;</syntaxhighlight>
Test program:
<syntaxhighlight lang="groovy">"ABBA" pal
"a" pal
"13231+464+989=989+464+13231" pal
"123 456 789 897 654 321" pal</syntaxhighlight>
{{out}}
<pre>1
1
1
0</pre>
=={{header|Groovy}}==
Line 2,762 ⟶ 2,923:
return x
end</syntaxhighlight>
=={{header|Insitux}}==
This function works also for vectors.
<syntaxhighlight lang="insitux">(var palindrome? (= (reverse %)))
(palindrome? "deified") ;returns true</syntaxhighlight>
Space and punctuation insensitive version:
<syntaxhighlight lang="insitux">(var palindrome? (comp (filter letter?) lower-case (= (reverse %))))
(palindrome? "In girum imus nocte et consumimur igni.") ;returns true</syntaxhighlight>
=={{header|Ioke}}==
Line 3,086 ⟶ 3,259:
=={{header|langur}}==
<syntaxhighlight lang="langur">val .ispal =
val .tests =
"": false,
"z": true,
Line 4,087 ⟶ 4,260:
<span style="color: #0000FF;">?</span><span style="color: #000000;">extra_credit</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"tregða, gón, reiði - er nóg að gert"</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
=={{header|Phixmonti}}==
<syntaxhighlight lang="Phixmonti">include ..\Utilitys.pmt
def palindrome? dup reverse == enddef
( "abba" "boom" "radar" "civic" "great" )
len for get
dup print " : palindrome? " print palindrome?
if "true" else "false" endif ?
endfor
def letter? dup 'z' <= swap 'a' >= and enddef
"" >ps
"In girum imus nocte, et consumimur igni" dup ? lower
len for get
dup letter?
if
ps> swap chain >ps
else
drop
endif
endfor
ps> palindrome? if "This is an inexact palindrome!" else "Not a palindrome." endif ?
</syntaxhighlight>
{{out}}
<pre>abba : palindrome? true
boom : palindrome? false
radar : palindrome? true
civic : palindrome? true
great : palindrome? false
In girum imus nocte, et consumimur igni
This is an inexact palindrome!
=== Press any key to exit ===</pre>
=={{header|PHP}}==
Line 4,999 ⟶ 5,209:
'ingirumimusnocteetconsumimurigni palindrome? n:put
</syntaxhighlight>
=={{header|Refal}}==
<syntaxhighlight lang="refal">$ENTRY Go {
= <Test 'rotor'>
<Test 'racecar'>
<Test 'RACEcar'>
<Test 'level'>
<Test 'rosetta'>
<Test 'A man, a plan, a canal: Panama'>
<Test 'Egad, a base tone denotes a bad age'>
<Test 'This is not a palindrome'>;
};
Test {
e.W, <Palindrome e.W> <InexactPalindrome e.W>: {
True s.1 = <Prout e.W ': exact palindrome'>;
s.1 True = <Prout e.W ': inexact palindrome'>;
False False = <Prout e.W ': not a palindrome'>;
};
};
InexactPalindrome {
e.W = <Palindrome <Filter ('ABCDEFGHIJKLMNOPQRSTUVWXYZ') <Upper e.W>>>;
};
Filter {
(e.Keep) = ;
(e.Keep) s.C e.W, e.Keep: {
e.1 s.C e.2 = s.C <Filter (e.Keep) e.W>;
e.1 = <Filter (e.Keep) e.W>;
};
};
Palindrome {
= True;
s.C = True;
s.C e.W s.C = <Palindrome e.W>;
e.X = False;
};</syntaxhighlight>
{{out}}
<pre>rotor: exact palindrome
marinus@frankenstein:~/refal$ refc palin && refgo palin
Refal-5 Compiler. Version PZ Jan 25 2024
Copyright: Refal Systems Inc.
rotor: exact palindrome
racecar: exact palindrome
RACEcar: inexact palindrome
level: exact palindrome
rosetta: not a palindrome
A man, a plan, a canal: Panama: inexact palindrome
Egad, a base tone denotes a bad age: inexact palindrome
This is not a palindrome: not a palindrome</pre>
=={{header|REXX}}==
Line 5,066 ⟶ 5,328:
</syntaxhighlight>
=={{header|RPL}}==
≪ ""
OVER SIZE 1 '''FOR''' j
OVER j DUP SUB + -1 '''STEP'''
==
≫ ‘<span style="color:blue">XPAL?</span>’ STO
====Stretch====
RPL does not support Unicode. To detect inexact palindromes, we just need a clean-up word:
≪ ""
1 3 PICK SIZE '''FOR''' j
OVER j DUP SUB
'''IF''' DUP "a" ≥ OVER "z" ≤ AND '''THEN''' NUM 32 - CHR '''END'''
'''IF''' DUP "A" ≥ OVER "Z" ≤ AND '''THEN''' + '''ELSE''' DROP '''END'''
'''NEXT''' SWAP DROP
≫ ‘<span style="color:blue">AZONLY</span>’ STO
≪ <span style="color:blue">AZONLY</span> ""
OVER SIZE 1 '''FOR''' j
OVER j DUP SUB + -1 '''STEP'''
==
≫ ‘<span style="color:blue">IPAL?</span>’ STO
"rotor" <span style="color:blue">XPAL?</span>
"In girum imus nocte et consumimur igni." <span style="color:blue">IPAL?</span>
{{out}}
<pre>
2: 1
1: 1
</pre>
=={{header|Ruby}}==
Line 5,104 ⟶ 5,395:
iterative 0.062000 0.000000 0.062000 ( 0.055000)
recursive 16.516000 0.000000 16.516000 ( 16.562000)</pre>
=={{header|Rhovas}}==
Simplest solution using <code>String.reverse</code>:
<syntaxhighlight lang="scala">
func isPalindromeReverse(string: String): Boolean {
return string == string.reverse();
}
</syntaxhighlight>
Alternate character-based solution using pattern matching. Unlike <code>String.reverse</code>, this has limited unicode support due to surrogates (code points split into multiple characters).
<syntaxhighlight lang="scala">
func isPalindromeChars(chars: List<String>): Boolean {
match (chars) {
[]: return true;
[elem]: return true;
[first, middle*, last]: return first == last && isPalindromeChars(middle);
}
}
</syntaxhighlight>
Overall result and test cases:
<syntaxhighlight lang="scala">
func isPalindrome(string: String): Boolean {
return isPalindromeReverse(string) && isPalindromeChars(string.chars);
}
assert isPalindrome("");
assert isPalindrome("f");
assert isPalindrome("noon");
assert isPalindrome("kayak");
assert isPalindrome("step on no pets");
assert !isPalindrome("palindrome");
assert !isPalindrome("A man, a plan, a canal - Panama!"); //inexact
assert isPalindrome("§★♖★§"); //single utf16 code points
assert isPalindromeReverse("🗲"); //string reverse handles surrogates
assert !isPalindromeChars("🗲".chars); //.chars splits surrogates into two chars
</syntaxhighlight>
=={{header|Run BASIC}}==
<syntaxhighlight lang="runbasic">data "My dog has fleas", "Madam, I'm Adam.", "1 on 1", "In girum imus nocte et consumimur igni"
for i = 1 to 4
read w$
print w$;" is ";isPalindrome$(w$);" Palindrome"
next
for i = 1 to len(str$)
a$ = upper$(mid$(str$,i,1))
if (a$ >= "A" and a$ <= "Z") or (a$ >= "0" and a$ <= "9") then b$ = b$ + a$: c$ = a$ + c$
next i
if b$ <> c$ then isPalindrome$ = "not"
end function</syntaxhighlight>
{{out}}
<pre>My dog has fleas is not Palindrome
Line 5,351 ⟶ 5,685:
'''Built-in'''
<syntaxhighlight lang="ruby">say "noon".is_palindrome
'''Non-recursive'''
Line 5,365 ⟶ 5,699:
true
}
elsif (s.first
false
}
else {
__FUNC__(s.
}
}</syntaxhighlight>
Line 5,658 ⟶ 5,992:
console.log(isPalindrome('Я иду с мечем судия'))
</syntaxhighlight>
=={{header|Uiua}}==
Does not ignore spaces.
<syntaxhighlight lang="uiua">≍⇌."tacocat"</syntaxhighlight>
=={{header|UNIX Shell}}==
Line 5,844 ⟶ 6,182:
=={{header|Wren}}==
<syntaxhighlight lang="
System.print("Are the following palindromes?")
Line 6,077 ⟶ 6,415:
ld (inputbuf+1),a ; New length of text without spaces for further processing
ld b,0 ; bc now set correctly to new length
ld de,bufcont ; Set up and
ld hl,compress
ldir
|