Palindrome detection: Difference between revisions

 
(179 intermediate revisions by 89 users not shown)
Line 3:
[[Category:String manipulation]]
[[Category:Classic CS problems and programs]]
[[Category:Palindromes]]
 
A [[wp:Palindrome|palindrome]] is a phrase which reads the same backward and forward.
Line 20 ⟶ 21:
 
{{task heading|Related tasks}}
 
{{Related tasks/Word plays}}
 
 
<hr>
{{Template:Strings}}
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F is_palindrome(s)
R s == reversed(s)</syntaxhighlight>
 
=={{header|360 Assembly}}==
<syntaxhighlight lang="360asm">* Reverse b string 25/06/2018
PALINDRO CSECT
USING PALINDRO,R13 base register
B 72(R15) skip savearea
DC 17F'0' savearea
STM R14,R12,12(R13) prolog
ST R13,4(R15) "
ST R15,8(R13) "
LR R13,R15 "
LA R8,BB @b[1]
LA R9,AA+L'AA-1 @a[n-1]
LA R6,1 i=1
LOOPI C R6,=A(L'AA) do i=1 to length(a)
BH ELOOPI leave i
MVC 0(1,R8),0(R9) substr(b,i,1)=substr(a,n-i+1,1)
LA R8,1(R8) @b=@b+1
BCTR R9,0 @a=@a-1
LA R6,1(R6) i=i+1
B LOOPI end do
ELOOPI XPRNT AA,L'AA print a
CLC BB,AA if b=a
BNE SKIP
XPRNT MSG,L'MSG then print msg
SKIP L R13,4(0,R13) epilog
LM R14,R12,12(R13) "
XR R15,R15 "
BR R14 exit
AA DC CL32'INGIRUMIMUSNOCTEETCONSUMIMURIGNI' a
BB DS CL(L'AA) b
MSG DC CL23'IT IS A TRUE PALINDROME'
YREGS
END PALINDRO</syntaxhighlight>
{{out}}
<pre>
INGIRUMIMUSNOCTEETCONSUMIMURIGNI
IT IS A TRUE PALINDROME
</pre>
 
=={{header|8080 Assembly}}==
 
<syntaxhighlight lang="8080asm"> org 100h
jmp demo
;;; Is the $-terminated string at DE a palindrome?
;;; Returns: zero flag set if palindrome
palin: mov h,d ; Find end of string
mov l,e
mvi a,'$'
cmp m ; The empty string is a palindrome
rz
pend: inx h ; Scan until terminator found
cmp m
jnz pend
dcx h ; Move to last byte of text
ptest: ldax d ; Load char at left pointer
cmp m ; Compare to char at right pointer
rnz ; If not equal, not a palindrome
inx d ; Move pointers
dcx h
mov a,d ; Check if left pointer is before right pointer
cmp h ; High byte
jc ptest
mov a,e ; Low byte
cmp l
jc ptest
xra a ; Made it to the end - set zero flag
ret ; Return
;;; Test the routine on a few examples
demo: lxi h,words ; Word list pointer
loop: mov e,m ; Load word pointer
inx h
mov d,m
inx h
mov a,e ; Stop when zero reached
ora d
rz
push h ; Keep word list pointer
call pstr ; Print word
call palin ; Check if palindrome
lxi d,no
jnz print ; Print "no" if not a palindrome
lxi d,yes ; Print "yes" otherwise
print: call pstr
pop h
jmp loop
;;; Print strint using CP/M keeping DEHL registers
pstr: push d
push h
mvi c,9
call 5
pop h
pop d
ret
yes: db ': yes',13,10,'$'
no: db ': no',13,10,'$'
words: dw w1,w2,w3,w4,0
w1: db 'rotor$'
w2: db 'racecar$'
w3: db 'level$'
w4: db 'rosetta$'</syntaxhighlight>
 
{{out}}
 
<pre>rotor: yes
racecar: yes
level: yes
rosetta: no</pre>
 
=={{header|8086 Assembly}}==
<syntaxhighlight lang="asm"> cpu 8086
org 100h
section .text
jmp demo
;;; Check if the $-terminated string in [DS:SI] is a palindrome.
;;; Returns with zero flag set if so.
;;; Destroyed: AL, CX, SI, DI, ES.
palin: push es ; Set ES=DS.
pop ds
mov al,'$' ; Find end of string
mov cx,-1
mov di,si
repne scasb
dec di ; Move back to last actual character
.loop: cmp si,di
ja .ok ; If SI > DI, it is a palindrome
lodsb
dec di ; Compare left character to right character
cmp al,[di]
jne .no ; If not equal, not a palindrome
jmp .loop ; Otherwise, try next pair of characters
.ok: cmp al,al ; Set zero flag
.no: ret ; Return
;;; Try the routine on a couple of strings
demo: mov si,words
.loop: lodsw ; Grab word pointer
test ax,ax ; Zero?
jz .done ; Then we are done
mov dx,ax ; Otherwise, print word
mov ah,9
int 21h
xchg bp,si ; Keep array pointer in BP
xchg si,dx ; Put word pointer in SI
call palin ; Check if it is a palindrome
mov dx,yes ; Print 'yes'...
jz .print ; ...if it is a palindrome
mov dx,no ; Otherwise, print 'no'
.print: int 21h
xchg si,bp ; Restore array pointer
jmp .loop ; Get next word.
.done: ret
yes: db ': yes',13,10,'$' ; Yes and no
no: db ': no',13,10,'$'
words: dw .w1,.w2,.w3,.w4,.w5,0
.w1: db 'rotor$' ; Words to check
.w2: db 'racecar$'
.w3: db 'level$'
.w4: db 'redder$'
.w5: db 'rosetta$'</syntaxhighlight>
 
{{out}}
 
<pre>rotor: yes
racecar: yes
level: yes
redder: yes
rosetta: no</pre>
 
=={{header|ACL2}}==
<langsyntaxhighlight Lisplang="lisp">(defun reverse-split-at-r (xs i ys)
(if (zp i)
(mv xs ys)
Line 42 ⟶ 217:
(if (= (mod lngth 2) 1)
(equal (rest xs) ys)
(equal xs ys)))))</langsyntaxhighlight>
 
=={{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!}}==
<syntaxhighlight lang="action!">BYTE FUNC Palindrome(CHAR ARRAY s)
BYTE l,r
 
l=1 r=s(0)
WHILE l<r
DO
IF s(l)#s(r) THEN RETURN (0) FI
l==+1 r==-1
OD
RETURN (1)
 
BYTE FUNC IsIgnored(BYTE c)
IF (c>=' AND c<='/) OR
(c>=': AND c<='@) OR
(c>='[ AND c<='_) THEN
RETURN (1)
FI
RETURN (0)
 
BYTE FUNC ToUpper(BYTE c)
IF c>='a AND c<='z THEN
RETURN (c-'a+'A)
FI
RETURN (c)
 
BYTE FUNC InexactPalindrome(CHAR ARRAY s)
BYTE l,r,lc,rc
 
l=1 r=s(0)
WHILE l<r
DO
WHILE IsIgnored(s(l))
DO
l==+1
IF l>=r THEN RETURN (1) FI
OD
WHILE IsIgnored(s(r))
DO
r==-1
IF l>=r THEN RETURN (1) FI
OD
 
lc=ToUpper(s(l))
rc=ToUpper(s(r))
 
IF lc#rc THEN RETURN (0) FI
l==+1 r==-1
OD
RETURN (1)
 
PROC Test(CHAR ARRAY s)
IF Palindrome(s) THEN
PrintF("'%S' is a palindrome%E%E",s)
ELSEIF InexactPalindrome(s) THEN
PrintF("'%S' is an inexact palindrome%E%E",s)
ELSE
PrintF("'%S' is not a palindrome%E%E",s)
FI
RETURN
 
PROC Main()
Test("rotavator")
Test("13231+464+989=989+464+13231")
Test("Was it a car or a cat I saw?")
Test("Did Hannah see bees? Hannah did.")
Test("This sentence is not a palindrome.")
Test("123 456 789 897 654 321")
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Palindrome_detection.png Screenshot from Atari 8-bit computer]
<pre>
'rotavator' is a palindrome
 
'13231+464+989=989+464+13231' is a palindrome
 
'Was it a car or a cat I saw?' is an inexact palindrome
 
'Did Hannah see bees? Hannah did.' is an inexact palindrome
 
'This sentence is not a palindrome.' is not a palindrome
 
'123 456 789 897 654 321' is not a palindrome
</pre>
 
=={{header|ActionScript}}==
The following function handles non-ASCII characters properly, since charAt() returns a single Unicode character.
<langsyntaxhighlight ActionScriptlang="actionscript">function isPalindrome(str:String):Boolean
{
for(var first:uint = 0, second:uint = str.length - 1; first < second; first++, second--)
if(str.charAt(first) != str.charAt(second)) return false;
return true;
}</langsyntaxhighlight>
 
=={{header|Ada}}==
<langsyntaxhighlight lang="ada">function Palindrome (Text : String) return Boolean is
begin
for Offset in 0..Text'Length / 2 - 1 loop
Line 61 ⟶ 408:
end loop;
return True;
end Palindrome;</langsyntaxhighlight>
 
----
Ada 2012 version:
<syntaxhighlight lang="ada">
function Palindrome (Text : String) return Boolean is
(for all i in Text'Range => Text(i)= Text(Text'Last-i+Text'First));
</syntaxhighlight>
 
=={{header|ALGOL 68}}==
{{trans|C}}
Line 68 ⟶ 423:
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386 - except for the '''FORMAT''' and ''printf'' in test}}
<langsyntaxhighlight lang="algol68"># Iterative #
PROC palindrome = (STRING s)BOOL:(
FOR i TO UPB s OVER 2 DO
Line 93 ⟶ 448:
printf((template, t, palindrome(t)));
printf((template, t, palindrome r(t)))
)</langsyntaxhighlight>
{{out}}
<pre>
Line 100 ⟶ 455:
</pre>
 
=={{header|APL}}==
NARS2000 APL, dynamic function "if the argument matches the reverse of the argument", with Unicode character support:
<syntaxhighlight lang="apl"> {⍵≡⌽⍵} 'abc'
0
{⍵≡⌽⍵} '⍋racecar⍋'
1</syntaxhighlight>
Or in tacit function form, a combination of three functions, right tack (echo), reverse, then the result of each compared with the middle one, match (equals):
<syntaxhighlight lang="apl"> (⊢≡⌽) 'abc'
0
(⊢≡⌽) 'nun'
1</syntaxhighlight>
An inexact version is harder, because uppercase and lowercase with Unicode awareness depends on APL interpreter; NARS2000 has no support for it. Classic case conversion means lookup up the letters in an alphabet of UppercaseLowercase, then mapping those positions into an UppercaseUppercase or LowercaseLowercase array. Remove non-A-Za-z first to get rid of punctuation, and get an inexact dynamic function with just English letter support:
<syntaxhighlight lang="apl">inexact←{Aa←(⎕A,⎕a) ⋄ (⊢≡⌽)(⎕a,⎕a)[Aa⍳⍵/⍨⍵∊Aa]}
inexact 'abc,-cbA2z'
0
inexact 'abc,-cbA2'
1</syntaxhighlight>
Dyalog APL has a Unicode-aware uppercase/lowercase function (819 I-beam), AFAIK no support for looking up Unicode character classes.
 
=={{header|AppleScript}}==
 
Using post-Yosemite AppleScript (to pull in lowercaseStringWithLocale from Foundation classes)
<syntaxhighlight lang="applescript">use framework "Foundation"
 
------ CASE-INSENSITIVE PALINDROME, IGNORING SPACES ? ----
<lang AppleScript>use framework "Foundation"
 
 
-- isPalindrome :: String -> Bool
Line 113 ⟶ 486:
end isPalindrome
 
-- toSpaceFreeLower :: String -> String
on spaceFreeToLower(s)
script notSpace
on |λ|(s)
s is not space
end |λ|
end script
intercalate("", filter(notSpace, characters of toLower(s)))
end spaceFreeToLower
 
 
--------------------------- TEST -------------------------
-- TEST
 
on run
isPalindrome(lowerCaseNoSpacespaceFreeToLower("In girum imus nocte et consumimur igni"))
--> true
Line 125 ⟶ 507:
end run
 
-- lowerCaseNoSpace :: String -> String
on lowerCaseNoSpace(s)
script notSpace
on lambda(s)
s is not space
end lambda
end script
intercalate("", filter(notSpace, characters of toLowerCase(s)))
end lowerCaseNoSpace
 
-------------------- GENERIC FUNCTIONS -------------------
 
-- GENERIC LIBRARY FUNCTIONS
 
-- toLowerCase :: String -> String
on toLowerCase(str)
set ca to current application
((ca's NSString's stringWithString:(str))'s ¬
lowercaseStringWithLocale:(ca's NSLocale's currentLocale())) as text
end toLowerCase
 
-- intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
set {dlm, my text item delimiters} to {my text item delimiters, strText}
set strJoined to lstText as text
set my text item delimiters to dlm
return strJoined
end intercalate
 
-- filter :: (a -> Bool) -> [a] -> [a]
Line 161 ⟶ 517:
repeat with i from 1 to lng
set v to item i of xs
if lambda|λ|(v, i, xs) then set end of lst to v
end repeat
return lst
end tell
end filter
 
 
-- intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
set {dlm, my text item delimiters} to {my text item delimiters, strText}
set strJoined to lstText as text
set my text item delimiters to dlm
return strJoined
end intercalate
 
 
-- Lift 2nd class handler function into 1st class script wrapper
Line 174 ⟶ 540:
else
script
property lambda|λ| : f
end script
end if
end mReturn</lang>
 
 
-- toLower :: String -> String
on toLower(str)
set ca to current application
((ca's NSString's stringWithString:(str))'s ¬
lowercaseStringWithLocale:(ca's NSLocale's currentLocale())) as text
end toLower</syntaxhighlight>
{{Out}}
<pre>true</pre>
----
===Core language only===
It's not clear if "sequence of characters" means an array thereof or a single piece of text. But the basic method in AppleScript would be:
<syntaxhighlight lang="applescript">on isPalindrome(txt)
set txt to join(txt, "") -- In case the input's a list (array).
return (txt = join(reverse of txt's characters, ""))
end isPalindrome
 
on join(lst, delim)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delim
set txt to lst as text
set AppleScript's text item delimiters to astid
return txt
end join
 
return isPalindrome("Radar")</syntaxhighlight>
 
Text comparisons in AppleScript are case-insensitive by default, so:
 
{{output}}
<syntaxhighlight lang="applescript">true</syntaxhighlight>
 
If case is to be taken into account, the call to the handler can be enclosed in a 'considering case' control statement.
<syntaxhighlight lang="applescript">considering case
return isPalindrome("Radar")
end considering</syntaxhighlight>
 
{{output}}
<syntaxhighlight lang="applescript">false</syntaxhighlight>
 
It's also possible to "ignore" white space, hyphens, and punctuation, which are considered by default. And of course case can be ignored explicitly, if desired, to ensure that this condition's in force during the call to the handler. The attributes can be combined in one statement. So to check for inexact palindromicity (if that's a word):
 
<syntaxhighlight lang="applescript">ignoring case, white space, hyphens and punctuation
return isPalindrome("Was it a 😀car, or a c😀at-I-saw?")
end ignoring</syntaxhighlight>
 
{{output}}
<syntaxhighlight lang="applescript">true</syntaxhighlight>
 
=={{header|Applesoft BASIC}}==
<langsyntaxhighlight ApplesoftBasiclang="applesoftbasic">100 DATA"MY DOG HAS FLEAS"
110 DATA"MADAM, I'M ADAM."
120 DATA"1 ON 1"
Line 205 ⟶ 620:
350 PA = MID$(W$, L0, 1) = MID$(W$, L - L0 + 1, 1)
360 IF PALINDROME THEN NEXT L0
370 RETURN</langsyntaxhighlight>
 
=={{header|ARM Assembly}}==
<syntaxhighlight lang="text">@ Check whether the ASCII string in [r0] is a palindrome
@ Returns with zero flag set if palindrome.
palin: mov r1,r0 @ Find end of string
1: ldrb r2,[r1],#1 @ Grab character and increment pointer
tst r2,r2 @ Zero yet?
bne 1b @ If not try next byte
sub r1,r1,#2 @ Move R1 to last actual character.
2: cmp r0,r1 @ When R0 >= R1,
cmpgt r2,r2 @ make sure zero is set,
bxeq lr @ and stop (the string is a palindrome).
ldrb r2,[r1],#-1 @ Grab [R1] (end) and decrement.
ldrb r3,[r0],#1 @ Grab [R0] (begin) and increment
cmp r2,r3 @ Are they equal?
bxne lr @ If not, it's not a palindrome.
b 2b @ Otherwise, try next pair.
@ Try the function on a couple of strings
.global _start
_start: ldr r8,=words @ Word pointer
1: ldr r9,[r8],#4 @ Grab word and move pointer
tst r9,r9 @ Null?
moveq r7,#1 @ Then we're done; syscall 1 = exit
swieq #0
mov r1,r9 @ Print the word
bl print
mov r0,r9 @ Test if the word is a palindrome
bl palin
ldreq r1,=yes @ "Yes" if it is a palindrome
ldrne r1,=no @ "No" if it's not a palindrome
bl print
b 1b @ Next word
 
@ Print zero-terminated string [r1] using Linux syscall
print: push {r7,lr} @ Keep R7 and link register
mov r2,r1 @ Find end of string
1: ldrb r0,[r2],#1 @ Grab character and increment pointer
tst r0,r0 @ Zero yet?
bne 1b @ If not, keep going
sub r2,r2,r1 @ Calculate length of string (bytes to write)
mov r0,#1 @ Stdout = 1
mov r7,#4 @ Syscall 4 = write
swi #0 @ Make the syscall
pop {r7,lr} @ Restore R7 and link register
bx lr
@ Strings
yes: .asciz ": yes\n" @ Output yes or no
no: .asciz ": no\n"
w1: .asciz "rotor" @ Words to test
w2: .asciz "racecar"
w3: .asciz "level"
w4: .asciz "redder"
w5: .asciz "rosetta"
words: .word w1,w2,w3,w4,w5,0</syntaxhighlight>
 
{{out}}
 
<pre>rotor: yes
racecar: yes
level: yes
redder: yes
rosetta: no</pre>
 
=={{header|Arturo}}==
<syntaxhighlight lang="rebol">palindrome?: $[seq] -> seq = reverse seq
loop ["abba" "boom" "radar" "civic" "great"] 'wrd [
print [wrd ": palindrome?" palindrome? wrd]
]</syntaxhighlight>
 
{{out}}
 
<pre>abba : palindrome? true
boom : palindrome? false
radar : palindrome? true
civic : palindrome? true
great : palindrome? false</pre>
 
=={{header|AutoHotkey}}==
Reversing the string:
<langsyntaxhighlight AutoHotkeylang="autohotkey">IsPalindrome(Str){
Loop, Parse, Str
ReversedStr := A_LoopField . ReversedStr
return, (ReversedStr == Str)?"Exact":(RegExReplace(ReversedStr,"\W")=RegExReplace(Str,"\W"))?"Inexact":"False"
}</langsyntaxhighlight>
 
=={{header|AutoIt}}==
 
<langsyntaxhighlight AutoItlang="autoit">;== AutoIt Version: 3.3.8.1
 
Global $aString[7] = [ _
Line 248 ⟶ 742:
Return True
EndFunc
</syntaxhighlight>
</lang>
{{out}}
<syntaxhighlight lang="text">
<lang Text>
"In girum imus nocte, et consumimur igni" is an inexact palindrome.
"Madam, I'm Adam." is an inexact palindrome.
Line 258 ⟶ 752:
"Ein Neger mit Gazelle zagt im Regen nie." is an inexact palindrome.
"something wrong" is not a palindrome.
</syntaxhighlight>
</lang>
 
--[[User:BugFix|BugFix]] ([[User talk:BugFix|talk]]) 14:26, 13 November 2013 (UTC)
Line 267 ⟶ 761:
See [[Reversing a string]].
 
<langsyntaxhighlight lang="awk">function is_palindro(s)
{
if ( s == reverse(s) ) return 1
return 0
}</langsyntaxhighlight>
 
'''Recursive'''
 
<langsyntaxhighlight lang="awk">function is_palindro_r(s)
{
if ( length(s) < 2 ) return 1
if ( substr(s, 1, 1) != substr(s, length(s), 1) ) return 0
return is_palindro_r(substr(s, 2, length(s)-2))
}</langsyntaxhighlight>
 
'''Testing'''
<langsyntaxhighlight lang="awk">BEGIN {
pal = "ingirumimusnocteetconsumimurigni"
print is_palindro(pal)
print is_palindro_r(pal)
}</langsyntaxhighlight>
 
=={{header|BaCon}}==
<syntaxhighlight lang="freebasic">
OPTION COMPARE TRUE
 
INPUT "Enter your line... ", word$
 
IF word$ = REVERSE$(word$) THEN
PRINT "This is an exact palindrome!"
ELIF EXTRACT$(word$, "[[:punct:]]|[[:blank:]]", TRUE) = REVERSE$(EXTRACT$(word$, "[[:punct:]]|[[:blank:]]", TRUE)) THEN
PRINT "This is an inexact palindrome!"
ELSE
PRINT "Not a palindrome."
ENDIF
</syntaxhighlight>
{{out}}
<pre>
Enter your line... In girum imus nocte, et consumimur igni
This is an inexact palindrome!
Enter your line... Madam, I'm Adam.
This is an inexact palindrome!
Enter your line... radar
This is an exact palindrome!
Enter your line... Something else
Not a palindrome.
</pre>
 
=={{header|Bash}}==
<syntaxhighlight lang="bash">
#! /bin/bash
# very simple way to detect a palindrome in Bash
# output of bash --version -> GNU bash, version 4.4.7(1)-release x86_64 ...
 
echo "enter a string"
read input
 
size=${#input}
count=0
 
while (($count < $size))
do
array[$count]=${input:$count:1}
(( count+=1 ))
done
 
count=0
 
for ((i=0 ; i < $size; i+=1))
do
if [ "${array[$i]}" == "${array[$size - $i - 1]}" ]
then
(( count += 1 ))
fi
done
 
if (( $count == $size ))
then
echo "$input is a palindrome"
fi
</syntaxhighlight>
 
=={{header|BASIC}}==
{{works with|QBasic}}
 
<langsyntaxhighlight lang="qbasic">' OPTION _EXPLICIT ' For QB64. In VB-DOS remove the underscore.
 
DIM txt$
Line 371 ⟶ 925:
RvrsText$ = NewText$
 
END FUNCTION</langsyntaxhighlight>
 
{{out}}
Line 384 ⟶ 938:
Is not a palindrome.
 
==={{header|BBC IS-BASIC}}===
<syntaxhighlight lang="is-basic">
<lang bbcbasic> test$ = "A man, a plan, a canal: Panama!"
100 PROGRAM "Palindr.bas"
110 LINE INPUT PROMPT "Text: ":TX$
120 PRINT """";TX$;""" is ";
130 IF PALIND(TX$) THEN
140 PRINT "a palindrome."
150 ELSE
160 PRINT "not a palindrome."
170 END IF
180 DEF TRIM$(TX$)
190 LET T$=""
200 FOR I=1 TO LEN(TX$)
210 IF TX$(I)>="A" AND TX$(I)<="Z" THEN LET T$=T$&TX$(I)
220 NEXT
230 LET TRIM$=T$
240 END DEF
250 DEF PALIND(TX$)
260 LET PALIND=-1:LET TX$=TRIM$(UCASE$(TX$))
270 FOR I=1 TO LEN(TX$)/2
280 IF TX$(I)<>TX$(LEN(TX$)-I+1) THEN LET PALIND=0:EXIT FOR
290 NEXT
300 END DEF</syntaxhighlight>
 
==={{header|Sinclair ZX81 BASIC}}===
====Exact palindrome====
The specification suggests, but does not insist, that we reverse the input string and then test for equality; this algorithm is more efficient.
<syntaxhighlight lang="basic"> 10 INPUT S$
20 FOR I=1 TO LEN S$/2
30 IF S$(I)<>S$(LEN S$-I+1) THEN GOTO 60
40 NEXT I
50 GOTO 70
60 PRINT "NOT A ";
70 PRINT "PALINDROME"</syntaxhighlight>
====Inexact palindrome====
Add the following lines to convert the program into an inexact-palindrome checker (i.e. one that ignores non-alphabetic characters). The resulting program still works with only 1k of RAM. The ZX81 only supports its own character set, which does not include lower case, so that case-insensitive comparison and <i>a fortiori</i> Unicode are not possible.
<syntaxhighlight lang="basic"> 15 GOSUB 90
80 STOP
90 LET T$=""
100 FOR I=1 TO LEN S$
110 IF S$(I)>="A" AND S$(I)<="Z" THEN LET T$=T$+S$(I)
120 NEXT I
130 LET S$=T$
140 RETURN</syntaxhighlight>
 
==={{header|BBC BASIC}}===
<syntaxhighlight lang="bbcbasic"> test$ = "A man, a plan, a canal: Panama!"
PRINT """" test$ """" ;
IF FNpalindrome(FNletters(test$)) THEN
Line 411 ⟶ 1,010:
ENDIF
NEXT
= B$</langsyntaxhighlight>
{{out}}
<pre>"A man, a plan, a canal: Panama!" is a palindrome</pre>
Line 417 ⟶ 1,016:
=={{header|Batch File}}==
 
<langsyntaxhighlight lang="dos">@echo off
setlocal enabledelayedexpansion
set /p string=Your string :
Line 431 ⟶ 1,030:
echo %string% %palindrome% a palindrome.
pause
exit</langsyntaxhighlight>
 
Or, recursive (and without setlocal enabledelayedexpansion) (compatible with ReactOS cmd.exe)
<langsyntaxhighlight lang="dos">@echo off
set /p testString=Your string (all same case please) :
call :isPalindrome result %testString: =%
Line 452 ⟶ 1,051:
call :isPalindrome %1 %string:~1,-1%
)
goto :eof</langsyntaxhighlight>
 
=={{header|BCPL}}==
<syntaxhighlight lang="bcpl">get "libhdr"
 
let palindrome(s) = valof
$( let l = s%0
for i = 1 to l/2
unless s%i = s%(l+1-i)
resultis false
resultis true
$)
 
let inexact(s) = valof
$( let temp = vec 1+256/BYTESPERWORD
temp%0 := 0
for i = 1 to s%0 do
$( let ch = s%i | 32
if '0'<=ch & ch<='9' | 'a'<=ch & ch<='z' then
$( temp%0 := temp%0 + 1
temp%(temp%0) := ch
$)
$)
resultis palindrome(temp)
$)
 
let check(s) =
palindrome(s) -> "exact palindrome",
inexact(s) -> "inexact palindrome",
"not a palindrome"
 
let start() be
$( let tests = vec 8
tests!0 := "rotor"
tests!1 := "racecar"
tests!2 := "RACEcar"
tests!3 := "level"
tests!4 := "redder"
tests!5 := "rosetta"
tests!6 := "A man, a plan, a canal: Panama"
tests!7 := "Egad, a base tone denotes a bad age"
tests!8 := "This is not a palindrome"
for i = 0 to 8 do
writef("'%S': %S*N", tests!i, check(tests!i))
$)</syntaxhighlight>
{{out}}
<pre>'rotor': exact palindrome
'racecar': exact palindrome
'RACEcar': inexact palindrome
'level': exact palindrome
'redder': 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|Befunge}}==
Line 459 ⟶ 1,113:
 
The following code reads a line from stdin and prints "True" if it is a palindrome, or False" otherwise.
<langsyntaxhighlight lang="befunge">v_$0:8p>:#v_:18p08g1-08p >:08g`!v
~->p5p ^ 0v1p80-1g80vj!-g5g80g5_0'ev
:a^80+1:g8<>8g1+:18pv>0"eslaF">:#,_@
[[relet]]-2010------>003-x -^"Tru"<</langsyntaxhighlight>
 
{{works with|Befunge|93}}
Line 473 ⟶ 1,127:
* The potential palindrome can be no longer than 76 characters (which beats the previous version's 11), and ''everything'' (spaces, punctuation, capitalization, etc.) is considered part of the palindrome. (Best to just use lower case letters and ''nothing else''.)
 
<langsyntaxhighlight lang="befunge">v> "emordnilap a toN",,,,,,,,,,,,,,,,@,,,,,,,,,,,,,,,"Is a palindrome" <
2^ < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < <
4 ^_v ^_v ^_v ^_v ^_v ^_v ^_v ^_v ^_v ^_v ^_v ^_v
Line 490 ⟶ 1,144:
>09g8p09g1+09pv
|: < <
^<</langsyntaxhighlight>
 
=={{header|BQN}}==
3 functions in three different styles to check if a string is a palindrome. All three forms return 1 for palindrome, and 0 for non-palindrome.
 
BQN considers characters as single units, and hence the functions support unicode by default.
 
<syntaxhighlight lang="bqn">Pal ← ≡⊸⌽
Pal1 ← ⊢≡⌽
Pal2 ← {𝕩≡⌽𝕩}</syntaxhighlight>
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang="bracmat">( ( palindrome
= a
. @(!arg:(%?a&utf$!a) ?arg !a)
Line 526 ⟶ 1,189:
)
&
);</langsyntaxhighlight>
Output:
<pre>In girum imus nocte et consumimur igni is indeed a palindrome
Line 539 ⟶ 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}}==
 
<langsyntaxhighlight lang="burlesque">
zz{ri}f[^^<-==
</syntaxhighlight>
</lang>
 
=={{header|C}}==
Line 555 ⟶ 1,228:
and if the length is odd, the middle doesn't need to be checked (so it's okay to do integer division by 2, which rounds down).
 
<langsyntaxhighlight lang="c">#include <string.h>
 
int palindrome(const char *s)
Line 566 ⟶ 1,239:
}
return 1;
}</langsyntaxhighlight>
More idiomatic version:
<langsyntaxhighlight lang="c">int palindrome(const char *s)
{
const char *t; /* t is a pointer that traverses backwards from the end */
Line 577 ⟶ 1,250:
}
return 1;
}</langsyntaxhighlight>
 
'''Recursive'''
Line 584 ⟶ 1,257:
itself a palindrome.
 
<langsyntaxhighlight lang="c">int palindrome_r(const char *s, int b, int e)
{
if ( (e - 1) <= b ) return 1;
if ( s[b] != s[e-1] ) return 0;
return palindrome_r(s, b+1, e-1);
}</langsyntaxhighlight>
 
'''Testing'''
 
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <string.h>
/* testing */
Line 607 ⟶ 1,280:
t, palindrome_r(t, 0, l) ? "" : "n't");
return 0;
}</langsyntaxhighlight>
 
=={{header|C++}}==
The C solutions also work in C++, but C++ allows a simpler one:
<lang cpp>#include <string>
#include <algorithm>
 
bool is_palindrome(std::string const& s)
{
return std::equal(s.begin(), s.end(), s.rbegin());
}</lang>
 
Or, checking half is sufficient (on odd-length strings, this will ignore the middle element):
<lang cpp>#include <string>
#include <algorithm>
 
bool is_palindrome(std::string const& s)
{
return std::equal(s.begin(), s.begin()+s.length()/2, s.rbegin());
}</lang>
 
=={{header|C sharp|C#}}==
Line 632 ⟶ 1,286:
'''Non-recursive'''
 
<langsyntaxhighlight lang="csharp">using System;
 
class Program
Line 652 ⟶ 1,306:
Console.WriteLine(IsPalindrome("ingirumimusnocteetconsumimurigni"));
}
}</langsyntaxhighlight>
 
'''Using LINQ operators'''
<langsyntaxhighlight lang="csharp">using System;
using System.Linq;
 
Line 670 ⟶ 1,324:
}
}
</syntaxhighlight>
</lang>
 
'''No string reversal'''
 
Reversing a string is very slow. A much faster way is to simply compare characters.
<langsyntaxhighlight lang="csharp">using System;
 
static class Program
Line 691 ⟶ 1,345:
Console.WriteLine("ingirumimusnocteetconsumimurigni".IsPalindrome());
}
}</langsyntaxhighlight>
 
=={{header|C++}}==
The C solutions also work in C++, but C++ allows a simpler one:
<syntaxhighlight lang="cpp">#include <string>
#include <algorithm>
 
bool is_palindrome(std::string const& s)
{
return std::equal(s.begin(), s.end(), s.rbegin());
}</syntaxhighlight>
 
Or, checking half is sufficient (on odd-length strings, this will ignore the middle element):
<syntaxhighlight lang="cpp">#include <string>
#include <algorithm>
 
bool is_palindrome(std::string const& s)
{
return std::equal(s.begin(), s.begin()+s.length()/2, s.rbegin());
}</syntaxhighlight>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(defn palindrome? [s]
(= s (apply str (clojure.string/reverse s))))</langsyntaxhighlight>
 
'''lower-level, but somewhat faster'''
'''Recursive'''
<langsyntaxhighlight lang="clojure">(defn palindrome? [^String s]
(loop [ifront 0 back (dec (.length s))]
j (decor (.>= sfront length)back)]
(condand (>= i(.charAt js front) true(.charAt s back))
(=recur (getinc s ifront) (getdec s jback)))))</syntaxhighlight>
(recur (inc i) (dec j))
:else false)))</lang>
 
'''Test'''
Line 713 ⟶ 1,384:
false
</pre>
 
=={{header|CLU}}==
<syntaxhighlight lang="clu">% Reverse a string
str_reverse = proc (s: string) returns (string)
chs: array[char] := array[char]$predict(0, string$size(s))
for c: char in string$chars(s) do
array[char]$addl(chs, c)
end
return (string$ac2s(chs))
end str_reverse
 
% 'Normalize' a string (remove everything but letters and make uppercase)
normalize = proc (s: string) returns (string)
chs: array[char] := array[char]$predict(0, string$size(s))
for c: char in string$chars(s) do
if c>='a' cand c<='z' then
c := char$i2c(char$c2i(c) - 32)
end
if c>='A' cand c<='Z' then
array[char]$addh(chs, c)
end
end
return (string$ac2s(chs))
end normalize
 
% Check if a string is an exact palindrome
palindrome = proc (s: string) returns (bool)
return (s = str_reverse(s))
end palindrome
 
% Check if a string is an inexact palindrome
inexact_palindrome = proc (s: string) returns (bool)
return (palindrome(normalize(s)))
end inexact_palindrome
 
% Test cases
start_up = proc ()
po: stream := stream$primary_output()
tests: array[string] := array[string]$[
"rotor", "racecar", "RACEcar", "level", "rosetta",
"A man, a plan, a canal: Panama",
"Egad, a base tone denotes a bad age",
"This is not a palindrome"
]
for test: string in array[string]$elements(tests) do
stream$puts(po, "\"" || test || "\": ")
if palindrome(test) then
stream$putl(po, "exact palindrome")
elseif inexact_palindrome(test) then
stream$putl(po, "inexact palindrome")
else
stream$putl(po, "not a palindrome")
end
end
end start_up</syntaxhighlight>
{{out}}
<pre>"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|COBOL}}==
{{works with|GnuCOBOL}}
<langsyntaxhighlight COBOLlang="cobol"> identification division.
function-id. palindromic-test.
 
Line 735 ⟶ 1,471:
goback.
end function palindromic-test.
</syntaxhighlight>
</lang>
 
=={{header|CoffeeScript}}==
<langsyntaxhighlight lang="coffeescript">
String::isPalindrome = ->
for i in [0...@length / 2] when @[i] isnt @[@length - (i + 1)]
Line 751 ⟶ 1,487:
'There is no spoon.'
]
</syntaxhighlight>
</lang>
 
{{out}}
Line 759 ⟶ 1,495:
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun palindrome-p (s)
(string= s (reverse s)))</langsyntaxhighlight>
===Alternate solution===
I use [https://franz.com/downloads/clp/survey Allegro CL 10.1]
 
<syntaxhighlight lang="lisp">
;; Project : Palindrome detection
 
(defun palindrome(x)
(if (string= x (reverse x))
(format t "~d" ": palindrome" (format t x))
(format t "~d" ": not palindrome" (format t x))))
(terpri)
(setq x "radar")
(palindrome x)
(terpri)
(setq x "books")
(palindrome x)
(terpri)
</syntaxhighlight>
Output:
<pre>
radar: palindrome
books: not palindrome
</pre>
 
=={{header|Component Pascal}}==
BlackBox Component Builder
<langsyntaxhighlight lang="oberon2">
MODULE BbtPalindrome;
IMPORT StdLog;
Line 801 ⟶ 1,560:
END Do;
END BbtPalindrome.
</syntaxhighlight>
</lang>
Execute: ^Q BbtPalindrome.Do<br/>
{{out}}
Line 810 ⟶ 1,569:
</pre>
 
=={{header|DelphiCowgol}}==
<syntaxhighlight lang="cowgol">include "cowgol.coh";
<lang Delphi>uses
SysUtils, StrUtils;
 
# Check if a string is a palindrome
function IsPalindrome(const aSrcString: string): Boolean;
sub palindrome(word: [uint8]): (r: uint8) is
begin
r := 1;
Result := SameText(aSrcString, ReverseString(aSrcString));
end;</lang>
# empty string is a palindrome
if [word] == 0 then
return;
end if;
# find the end of the word
var end_ := word;
while [@next end_] != 0 loop
end_ := @next end_;
end loop;
# check if bytes match in both directions
while word < end_ loop
if [word] != [end_] then
r := 0;
return;
end if;
word := @next word;
end_ := @prev end_;
end loop;
end sub;
 
# Check if a string is an inexact palindrome
sub inexact(word: [uint8]): (r: uint8) is
var buf: uint8[256];
var ptr := &buf[0];
# filter non-letters and non-numbers
while [word] != 0 loop
var c := [word];
if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') then
# copy lowercase letters and numbers over verbatim
[ptr] := c;
ptr := @next ptr;
elseif c >= 'A' and c <= 'Z' then
# make uppercase letters lowercase
[ptr] := c | 32;
ptr := @next ptr;
end if;
word := @next word;
end loop;
[ptr] := 0;
r := palindrome(&buf[0]);
end sub;
 
var tests: [uint8][] := {
"civic", "level", "racecar",
"A man, a plan, a canal: Panama",
"Egad, a base tone denotes a bad age",
"There is no spoon."
};
 
var i: @indexof tests := 0;
while i < @sizeof tests loop
print(tests[i]);
print(": ");
if palindrome(tests[i]) == 1 then
print("exact palindrome\n");
elseif inexact(tests[i]) == 1 then
print("inexact palindrome\n");
else
print("not a palindrome\n");
end if;
i := i + 1;
end loop;</syntaxhighlight>
 
{{out}}
 
<pre>civic: exact palindrome
level: exact palindrome
racecar: exact palindrome
A man, a plan, a canal: Panama: inexact palindrome
Egad, a base tone denotes a bad age: inexact palindrome
There is no spoon.: not a palindrome</pre>
 
 
=={{header|Crystal}}==
===Declarative===
<syntaxhighlight lang="ruby">
def palindrome(s)
s == s.reverse
end
</syntaxhighlight>
 
===Imperative===
<syntaxhighlight lang="ruby">
def palindrome_imperative(s) : Bool
mid = s.size // 2
last = s.size - 1
(0...mid).each do |i|
if s[i] != s[last - i]
return false
end
end
 
true
end
</syntaxhighlight>
 
Also
 
<syntaxhighlight lang="ruby">def palindrome_2(s)
mid = s.size // 2
mid.times { |j| return false if s[j] != s[-1 - j] }
true
end</syntaxhighlight>
 
Performance comparison
<syntaxhighlight lang="ruby">
require "benchmark"
Benchmark.ips do |x|
x.report("declarative") { palindrome("hannah") }
x.report("imperative1") { palindrome_imperative("hannah")}
x.report("imperative2") { palindrome_2("hannah")}
end
</syntaxhighlight>
 
<pre>declarative 45.45M ( 22.00ns) (±11.16%) 32.0B/op fastest
imperative1 35.49M ( 28.18ns) (± 2.82%) 0.0B/op 1.28× slower
imperative2 40.73M ( 24.55ns) (± 3.82%) 0.0B/op 1.12× slower</pre>
 
=={{header|D}}==
===High-level 32-bit Unicode Version===
<langsyntaxhighlight lang="d">import std.traits, std.algorithm;
 
bool isPalindrome1(C)(in C[] s) pure /*nothrow*/
Line 842 ⟶ 1,719:
assert(pali("ingirumimusnocteetconsumimurigni"));
assert(pali("salàlas"));
}</langsyntaxhighlight>
 
===Mid-level 32-bit Unicode Version===
<langsyntaxhighlight lang="d">import std.traits;
 
bool isPalindrome2(C)(in C[] s) pure if (isSomeChar!C) {
Line 870 ⟶ 1,747:
assert(pali("ingirumimusnocteetconsumimurigni"));
assert(pali("salàlas"));
}</langsyntaxhighlight>
 
===Low-level 32-bit Unicode Version===
<langsyntaxhighlight lang="d">import std.stdio, core.exception, std.traits;
 
// assume alloca() to be pure for this program
Line 911 ⟶ 1,788:
assert(pali("ingirumimusnocteetconsumimurigni"));
assert(pali("salàlas"));
}</langsyntaxhighlight>
 
===Low-level ASCII Version===
<langsyntaxhighlight lang="d">bool isPalindrome4(in string str) pure nothrow {
if (str.length == 0) return true;
immutable(char)* s = str.ptr;
Line 936 ⟶ 1,813:
assert(pali("ingirumimusnocteetconsumimurigni"));
//assert(pali("salàlas"));
}</langsyntaxhighlight>
 
=={{header|Dart}}==
 
<langsyntaxhighlight lang="dartlang">
bool isPalindrome(String s){
for(int i = 0; i < s.length/2;i++){
Line 948 ⟶ 1,825:
return true;
}
</syntaxhighlight>
</lang>
 
=={{header|Delphi}}==
<syntaxhighlight lang="delphi">uses
SysUtils, StrUtils;
 
function IsPalindrome(const aSrcString: string): Boolean;
begin
Result := SameText(aSrcString, ReverseString(aSrcString));
end;</syntaxhighlight>
 
=={{header|Dyalect}}==
 
<syntaxhighlight lang="dyalect">func isPalindrom(str) {
str == str.Reverse()
}
 
print(isPalindrom("ingirumimusnocteetconsumimurigni"))</syntaxhighlight>
 
=={{header|Déjà Vu}}==
 
<langsyntaxhighlight lang="dejavu">palindrome?:
local :seq chars
local :len-seq -- len seq
Line 962 ⟶ 1,856:
 
!. palindrome? "ingirumimusnocteetconsumimurigni"
!. palindrome? "nope"</langsyntaxhighlight>
{{out}}
<pre>true
Line 973 ⟶ 1,867:
The for loop syntax is <code>for <var>key pattern</var> => <var>value pattern</var> in <var>collection</var> { ... }</code>, <code>?</code> imposes an additional boolean condition on a pattern (it may be read “''such that''”), and if the pattern does not match in a for loop then the iteration is skipped, so false is returned only if <code>upper[last - i] != c</code>.
 
<langsyntaxhighlight lang="e">def isPalindrome(string :String) {
def upper := string.toUpperCase()
def last := upper.size() - 1
Line 980 ⟶ 1,874:
}
return true
}</langsyntaxhighlight>
 
=={{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}}==
<langsyntaxhighlight lang="lisp">
;; returns #t or #f
(define (palindrome? string)
Line 992 ⟶ 1,910:
;;(let ((string (string-replace string "/\ /" "" "g")))
;;(equal? (string->list string) (reverse (string->list string)))))
</syntaxhighlight>
</lang>
 
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
<lang Eiffel>
is_palindrome (a_string: STRING): BOOLEAN
-- Is `a_string' a palindrome?
Line 1,014 ⟶ 1,932:
end
end
</syntaxhighlight>
</lang>
 
=={{header|Ela}}==
 
<langsyntaxhighlight lang="ela">open list string
 
isPalindrome xs = xs == reverse xs
isPalindrome <| toList "ingirumimusnocteetconsumimurigni"
</syntaxhighlight>
</lang>
 
Function <code>reverse</code> is taken from list module and is defined as:
 
<langsyntaxhighlight lang="ela">reverse = foldl (flip (::)) (nil xs)
 
foldl f z (x::xs) = foldl f (f z x) xs
foldl _ z [] = z
</syntaxhighlight>
</lang>
 
=={{header|Elixir}}==
<langsyntaxhighlight lang="elixir">
defmodule PalindromeDetection do
def is_palindrome(str), do: str == String.reverse(str)
end
</syntaxhighlight>
</lang>
Note: Because of Elixir's strong Unicode support, this even supports graphemes:
<pre>
Line 1,047 ⟶ 1,965:
true
</pre>
 
=={{header|Elm}}==
<langsyntaxhighlight lang="elm">import String exposing (reverse, length)
import Html exposing (Html, Attribute, text, div, input)
import Html.Attributes exposing (placeholder, value, style)
Line 1,092 ⟶ 2,011:
, ("font-size", "1em")
, ("text-align", "left")
]</langsyntaxhighlight>
 
Link to live demo: http://dc25.github.io/palindromeDetectionElm/
 
=={{header|Emacs Lisp}}==
<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}}==
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( palindrome ).
 
Line 1,116 ⟶ 2,053:
 
display( String1, String2 ) -> io:fwrite( "Is ~p a palindrom? ~p~n", [String1, is_palindrome(String2)] ).
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,126 ⟶ 2,063:
 
=={{header|Euphoria}}==
<langsyntaxhighlight lang="euphoria">function isPalindrome(sequence s)
for i = 1 to length(s)/2 do
if s[i] != s[$-i+1] then
Line 1,133 ⟶ 2,070:
end for
return 1
end function</langsyntaxhighlight>
 
<syntaxhighlight lang="euphoria">
include std/sequence.e -- reverse
include std/console.e -- display
include std/text.e -- upper
include std/utils.e -- iif
 
IsPalindrome("abcba")
IsPalindrome("abcdef")
IsPalindrome("In girum imus nocte et consumimur igni")
 
procedure IsPalindrome(object s)
display("Is '[]' a palindrome? ",{s},0)
s = remove_all(' ',upper(s))
display(iif(equal(s,reverse(s)),"true","false"))
end procedure</syntaxhighlight>
{{out}}
<pre>
Is 'abcba' a palindrome? true
Is 'abcdef' a palindrome? false
Is 'In girum imus nocte et consumimur igni' a palindrome? true
</pre>
 
=={{header|Excel}}==
===LAMBDA===
 
Binding the following lambda expression to the name ISPALINDROME in the Name Manager for the Excel WorkBook:
 
(See [https://www.microsoft.com/en-us/research/blog/lambda-the-ultimatae-excel-worksheet-function/ LAMBDA: The ultimate Excel worksheet function])
 
{{Works with| Office 265 Betas 2021}}
<syntaxhighlight lang="lisp">ISPALINDROME
=LAMBDA(s,
LET(
lcs, FILTERP(
LAMBDA(c, " " <> c)
)(
CHARS(LOWER(s))
),
CONCAT(lcs) = CONCAT(REVERSE(lcs))
)
)</syntaxhighlight>
 
and assuming that the following generic lambdas are also bound to the names CHARS, FILTERP, and REVERSE in the Name Manager for the active WorkBook:
 
<syntaxhighlight lang="lisp">CHARS
=LAMBDA(s,
MID(s, ROW(INDIRECT("1:" & LEN(s))), 1)
)
 
 
FILTERP
=LAMBDA(p,
LAMBDA(xs,
FILTER(xs, p(xs))
)
)
 
 
REVERSE
=LAMBDA(xs,
LET(
n, ROWS(xs),
SORTBY(
xs,
SEQUENCE(n, 1, n, -1)
)
)
)</syntaxhighlight>
{{Out}}
{| class="wikitable"
|-
|||style="text-align:right; font-family:serif; font-style:italic; font-size:120%;"|fx
! colspan="2" style="text-align:left; vertical-align: bottom; font-family:Arial, Helvetica, sans-serif !important;"|=ISPALINDROME(A2)
|- style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff;"
|
| A
| B
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 1
| style="text-align:right; font-weight:bold" | Test string
| style="text-align:left; font-weight:bold" | Is palindrome ?
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 2
| style="text-align:right;" | In girum imus nocte et consumimur igni
| style="text-align:left; background-color:#cbcefb;" | TRUE
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 3
| style="text-align:right;" | abban
| style="text-align:left" | FALSE
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 4
| style="text-align:right;" | abba
| style="text-align:left" | TRUE
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 5
| style="text-align:right;" | aba
| style="text-align:left" | TRUE
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 6
| style="text-align:right; f" | ab
| style="text-align:left" | FALSE
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 7
| style="text-align:right;" | a
| style="text-align:left" | TRUE
|}
 
=={{header|F Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">let isPalindrome (s: string) =
let arr = s.ToCharArray()
arr = Array.rev arr</langsyntaxhighlight>
 
Examples:
<langsyntaxhighlight lang="fsharp">isPalindrome "abcba"
val it : bool = true
isPalindrome ("In girum imus nocte et consumimur igni".Replace(" ", "").ToLower());;
val it : bool = true
isPalindrome "abcdef"
val it : bool = false</langsyntaxhighlight>
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: kernel sequences ;
: palindrome? ( str -- ? ) dup reverse = ;</langsyntaxhighlight>
 
=={{header|Falcon}}==
'''VBA/Python programmer's approach not sure if it's the most falconic way'''
<syntaxhighlight lang="falcon">
/* created by Aykayayciti Earl Lamont Montgomery
April 9th, 2018 */
 
function is_palindrome(a)
a = strUpper(a).replace(" ", "")
b = a[-1:0]
return b == a
end
 
a = "mom"
> is_palindrome(a)
</syntaxhighlight>
{{out}}
<pre>
true
[Finished in 1.7s]
</pre>
 
'''more falconic'''
<syntaxhighlight lang="falcon">
/* created by Aykayayciti Earl Lamont Montgomery
April 9th, 2018 */
 
b = "mom"
> strUpper(b).replace(" ", "") == strUpper(b[-1:0]) ? "Is a palindrome" : "Is not a palindrome"
</syntaxhighlight>
{{out}}
<pre>
Is a palindrome
[Finished in 1.5s]
</pre>
 
=={{header|Fantom}}==
 
<langsyntaxhighlight lang="fantom">
class Palindrome
{
Line 1,175 ⟶ 2,254:
}
}
</syntaxhighlight>
</lang>
 
=={{header|FBSL}}==
 
<langsyntaxhighlight lang="qbasic">#APPTYPE CONSOLE
 
FUNCTION stripNonAlpha(BYVAL s AS STRING) AS STRING
Line 1,206 ⟶ 2,285:
 
PAUSE
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,215 ⟶ 2,294:
 
=={{header|Forth}}==
<langsyntaxhighlight lang="forth">: first over c@ ;
: last >r 2dup + 1- c@ r> swap ;
: palindrome? ( c-addr u -- f )
Line 1,223 ⟶ 2,302:
1 /string 1-
again ;
</syntaxhighlight>
</lang>
 
FIRST and LAST are once-off words that could be beheaded immediately afterwards.
Line 1,229 ⟶ 2,308:
The horizontal formatting highlights the parallel code - and potential factor;
a library of many string tests like this could have ?SUCCESS and ?FAIL .
 
 
'''Below is a separate Forth program that detects palindrome phrases as well as single word palindromes. It was programmed using gforth.'''
 
<syntaxhighlight lang="forth">
variable temp-addr
 
: valid-char? ( addr1 u -- f ) ( check for valid character )
+ dup C@ 48 58 within
over C@ 65 91 within or
swap C@ 97 123 within or ;
 
: >upper ( c1 -- c2 )
dup 97 123 within if 32 - then ;
 
: strip-input ( addr1 u -- addr2 u ) ( Strip characters, then copy stripped string to temp-addr )
pad temp-addr !
temp-addr @ rot rot 0 do dup I 2dup valid-char? if
+ C@ >upper temp-addr @ C! 1 temp-addr +!
else 2drop
then loop drop temp-addr @ pad - ;
 
: get-phrase ( -- addr1 u )
." Type a phrase: " here 1024 accept here swap -trailing cr ;
 
: position-phrase ( addr1 u -- addr1 u addr2 u addr1 addr2 u )
temp-addr @ over 2over 2over drop swap ;
 
: reverse-copy ( addr1 addr2 u -- addr1 addr2 )
0 do over I' 1- I - + over I + 1 cmove loop 2drop ;
 
: palindrome? ( -- )
get-phrase strip-input position-phrase reverse-copy compare 0= if
." << Valid >> Palindrome."
else ." << Not >> a Palindrome."
then cr ;
</syntaxhighlight>
 
Example:
 
palindrome?<br>
Type a phrase: A man, a plan, a cat, a ham, a yak, a yam, a hat, a canal-Panama!
 
<< Valid >> Palindrome.
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">program palindro
 
implicit none
Line 1,245 ⟶ 2,368:
print *, is_palindro("last test")
 
contains</langsyntaxhighlight>
 
'''Non-recursive'''
 
<langsyntaxhighlight lang="fortran">! non-recursive
function is_palindro(t)
logical :: is_palindro
Line 1,274 ⟶ 2,397:
forall(i=1:len(t)) s(len(t)-i+1:len(t)-i+1) = t(i:i)
isp = ( s == t )
end function is_palindro2</langsyntaxhighlight>
 
'''Recursive'''
<langsyntaxhighlight lang="fortran"> recursive function is_palindro_r (t) result (isp)
 
implicit none
Line 1,285 ⟶ 2,408:
isp = len (t) == 0 .or. t (: 1) == t (len (t) :) .and. is_palindro_r (t (2 : len (t) - 1))
 
end function is_palindro_r</langsyntaxhighlight>
 
<syntaxhighlight lang ="fortran">end program palindro</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight FreeBASIClang="freebasic">' version 20-06-2015
' compile with: fbc -s console "filename".bas
 
Line 1,365 ⟶ 2,488:
Print : Print : Print "Hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre> reverse(test) = FALSE
Line 1,373 ⟶ 2,496:
 
=={{header|Frink}}==
This version will even work with upper-plane Unicode characters. Many implementationslanguages will not work correctly with upper-plane Unicode characters because they are represented as Unicode "surrogate pairs" which are represented as two characters in a UTF-16 stream. In addition, Frink uses a ''grapheme''-based reverse, which allows the algorithm below to operate on combined sequences of Unicode characters.
 
For example, the string "og\u0308o" represents an o, a g with combining diaeresis, followed by the letter o. Or, in other words, "og̈o". Note that while there are four Unicode codepoints, only three "graphemes" are displayed. Using Frink's smart "reverse" function preserves these combined graphemes and detects them correctly as palindromes.
<lang frink>isPalindrome[x] := x == reverse[x]
 
</lang>
<syntaxhighlight lang="frink">isPalindrome[x] := x == reverse[x]
</syntaxhighlight>
 
Test in Frink with upper-plane Unicode:
<langsyntaxhighlight lang="frink">isPalindrome["x\u{1f638}x"]</langsyntaxhighlight>
 
<code>
true
</code>
 
 
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
 
local fn IsCleanStringPalindrome( testStr as CFStringRef ) as BOOL
NSUInteger i
BOOL result = NO
NSUInteger strLen = len(testStr)
for i = 0 to strLen / 2
if ( fn StringCharacterAtIndex( testStr, i ) != fn StringCharacterAtIndex( testStr, strLen -i -1 ) )
result = NO
exit fn
end if
next
result = YES
end fn = result
 
local fn IsDirtyStringPalindrome( dirtyStr as CFStringRef )
BOOL result = NO
CFStringRef tempStr
CFStringRef lowerCaseStr = fn StringLowercaseString( dirtyStr )
CFStringRef removeStr = @"!\"#$%&'()*+,-./:;<=>?@[]^_ {|}~"
NSUInteger i, count = len(removeStr)
tempStr = lowerCaseStr
for i = 0 to count -1
CFStringRef chrStr = fn StringWithFormat( @"%c", fn StringCharacterAtIndex( removeStr, i ) )
tempStr = fn StringByReplacingOccurrencesOfString( tempStr, chrStr, @"" )
next
result = fn IsCleanStringPalindrome( tempStr )
end fn = result
 
 
local fn PalindromeTest( testStr as CFStringRef )
BOOL result = NO
result = fn IsCleanStringPalindrome( testStr )
if ( result == YES )
NSLog( @"%17s : %@", fn StringUTF8String( @"Clean palindrome" ), testStr ) : exit fn
else
result = fn IsDirtyStringPalindrome( testStr )
if ( result == YES )
NSLog( @"%17s : %@", fn StringUTF8String( @"Dirty palindrome" ), testStr ) : exit fn
else
NSLog( @"%17s : %@", fn StringUTF8String( @"Not a palindrome" ), testStr )
end if
end if
end fn
 
fn PalindromeTest( @"racecar" )
fn PalindromeTest( @"level" )
fn PalindromeTest( @"rosetta" )
fn PalindromeTest( @"rotavator" )
fn PalindromeTest( @"13231+464+989=989+464+13231" )
fn PalindromeTest( @"Was it a car or a cat I saw?" )
fn PalindromeTest( @"Did Hannah see bees? Hannah did." )
fn PalindromeTest( @"This sentence is not a palindrome." )
fn PalindromeTest( @"123 456 789 897 654 321" )
fn PalindromeTest( @"123 456 789 987 654 321" )
fn PalindromeTest( @"Radar" )
fn PalindromeTest( @"abba" )
fn PalindromeTest( @"boom " )
fn PalindromeTest( @"radar" )
fn PalindromeTest( @"civic" )
fn PalindromeTest( @"great" )
fn PalindromeTest( @"Madam, I'm Adam." )
fn PalindromeTest( @"salàla" )
fn PalindromeTest( @"A man, a plan, a canal: Panama" )
fn PalindromeTest( @"a man a plan a canal panama" )
fn PalindromeTest( @"Egad, a base tone denotes a bad age" )
fn PalindromeTest( @"In girum imus nocte et consumimur igni" )
fn PalindromeTest( @"sees" )
fn PalindromeTest( @"solo" )
fn PalindromeTest( @"solos" )
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
Clean palindrome : racecar
Clean palindrome : level
Not a palindrome : rosetta
Clean palindrome : rotavator
Clean palindrome : 13231+464+989=989+464+13231
Dirty palindrome : Was it a car or a cat I saw?
Dirty palindrome : Did Hannah see bees? Hannah did.
Not a palindrome : This sentence is not a palindrome.
Not a palindrome : 123 456 789 897 654 321
Clean palindrome : 123 456 789 987 654 321
Dirty palindrome : Radar
Clean palindrome : abba
Not a palindrome : boom
Clean palindrome : radar
Clean palindrome : civic
Not a palindrome : great
Dirty palindrome : Madam, I'm Adam.
Not a palindrome : salàla
Dirty palindrome : A man, a plan, a canal: Panama
Dirty palindrome : a man a plan a canal panama
Dirty palindrome : Egad, a base tone denotes a bad age
Dirty palindrome : In girum imus nocte et consumimur igni
Clean palindrome : sees
Not a palindrome : solo
Clean palindrome : solos
</pre>
 
 
 
=={{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}}==
<langsyntaxhighlight lang="gap">ZapGremlins := function(s)
local upper, lower, c, i, n, t;
upper := "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Line 1,412 ⟶ 2,665:
t := ZapGremlins(s);
return t = Reversed(t);
end;</langsyntaxhighlight>
 
=={{header|GML}}==
<syntaxhighlight lang="go">
<lang go>
//Setting a var from an argument passed to the script
var str;
Line 1,430 ⟶ 2,684:
//returns true if the sequence is a palindrome else returns false
return (str == inv);
</syntaxhighlight>
</lang>
 
Palindrome detection using a [http://rosettacode.org/wiki/Loop/Downward_For#GML Downward For-Loop]
 
<syntaxhighlight lang="go">
<lang go>
 
//Remove everything except for letters and digits and convert the string to lowercase. source is what will be compared to str.
Line 1,446 ⟶ 2,700:
//Return if it is a palindrome.
return source == str;
</syntaxhighlight>
</lang>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package pal
 
func IsPal(s string) bool {
Line 1,460 ⟶ 2,714:
}
return true
}</langsyntaxhighlight>
 
This version works with Unicode,
 
<syntaxhighlight lang="go">
<lang go>
func isPalindrome(s string) bool {
runes := []rune(s)
Line 1,474 ⟶ 2,728:
}
return true
}</langsyntaxhighlight>
 
Or using more slicing,
 
<syntaxhighlight lang="go">
<lang go>
func isPalindrome(s string) bool {
runes := []rune(s)
Line 1,488 ⟶ 2,742:
}
return true
}</langsyntaxhighlight>
 
=={{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 1,494 ⟶ 2,767:
 
Solution:
<langsyntaxhighlight lang="groovy">def isPalindrome = { String s ->
s == s?.reverse()
}</langsyntaxhighlight>
 
Test program:
<langsyntaxhighlight lang="groovy">println isPalindrome("")
println isPalindrome("a")
println isPalindrome("abcdefgfedcba")
println isPalindrome("abcdeffedcba")
println isPalindrome("abcedfgfedcb")</langsyntaxhighlight>
 
{{out}}
Line 1,517 ⟶ 2,790:
 
Solution:
<langsyntaxhighlight lang="groovy">def isPalindrome = { String s ->
def n = s.size()
n < 2 || s[0..<n/2] == s[-1..(-n/2)]
}</langsyntaxhighlight>
 
Test program and output are the same.
Line 1,528 ⟶ 2,801:
 
Solution follows the [[#C|C palindrome_r]] recursive solution:
<langsyntaxhighlight lang="groovy">def isPalindrome
isPalindrome = { String s ->
def n = s.size()
n < 2 || (s[0] == s[n-1] && isPalindrome(s[1..<(n-1)]))
}</langsyntaxhighlight>
 
Test program and output are the same.
Line 1,543 ⟶ 2,816:
A string is a palindrome if reversing it we obtain the same string.
 
<langsyntaxhighlight lang="haskell">is_palindrome x = x == reverse x</langsyntaxhighlight>
 
Or, applicative and point-free, with some pre-processing of data (shedding white space and upper case):
 
<syntaxhighlight lang="haskell">import Data.Bifunctor (second)
import Data.Char (toLower)
 
------------------- PALINDROME DETECTION -----------------
 
isPalindrome :: Eq a => [a] -> Bool
isPalindrome = (==) <*> reverse
 
-- Or, comparing just the leftward characters with
-- with a reflection of just the rightward characters.
 
isPal :: String -> Bool
isPal s =
let (q, r) = quotRem (length s) 2
in uncurry (==) $
second (reverse . drop r) $ splitAt q s
 
--------------------------- TEST -------------------------
main :: IO ()
main =
mapM_ putStrLn $
(showResult <$> [isPalindrome, isPal])
<*> fmap
prepared
[ "",
"a",
"ab",
"aba",
"abba",
"In girum imus nocte et consumimur igni"
]
 
prepared :: String -> String
prepared cs = [toLower c | c <- cs, ' ' /= c]
 
showResult f s = (show s) <> " -> " <> show (f s)</syntaxhighlight>
{{Out}}
<pre>"" -> True
"a" -> True
"ab" -> False
"aba" -> True
"abba" -> True
"ingirumimusnocteetconsumimurigni" -> True
"" -> True
"a" -> True
"ab" -> False
"aba" -> True
"abba" -> True
"ingirumimusnocteetconsumimurigni" -> True</pre>
 
 
'''Recursive'''
 
See the C palindrome_r code for an explanation of the concept used in this solution.,
though it may be better suited to indexed arrays than to linked lists.
 
(last is expensive, and entails multiplied recursions over the right hand side
of the remaining list here).
 
<langsyntaxhighlight lang="haskell">is_palindrome_r x | length x <= 1 = True
| head x == last x = is_palindrome_r . tail. init $ x
| otherwise = False</langsyntaxhighlight>
 
=={{header|HicEst}}==
{{incorrect|HicEst|The stripping of spaces and case conversion should be outside the palindrome detection.}}
 
<langsyntaxhighlight lang="hicest"> result = Palindrome( "In girum imus nocte et consumimur igni" ) ! returns 1
END
 
Line 1,572 ⟶ 2,902:
IF( Palindrome == 0 ) RETURN
ENDDO
END</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon">procedure main(arglist)
every writes(s := !arglist) do write( if palindrome(s) then " is " else " is not", " a palindrome.")
end</langsyntaxhighlight>
 
The following simple procedure uses the built-in reverse. Reverse creates a transient string which will get garbage collected.
<langsyntaxhighlight Iconlang="icon">procedure palindrome(s) #: return s if s is a palindrome
return s == reverse(s)
end</langsyntaxhighlight>
{{libheader|Icon Programming Library}}
 
Line 1,588 ⟶ 2,918:
 
This version uses positive and negative sub-scripting and works not only on strings but lists of strings, such as ["ab","ab"] or ["ab","x"] the first list would pass the test but the second wouldn't.
<langsyntaxhighlight Iconlang="icon">procedure palindrome(x) #: return x if s is x palindrome
local i
every if x[i := 1 to (*x+ 1)/2] ~== x[-i] then fail
return x
end</langsyntaxhighlight>
 
=={{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}}==
<langsyntaxhighlight lang="ioke">Text isPalindrome? = method(self chars == self chars reverse)</langsyntaxhighlight>
 
=={{header|J}}==
Line 1,601 ⟶ 2,943:
 
Reverse and match method
<langsyntaxhighlight lang="j">isPalin0=: -: |.</langsyntaxhighlight>
Example usage
<langsyntaxhighlight lang="j"> isPalin0 'ABBA'
1
isPalin0 -.&' ' tolower 'In girum imus nocte et consumimur igni'
1</langsyntaxhighlight>
 
'''Recursive'''
 
Tacit and explicit verbs:
<langsyntaxhighlight lang="j">isPalin1=: 0:`($:@(}.@}:))@.({.={:)`1:@.(1>:#)
 
isPalin2=: monad define
if. 1>:#y do. 1 return. end.
if. ({.={:)y do. isPalin2 }.}:y else. 0 end.
)</langsyntaxhighlight>
 
Note that while these recursive verbs are bulkier and more complicated, they are also several thousand times more inefficient than isPalin0.
 
<langsyntaxhighlight lang="j"> foo=: foo,|.foo=:2000$a.
ts=:6!:2,7!:2 NB. time and space required to execute sentence
ts 'isPalin0 foo'
Line 1,631 ⟶ 2,973:
1599.09 1164.23
'isPalin2 foo' %&ts 'isPalin0 foo'
3967.53 2627.04</langsyntaxhighlight>
 
=={{header|Jakt}}==
<syntaxhighlight lang="jakt">
fn is_palindrome(anon string: String) throws -> bool {
mut points: [u32] = []
for point in string.code_points() {
points.push(point)
}
 
mut i: usize = 0
while i < points.size() / 2 {
if points[i] != points[points.size() - 1 - i] {
return false
}
i++
}
return true
}
 
fn main() {
println("{}", is_palindrome("amanaplanacanalpanama"))
println("{}", is_palindrome("madamimadam"))
println("{}", is_palindrome("madamimddam"))
println("{}", is_palindrome("私は私"))
}
</syntaxhighlight>
 
=={{header|Java}}==
Line 1,637 ⟶ 3,005:
'''Non-Recursive'''
 
<langsyntaxhighlight lang="java">public static boolean pali(String testMe){
StringBuilder sb = new StringBuilder(testMe);
return testMe.equals(sb.reverse().toString());
}</langsyntaxhighlight>
 
'''Non-Recursive using indexes (supports upper-plane Unicode)'''
<syntaxhighlight lang="java">public static boolean isPalindrome(String input) {
for (int i = 0, j = input.length() - 1; i < j; i++, j--) {
char startChar = input.charAt(i);
char endChar = input.charAt(j);
 
// Handle surrogate pairs in UTF-16
if (Character.isLowSurrogate(endChar)) {
if (startChar != input.charAt(--j)) {
return false;
}
if (input.charAt(++i) != endChar) {
return false;
}
} else if (startChar != endChar) {
return false;
}
}
return true;
}</syntaxhighlight>
 
'''Recursive (this version does not work correctly with upper-plane Unicode)'''
 
<langsyntaxhighlight lang="java">public static boolean rPali(String testMe){
if(testMe.length()<=1){
return true;
Line 1,651 ⟶ 3,041:
}
return rPali(testMe.substring(1, testMe.length()-1));
}</langsyntaxhighlight>
 
'''Recursive using indexes (this version does not work correctly with upper-plane Unicode)'''
 
<langsyntaxhighlight lang="java">public static boolean rPali(String testMe){
int strLen = testMe.length();
return rPaliHelp(testMe, strLen-1, strLen/2, 0);
Line 1,669 ⟶ 3,059:
return rPaliHelp(testMe, strLen, testLen, index + 1);
}
</syntaxhighlight>
</lang>
 
'''Regular Expression'''
([http://stackoverflow.com/questions/3664881/how-does-this-java-regex-detect-palindromes source])
<langsyntaxhighlight lang="java">public static boolean pali(String testMe){
return testMe.matches("|(?:(.)(?<=(?=^.*?(\\1\\2?)$).*))+(?<=(?=^\\2$).*)");
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
<langsyntaxhighlight lang="javascript">function isPalindrome(str) {
return str === str.split("").reverse().join("");
}
 
console.log(isPalindrome("ingirumimusnocteetconsumimurigni"));</langsyntaxhighlight>
 
 
ES6 implementation
<langsyntaxhighlight lang="javascript">var isPal = str => str === str.split("").reverse().join("");</langsyntaxhighlight>
 
Or, ignoring spaces and variations in case:
 
<syntaxhighlight lang="javascript">(() => {
Or, adding a wrapper function prepare the test data:
 
<lang JavaScript>(function (strSample) {
 
// isPalindrome :: String -> Bool
letconst isPalindrome = s => {
const cs = filter(c => ' ' !== c, s.toLocaleLowerCase());
s.split('')
return cs.join('') === reverse(cs).join('');
.join('') === s};
 
 
// TEST -----------------------------------------------
const main = () =>
isPalindrome(
'In girum imus nocte et consumimur igni'
)
 
// GENERIC FUNCTIONS ----------------------------------
// TESTING
 
// lowerCaseNoSpacefilter :: String(a -> StringBool) -> [a] -> [a]
letconst lowerCaseNoSpacefilter = s(f, xs) => (
concatMap(c => c'string' !== 'typeof 'xs ? [c.toLowerCase()] : [],
s.split(''))xs
) : xs.joinsplit(''),
).filter(f);
 
// concatMap :: (a -> [b]) -> [a] -> [b]
concatMap = (f, xs) => [].concat.apply([], xs.map(f));
 
 
return isPalindrome(
lowerCaseNoSpace(strSample)
);
 
 
})("In girum imus nocte et consumimur igni");</lang>
 
// reverse :: [a] -> [a]
const reverse = xs =>
'string' !== typeof xs ? (
xs.slice(0).reverse()
) : xs.split('').reverse().join('');
 
// MAIN ---
return main();
})();</syntaxhighlight>
{{Out}}
<pre>true</pre>
 
=={{header|jq}}==
The definitional implementation would probably be fine except for very long strings:
<lang jq>def palindrome: explode as $in | ($in|reverse) == $in;</lang>
<syntaxhighlight lang="jq">
def palindrome: explode | reverse == .;
</syntaxhighlight>
So here is an implementation with a view to efficiency:
<syntaxhighlight lang="jq">
def isPalindrome:
length as $n
| explode as $in
| first(range(0; $n/2)
| select($in[.] != $in[$n - 1 - .]) )
// false
| not;
</syntaxhighlight>
'''Example''':
"salàlas" | palindrome
{{Out}}
true
 
=={{header|Jsish}}==
<syntaxhighlight lang="javascript">/* Palindrome detection, in Jsish */
function isPalindrome(str:string, exact:boolean=true) {
if (!exact) {
str = str.toLowerCase();
str = str.replace(/[ \t,;:!?.]/g, '');
}
return str === str.match(/./g).reverse().join('');
}
 
;isPalindrome('BUB');
;isPalindrome('CUB');
;isPalindrome('Bub');
;isPalindrome('Bub', false);
;isPalindrome('In girum imus nocte et consumimur igni', false);
;isPalindrome('A man, a plan, a canal; Panama!', false);
;isPalindrome('Never odd or even', false);
 
/*
=!EXPECTSTART!=
isPalindrome('BUB') ==> true
isPalindrome('CUB') ==> false
isPalindrome('Bub') ==> false
isPalindrome('Bub', false) ==> true
isPalindrome('In girum imus nocte et consumimur igni', false) ==> true
isPalindrome('A man, a plan, a canal; Panama!', false) ==> true
isPalindrome('Never odd or even', false) ==> true
=!EXPECTEND!=
*/</syntaxhighlight>
 
Most of that code is for testing, using echo mode lines (semicolon in column 1)
 
{{out}}
<pre>prompt$ jsish --U palindrome.jsi
isPalindrome('BUB') ==> true
isPalindrome('CUB') ==> false
isPalindrome('Bub') ==> false
isPalindrome('Bub', false) ==> true
isPalindrome('In girum imus nocte et consumimur igni', false) ==> true
isPalindrome('A man, a plan, a canal; Panama!', false) ==> true
isPalindrome('Never odd or even', false) ==> true
 
prompt$ jsish -u palindrome.jsi
[PASS] palindrome.jsi</pre>
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">palindrome(s) = s == reverse(s)</langsyntaxhighlight>
<b> Non-Recursive </b>
<langsyntaxhighlight lang="julia">
function palindrome(s)
len = length(s)
Line 1,743 ⟶ 3,194:
return true
end
</syntaxhighlight>
</lang>
<b> Recursive </b>
<langsyntaxhighlight lang="julia">
function palindrome(s)
len = length(s)
Line 1,755 ⟶ 3,206:
end
return false
end</langsyntaxhighlight>
 
=={{header|k}}==
<syntaxhighlight lang ="k">is_palindrome:{x~|x}</langsyntaxhighlight>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.2
 
/* These functions deal automatically with Unicode as all strings are UTF-16 encoded in Kotlin */
 
fun isExactPalindrome(s: String) = (s == s.reversed())
 
fun isInexactPalindrome(s: String): Boolean {
var t = ""
for (c in s) if (c.isLetterOrDigit()) t += c
t = t.toLowerCase()
return t == t.reversed()
}
 
fun main(args: Array<String>) {
val candidates = arrayOf("rotor", "rosetta", "step on no pets", "été")
for (candidate in candidates) {
println("'$candidate' is ${if (isExactPalindrome(candidate)) "an" else "not an"} exact palindrome")
}
println()
val candidates2 = arrayOf(
"In girum imus nocte et consumimur igni",
"Rise to vote, sir",
"A man, a plan, a canal - Panama!",
"Ce repère, Perec" // note: 'è' considered a distinct character from 'e'
)
for (candidate in candidates2) {
println("'$candidate' is ${if (isInexactPalindrome(candidate)) "an" else "not an"} inexact palindrome")
}
}</syntaxhighlight>
 
{{out}}
<pre>
'rotor' is an exact palindrome
'rosetta' is not an exact palindrome
'step on no pets' is an exact palindrome
'été' is an exact palindrome
 
'In girum imus nocte et consumimur igni' is an inexact palindrome
'Rise to vote, sir' is an inexact palindrome
'A man, a plan, a canal - Panama!' is an inexact palindrome
'Ce repère, Perec' is not an inexact palindrome
</pre>
 
=={{header|LabVIEW}}==
{{VI solution|LabVIEW_Palindrome_detection.png}}
 
=={{header|langur}}==
<syntaxhighlight lang="langur">val .ispal = fn .s: len(.s) > 0 and .s == reverse .s
 
val .tests = {
"": false,
"z": true,
"aha": true,
"αηα": true,
"αννα": true,
"αννασ": false,
"sees": true,
"seas": false,
"deified": true,
"solo": false,
"solos": true,
"amanaplanacanalpanama": true,
"a man a plan a canal panama": false, # true if we remove spaces
"ingirumimusnocteetconsumimurigni": true,
}
 
for .word in sort(keys .tests) {
val .foundpal = .ispal(.word)
writeln .word, ": ", .foundpal, if(.foundpal == .tests[.word]: ""; " (FAILED TEST)")
}</syntaxhighlight>
 
{{out}}
<pre>: false
a man a plan a canal panama: false
aha: true
amanaplanacanalpanama: true
deified: true
ingirumimusnocteetconsumimurigni: true
seas: false
sees: true
solo: false
solos: true
z: true
αηα: true
αννα: true
αννασ: false</pre>
 
=={{header|Lasso}}==
<langsyntaxhighlight Lassolang="lasso">define ispalindrome(text::string) => {
 
local(_text = string(#text)) // need to make copy to get rid of reference issues
Line 1,780 ⟶ 3,315:
ispalindrome('Hello World')
 
ispalindrome('A man, a plan, a canoe, pasta, heros, rajahs, a coloratura, maps, snipe, percale, macaroni, a gag, a banana bag, a tan, a tag, a banana bag again (or a camel), a crepe, pins, Spam, a rut, a Rolo, cash, a jar, sore hats, a peon, a canal – Panama!')</langsyntaxhighlight>
{{out}}
<pre>true
Line 1,787 ⟶ 3,322:
 
=={{header|Liberty BASIC}}==
<langsyntaxhighlight lang="lb">print isPalindrome("In girum imus nocte et consumimur igni")
print isPalindrome(removePunctuation$("In girum imus nocte et consumimur igni", "S"))
print isPalindrome(removePunctuation$("In girum imus nocte et consumimur igni", "SC"))
Line 1,808 ⟶ 3,343:
next i
removePunctuation$ = string$
end function</langsyntaxhighlight>
 
{{out}}
Line 1,818 ⟶ 3,353:
 
=={{header|LiveCode}}==
This implementation defaults to exact match, but has an optional parameter to do inexact.<langsyntaxhighlight LiveCodelang="livecode">function palindrome txt exact
if exact is empty or exact is not false then
set caseSensitive to true --default is false
Line 1,833 ⟶ 3,368:
end repeat
return revstr
end reverse</langsyntaxhighlight>
 
=={{header|Logo}}==
<langsyntaxhighlight lang="logo">to palindrome? :w
output equal? :w reverse :w
end</langsyntaxhighlight>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function ispalindrome(s) return s == string.reverse(s) end</langsyntaxhighlight>
 
=={{header|M4}}==
Line 1,847 ⟶ 3,382:
'''Non-recursive'''
This uses the <code>invert</code> from [[Reversing a string]].
<langsyntaxhighlight lang="m4">define(`palindrorev',`ifelse(`$1',invert(`$1'),`yes',`no')')dnl
palindrorev(`ingirumimusnocteetconsumimurigni')
palindrorev(`this is not palindrome')</langsyntaxhighlight>
 
'''Recursive'''
<langsyntaxhighlight lang="m4">define(`striptwo',`substr(`$1',1,eval(len(`$1')-2))')dnl
define(`cmplast',`ifelse(`striptwo(`$1')',,`yes',dnl
substr(`$1',0,1),substr(`$1',eval(len(`$1')-1),1),`yes',`no')')dnl
Line 1,858 ⟶ 3,393:
ifelse(eval(len(`$1')<1),1,`yes',cmplast(`$1'),`yes',`palindro(striptwo(`$1'))',`no')')dnl
palindro(`ingirumimusnocteetconsumimurigni')
palindro(`this is not palindrome')</langsyntaxhighlight>
 
=={{header|MACRO-11}}==
<syntaxhighlight lang="macro11"> .TITLE PALIN
.MCALL .GTLIN,.PRINT,.EXIT
PALIN:: .GTLIN #INBUF ; READ INPUT
MOV #INBUF,R0
TSTB (R0) ; END OF INPUT?
BEQ 3$
JSR PC,EPALIN ; CHECK (EXACT) PALINDROME
BNE 1$
.PRINT #4$
BR PALIN
1$: MOV #INBUF,R0 ; CHECK INEXACT PALINDROME
JSR PC,IPALIN
BNE 2$
.PRINT #5$
BR PALIN
2$: .PRINT #6$ ; NOT A PALINDROME AT ALL
BR PALIN
3$: .EXIT
4$: .ASCIZ /EXACT PALINDROME/
5$: .ASCIZ /INEXACT PALINDROME/
6$: .ASCIZ /NOT A PALINDROME/
.EVEN
; IS STRING AT R0 AN EXACT PALINDROME?
; ZERO FLAG SET IF TRUE
EPALIN: MOV R0,R1
1$: TSTB (R1)+ ; FIND END OF STRING
BNE 1$
DEC R1
2$: CMPB (R0)+,-(R1) ; SCAN BACKWARDS AND FORWARDS
BNE 4$ ; NOT PALINDROME?
CMP R0,R1 ; DONE YET?
BLT 2$
3$: CLR R1
4$: RTS PC
 
; IS STRING AT R0 AN INEXACT PALINDROME?
IPALIN: MOV #3$,R1 ; COPY TO BUFFER
BR 2$
1$: BICB #40,R2 ; MAKE UPPERCASE IF LETTER
CMPB R2,#101 ; < A = DISREGARD
BLT 2$
CMPB R2,#132 ; > Z = DISREGARD
BGT 2$
MOVB R2,(R1)+ ; STORE IN BUFFER
2$: MOVB (R0)+,R2 ; GET CHARACTER
BNE 1$ ; END?
CLRB (R1) ; ZERO TERMINATE BUFFER
MOV #3$,R0 ; NOW SEE IF RESULT IS EXACT PALINDROME
BR EPALIN
3$: .BLKB 200 ; BUFFER
 
INBUF: .BLKB 200
.END PALIN</syntaxhighlight>
{{out}}
<pre>.palin racecar
EXACT PALINDROME
 
.palin raceCAR
INEXACT PALINDROME
 
.palin rosetta
NOT A PALINDROME</pre>
 
=={{header|Maple}}==
Line 1,865 ⟶ 3,464:
This uses functions from Maple's built-in <code>StringTools</code> package.
 
<syntaxhighlight lang="maple">
<lang Maple>
with(StringTools):
 
Line 1,873 ⟶ 3,472:
 
IsPalindrome(LowerCase(DeleteSpace("In girum imus nocte et consumimur igni")));
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,884 ⟶ 3,483:
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Built-in function handling lists, numbers, and strings:
Custom functions:
<syntaxhighlight lang="mathematica">PalindromeQ</syntaxhighlight>
 
'''Non-recursive'''
 
<lang Mathematica>PalindromeQ[i_String] := StringReverse[i] == i</lang>
 
Test numbers:
 
PalindromeQ[i_Integer] := Reverse[IntegerDigits[i]] == IntegerDigits[i];
 
{{out|Examples}}
<pre>PalindromeQ["TNT"]
PalindromeRecQ["TNT"]
PalindromeQ["test"]
PalindromeQ["deified"]
PalindromeRecQ["test"]
PalindromeQ["deifiedsalálas"]
PalindromeQ["ingirumimusnocteetconsumimurigni"]</pre>
PalindromeRecQ["deified"]
PalindromeQ["sal&agrave;las"]
PalindromeRecQ["sal&agrave;las"]
PalindromeQ["ingirumimusnocteetconsumimurigni"]
PalindromeRecQ["ingirumimusnocteetconsumimurigni"]</pre>
 
Note that the code block doesn't correctly show the &agrave; in sal&agrave;las.
{{out}}
<pre>True
True
False
False
True
True
True
True
True
Line 1,921 ⟶ 3,500:
 
=={{header|MATLAB}}==
<langsyntaxhighlight MATLABlang="matlab">function trueFalse = isPalindrome(string)
trueFalse = all(string == fliplr(string)); %See if flipping the string produces the original string
Line 1,935 ⟶ 3,514:
end
end</langsyntaxhighlight>
 
{{out|Sample Usage}}
<langsyntaxhighlight MATLABlang="matlab">>> isPalindrome('In girum imus nocte et consumimur igni')
 
ans =
 
1
</syntaxhighlight>
</lang>
 
=={{header|Maxima}}==
<langsyntaxhighlight lang="maxima">palindromep(s) := block([t], t: sremove(" ", sdowncase(s)), sequal(t, sreverse(t)))$
 
palindromep("Sator arepo tenet opera rotas"); /* true */</langsyntaxhighlight>
 
=={{header|MAXScript}}==
Line 1,954 ⟶ 3,533:
'''Non-recursive'''
 
<langsyntaxhighlight lang="maxscript">fn isPalindrome s =
(
local reversed = ""
for i in s.count to 1 by -1 do reversed += s[i]
return reversed == s
)</langsyntaxhighlight>
 
'''Recursive'''
 
<langsyntaxhighlight lang="maxscript">fn isPalindrome_r s =
(
if s.count <= 1 then
Line 1,977 ⟶ 3,556:
isPalindrome_r (substring s 2 (s.count-2))
)
)</langsyntaxhighlight>
 
'''Testing'''
 
<langsyntaxhighlight lang="maxscript">local p = "ingirumimusnocteetconsumimurigni"
format ("'%' is a palindrome? %\n") p (isPalindrome p)
format ("'%' is a palindrome? %\n") p (isPalindrome_r p)</langsyntaxhighlight>
 
=={{header|min}}==
{{works with|min|0.19.3}}
<syntaxhighlight lang="min">(dup reverse ==) :palindrome?
(dup "" split reverse "" join ==) :str-palindrome?
 
"apple" str-palindrome? puts
"racecar" str-palindrome? puts
(a b c) palindrome? puts
(a b b a) palindrome? puts</syntaxhighlight>
{{out}}
<pre>
false
true
false
true
</pre>
 
=={{header|MiniScript}}==
<syntaxhighlight lang="miniscript">isPalindrome = function(s)
// convert to lowercase, and strip non-letters
stripped = ""
for c in s.lower
if c >= "a" and c <= "z" then stripped = stripped + c
end for
 
// check palindromity
mid = floor(stripped.len/2)
for i in range(0, mid)
if stripped[i] != stripped[-i - 1] then return false
end for
return true
end function
 
testStr = "Madam, I'm Adam"
answer = [testStr, "is"]
if not isPalindrome(testStr) then answer.push "NOT"
answer.push "a palindrome"
print answer.join</syntaxhighlight>
{{out}}
<pre>
Madam, I'm Adam is a palindrome
</pre>
 
=={{header|Mirah}}==
<langsyntaxhighlight lang="mirah">def reverse(s:string)
StringBuilder.new(s).reverse.toString()
end
Line 1,997 ⟶ 3,619:
puts palindrome?("Erik") # ==> false
puts palindrome?("palindroom-moordnilap") # ==> true
puts nil # ==> null</langsyntaxhighlight>
 
=={{header|ML}}==
==={{header|mLite}}===
<langsyntaxhighlight lang="ocaml">fun to_locase s = implode ` map (c_downcase) ` explode s
 
fun only_alpha s = implode ` filter (fn x = c_alphabetic x) ` explode s
Line 2,031 ⟶ 3,653:
println ` test (is_palin, "Lagerregal", true, "is a palindrome", "is NOT a palindrome");
println ` test (is_palin, "Ein Neger mit Gazelle zagt im Regen nie.", true, "is a palindrome", "is NOT a palindrome");
println ` test (is_palin, "something wrong", true, "is a palindrome", "is NOT a palindrome");</langsyntaxhighlight>
Output:
<pre>'In girum imus nocte, et consumimur igni' is a palindrome
Line 2,043 ⟶ 3,665:
 
==={{header|Standard ML}}===
<langsyntaxhighlight lang="sml">
fun palindrome s =
let val cs = explode s in
cs = rev cs
end
</syntaxhighlight>
</lang>
 
=={{header|MMIX}}==
<langsyntaxhighlight lang="mmix">argc IS $0
argv IS $1
 
Line 2,118 ⟶ 3,740:
1H TRAP 0,Fputs,StdOut % print
3H XOR $255,$255,$255
TRAP 0,Halt,0 % exit(0)</langsyntaxhighlight>
 
=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE Palindrome;
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT WriteString,ReadChar;
 
PROCEDURE IsPalindrome(str : ARRAY OF CHAR) : BOOLEAN;
VAR i,m : INTEGER;
VAR buf : ARRAY[0..63] OF CHAR;
BEGIN
i := 0;
m := HIGH(str) - 1;
WHILE i<m DO
IF str[i] # str[m-i] THEN
RETURN FALSE
END;
INC(i)
END;
RETURN TRUE
END IsPalindrome;
 
PROCEDURE Print(str : ARRAY OF CHAR);
VAR buf : ARRAY[0..63] OF CHAR;
BEGIN
FormatString("%s: %b\n", buf, str, IsPalindrome(str));
WriteString(buf)
END Print;
 
BEGIN
Print("");
Print("z");
Print("aha");
Print("sees");
Print("oofoe");
Print("deified");
Print("Deified");
Print("amanaplanacanalpanama");
Print("ingirumimusnocteetconsumimurigni");
 
ReadChar
END Palindrome.</syntaxhighlight>
 
=={{header|Modula-3}}==
<langsyntaxhighlight lang="modula3">MODULE Palindrome;
 
IMPORT Text;
Line 2,135 ⟶ 3,798:
RETURN TRUE;
END isPalindrome;
END Palindrome.</langsyntaxhighlight>
 
=={{header|Nanoquery}}==
<syntaxhighlight lang="nanoquery">def is_palindrome(s)
temp = ""
for char in s
if "abcdefghikjklmnopqrstuvwxyz" .contains. lower(char)
temp += lower(char)
end
end
 
return list(temp) = list(temp).reverse()
end</syntaxhighlight>
 
=={{header|Nemerle}}==
<langsyntaxhighlight Nemerlelang="nemerle">using System;
using System.Console;
using Nemerle.Utility.NString; //contains methods Explode() and Implode() which convert string -> list[char] and back
Line 2,153 ⟶ 3,828:
WriteLine("radar is a palindrome: {0}", IsPalindrome("radar"));
}
}</langsyntaxhighlight>
And a function to remove spaces and punctuation and convert to lowercase
<langsyntaxhighlight Nemerlelang="nemerle">Clean( text : string ) : string
{
def sepchars = Explode(",.;:-?!()' ");
Concat( "", Split(text, sepchars)).ToLower()
}</langsyntaxhighlight>
 
=={{header|NetRexx}}==
{{Trans|REXX}}
<langsyntaxhighlight lang="netrexx">
y='In girum imus nocte et consumimur igni'
 
Line 2,181 ⟶ 3,856:
/* and translate to uppercase. */
return x==x.reverse() /* returns 1 if exactly equal */
</syntaxhighlight>
</lang>
 
=={{header|NewLISP}}==
Works likewise for strings and for lists
<langsyntaxhighlight lang="lisp">
(define (palindrome? s)
(setq r s)
Line 2,194 ⟶ 3,869:
(define (palindrome? s)
(= s (reverse (copy s))))
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
The following program detects if UTF-8 strings are exact palindromes. If "exact" is set to "false", it ignores the white spaces and the differences of letter case to detect inexact palindromes. Differences in punctuation are still relevant.
<lang nim>proc reverse(s): string =
<syntaxhighlight lang="nim">import unicode
result = newString(s.len)
for i,c in s:
result[s.high - i] = c
 
proc isPalindrome(s): bool =
s == reverse(s)
 
echofunc isPalindrome("FoobooF"rseq: seq[Rune])</lang>: bool =
## Return true if a sequence of runes is a palindrome.
for i in 1..(rseq.len shr 1):
if rseq[i - 1] != rseq[^i]:
return false
result = true
 
 
func isPalindrome(str: string; exact = true): bool {.inline.} =
## Return true if a UTF-8 string is a palindrome.
## If "exact" is false, ignore white spaces and ignore case.
 
if exact:
result = str.toRunes.isPalindrome()
else:
var rseq: seq[Rune]
for rune in str.runes:
if not rune.isWhiteSpace:
rseq.add rune.toLower
result = rseq.isPalindrome()
 
 
when isMainModule:
 
proc check(s: string) =
var exact, inexact: bool
exact = s.isPalindrome()
if not exact:
inexact = s.isPalindrome(exact = false)
let txt = if exact: " is an exact palindrome."
elif inexact: " is an inexact palindrome."
else: " is not a palindrome."
echo '"', s, '"', txt
 
check "rotor"
check "été"
check "αννα"
check "salà las"
check "In girum imus nocte et consumimur igni"
check "Esope reste ici et se repose"
check "This is a palindrom"</syntaxhighlight>
 
{{out}}
<pre>"rotor" is an exact palindrome.
"été" is an exact palindrome.
"αννα" is an exact palindrome.
"salà las" is an inexact palindrome.
"In girum imus nocte et consumimur igni" is an inexact palindrome.
"Esope reste ici et se repose" is an inexact palindrome.
"This is a palindrom" is not a palindrome.</pre>
 
=={{header|Objeck}}==
<langsyntaxhighlight lang="objeck">
bundle Default {
class Test {
Line 2,229 ⟶ 3,949:
}
}
</syntaxhighlight>
</lang>
 
=={{header|OCaml}}==
 
<langsyntaxhighlight lang="ocaml">let is_palindrome s =
let l = String.length s in
let rec comp n =
n = 0 || (s.[l-n] = s.[n-1] && comp (n-1)) in
comp (l / 2)</langsyntaxhighlight>
 
and here a function to remove the white spaces in the string:
 
<langsyntaxhighlight lang="ocaml">let rem_space str =
let len = String.length str in
let res = StringBytes.create len in
let rec aux i j =
if i >= len
then (StringBytes.subsub_string res 0 j)
else match str.[i] with
| ' ' | '\n' | '\t' | '\r' ->
aux (i+1) (j)
| _ ->
resBytes.[j]set <-res j str.[i];
aux (i+1) (j+1)
in
aux 0 0</lang>
</syntaxhighlight>
 
and to make the test case insensitive, just use the function <tt>String.lowercaselowercase_ascii</tt>.
 
 
=={{header|Oforth}}==
 
<lang Oforth>String method: isPalindrome self reverse self == ;</lang>
 
=={{header|Octave}}==
'''Recursive'''
<langsyntaxhighlight lang="octave">function v = palindro_r(s)
if ( length(s) == 1 )
v = true;
Line 2,278 ⟶ 3,994:
v = false;
endif
endfunction</langsyntaxhighlight>
 
'''Non-recursive'''
<langsyntaxhighlight lang="octave">function v = palindro(s)
v = all( (s == s(length(s):-1:1)) == 1);
endfunction</langsyntaxhighlight>
 
'''Testing'''
<langsyntaxhighlight lang="octave">palindro_r("ingirumimusnocteetconsumimurigni")
palindro("satorarepotenetoperarotas")</langsyntaxhighlight>
 
=={{header|Oforth}}==
 
<syntaxhighlight lang="oforth">String method: isPalindrome self reverse self == ;</syntaxhighlight>
 
=={{header|Ol}}==
<syntaxhighlight lang="scheme">
; simple case - only lowercase letters
(define (palindrome? str)
(let ((l (string->runes str)))
(equal? l (reverse l))))
 
(print (palindrome? "ingirumimusnocteetconsumimurigni"))
; ==> #true
(print (palindrome? "thisisnotapalindrome"))
; ==> #false
 
 
; complex case - with ignoring letter case and punctuation
(define (alpha? x)
(<= #\a x #\z))
(define (lowercase x)
(if (<= #\A x #\Z)
(- x (- #\A #\a))
x))
 
(define (palindrome? str)
(let ((l (filter alpha? (map lowercase (string->runes str)))))
(equal? l (reverse l))))
 
(print (palindrome? "A man, a plan, a cat, a ham, a yak, a yam, a hat, a canal-Panama!"))
; ==> #true
(print (palindrome? "This is not a palindrome"))
; ==> #false
</syntaxhighlight>
 
=={{header|Oz}}==
<langsyntaxhighlight lang="oz">fun {IsPalindrome S}
{Reverse S} == S
end</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">ispal(s)={
s=Vec(s);
for(i=1,#v\2,
Line 2,301 ⟶ 4,052:
);
1
};</langsyntaxhighlight>
 
A version for numbers:
{{works with|PARI/GP|2.6.0 and above}}
<langsyntaxhighlight lang="parigp">ispal(s)={
my(d=digits(n));
for(i=1,#d\2,
Line 2,311 ⟶ 4,062:
);
1
};</langsyntaxhighlight>
 
=={{header|Pascal}}==
{{works with|Free Pascal}}
<langsyntaxhighlight lang="pascal">program Palindro;
 
{ RECURSIVE }
Line 2,337 ⟶ 4,088:
else
is_palindro := false
end;</langsyntaxhighlight>
 
<langsyntaxhighlight lang="pascal">procedure test_r(s : String; r : Boolean);
begin
write('"', s, '" is ');
Line 2,357 ⟶ 4,108:
test_r(s1, is_palindro(s1));
test_r(s2, is_palindro(s2))
end.</langsyntaxhighlight>
 
<syntaxhighlight lang="pascal">program PalindromeDetection;
var
input, output: string;
s: char; i: integer;
begin
writeln('write down your input:');
readln(input);
output:='';
for i:=1 to length(input) do
begin
s:=input[i];
output:=s+output;
end;
writeln('');
if(input=output)then
writeln('input was palindrome')
else
writeln('input was not palindrome');
end.</syntaxhighlight>
 
=={{header|Perl}}==
Line 2,373 ⟶ 4,144:
before you call these functions.
 
<langsyntaxhighlight lang="perl"># Palindrome.pm
package Palindrome;
 
Line 2,409 ⟶ 4,180:
{
(@_ ? shift : $_) =~ /^(.?|(.)(?1)\2)$/ + 0
}</langsyntaxhighlight>
 
This example shows how to use the functions:
 
<langsyntaxhighlight lang="perl"># pbench.pl
use strict;
use warnings;
Line 2,435 ⟶ 4,206:
palindrome_r => sub { palindrome_r $latin },
palindrome_e => sub { palindrome_e $latin },
});</langsyntaxhighlight>
 
{{out}} on a machine running Perl 5.10.1 on amd64-openbsd:
Line 2,462 ⟶ 4,233:
The Perl regular expression engine recursed twice as fast as the Perl interpreter.
 
=={{header|Perl 6Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang perl6>subset Palindrom of Str where {
<span style="color: #008080;">function</span> <span style="color: #000000;">is_palindrome</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
.flip eq $_ given .comb(/\w+/).join.lc
<span style="color: #008080;">return</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">==</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
}
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
my @tests = q:to/END/.lines;
<span style="color: #0000FF;">?</span><span style="color: #000000;">is_palindrome</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"rotator"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- prints 1</span>
A man, a plan, a canal: Panama.
<span style="color: #0000FF;">?</span><span style="color: #000000;">is_palindrome</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"tractor"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- prints 0</span>
My dog has fleas
Madam, I'm Adam.
<span style="color: #008080;">constant</span> <span style="color: #000000;">punctuation</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">" `~!@#$%^&*()-=_+[]{}\\|;:',.&lt;&gt;/?"</span><span style="color: #0000FF;">,</span>
1 on 1
<span style="color: #000000;">nulls</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">punctuation</span><span style="color: #0000FF;">))</span>
In girum imus nocte et consumimur igni
END
<span style="color: #008080;">function</span> <span style="color: #000000;">extra_credit</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">utf8_to_utf32</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">lower</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">substitute_all</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">punctuation</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nulls</span><span style="color: #0000FF;">)))</span>
for @tests { say $_ ~~ Palindrom, "\t", $_ }</lang>
<span style="color: #008080;">return</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">==</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #000080;font-style:italic;">-- these all print 1 (true)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">extra_credit</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Madam, I'm Adam."</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">extra_credit</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"A man, a plan, a canal: Panama!"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">extra_credit</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"In girum imus nocte et consumimur igni"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">extra_credit</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"人人為我,我為人人"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">extra_credit</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Я иду с мечем, судия"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">extra_credit</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"아들딸들아"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">extra_credit</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"가련하시다 사장집 아들딸들아 집장사 다시 하련가"</span><span style="color: #0000FF;">)</span>
<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
<pre>True A man, a plan, a canal: Panama.
boom : palindrome? false
False My dog has fleas
radar : palindrome? true
True Madam, I'm Adam.
civic : palindrome? true
False 1 on 1
great : palindrome? false
True In girum imus nocte et consumimur igni
In girum imus nocte, et consumimur igni
</pre>
This is an inexact palindrome!
 
=={{header|Phix}}==
<lang Phix>function is_palindrome(sequence s)
return s==reverse(s)
end function
 
=== Press any key to exit ===</pre>
?is_palindrome(lower(substitute("In girum imus nocte et consumimur igni"," ",""))) -- prints 1</lang>
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php"><?php
function is_palindrome($string) {
return $string == strrev($string);
}
?></langsyntaxhighlight>
 
Regular expression-based solution ([http://www.polygenelubricants.com/2010/09/matching-palindromes-in-pcre-regex.html source])
<langsyntaxhighlight lang="php"><?php
function is_palindrome($string) {
return preg_match('/^(?:(.)(?=.*(\1(?(2)\2|))$))*.?\2?$/', $string);
}
?></langsyntaxhighlight>
 
=={{header|Picat}}==
<syntaxhighlight lang="picat">go =>
Tests = ["In girum imus nocte et consumimur igni",
"this is a non palindrome string",
"anna ABcdcBA anna",
"anna ABcdcBA annax",
"A man, a plan, a canoe, pasta, heros, rajahs" ++
"a coloratura, maps, snipe, percale, macaroni, " ++
"a gag, a banana bag, a tan, a tag, " ++
"a banana bag again (or a camel), a crepe, pins, " ++
"Spam, a rut, a Rolo, cash, a jar, sore hats, " ++
"a peon, a canal - Panama!",
10,
111111,
12221,
9384212,
10.01
],
 
foreach(Test in Tests)
if is_palindrome(Test) then
println([Test, "exact palindrome"])
elseif is_palindrome_inexact(Test) then
println([Test, "inexact palindrome"])
else
println([Test, "no"])
end
end,
nl.
 
% Detect palindromes for strings (and numbers).
is_palindrome(N), number(N) => is_palindrome(N.to_string()).
is_palindrome(S) => S == S.reverse().
 
% Detect inexact palindromes.
is_palindrome_inexact(N), number(N) => is_palindrome_inexact(N.to_string()).
is_palindrome_inexact(S) =>
is_palindrome(strip(S)).
 
 
% convert to lowercase and
% skips punctuation and white space.
strip(S) = [C : C in S.to_lowercase(),
not C.membchk("!?,.;-_ \t\n()[]{}")].</syntaxhighlight>
 
{{out}}
<pre>[In girum imus nocte et consumimur igni,inexact palindrome]
[this is a non palindrome string,no]
[anna ABcdcBA anna,exact palindrome]
[anna ABcdcBA annax,no]
[A man, a plan, a canoe, pasta, heros, rajahsa coloratura, maps, snipe, percale, macaroni, a gag, a banana bag, a tan, a tag, a banana bag again (or a camel), a crepe, pins, Spam, a rut, a Rolo, cash, a jar, sore hats, a peon, a canal - Panama!,inexact palindrome]
[10,no]
[11,exact palindrome]
[111111,exact palindrome]
[12221,exact palindrome]
[9384212,no]
[10.01,exact palindrome]</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de palindrome? (S)
(= (setq S (chop S)) (reverse S)) )</langsyntaxhighlight>
{{out}}
<pre>: (palindrome? "ingirumimusnocteetconsumimurigni")
Line 2,513 ⟶ 4,378:
 
=={{header|Pike}}==
<langsyntaxhighlight lang="pike">int main(){
if(pal("rotator")){
write("palindrome!\n");
Line 2,528 ⟶ 4,393:
return 0;
}
}</langsyntaxhighlight>
 
=={{header|PL/I}}==
To satisfy the revised specification (which contradicts the preceding explanation)
the following trivially solves the problem in PL/I:
<langsyntaxhighlight PLlang="pl/Ii">is_palindrome = (text = reverse(text));</langsyntaxhighlight>
 
The following solution strips spaces:
<syntaxhighlight lang="text">is_palindrome: procedure (text) returns (bit(1));
declare text character (*) varying;
 
Line 2,553 ⟶ 4,418:
return (substr(text, 1, j));
end remove_blanks;
end is_palindrome;</langsyntaxhighlight>
 
=={{header|PL/M}}==
<syntaxhighlight lang="plm">100H:
 
/* CHECK EXACT PALINDROME ASSUMING $-TERMINATED STRING */
PALINDROME: PROCEDURE(PTR) BYTE;
DECLARE (PTR, FRONT, BACK) ADDRESS, STR BASED PTR BYTE;
/* FIND END */
FRONT, BACK = 0;
DO WHILE STR(BACK) <> '$';
BACK = BACK + 1;
END;
BACK = BACK - 1;
/* CHECK MATCH */
DO WHILE (FRONT < BACK) AND (STR(FRONT) = STR(BACK));
FRONT = FRONT + 1;
BACK = BACK - 1;
END;
RETURN FRONT >= BACK;
END PALINDROME;
 
/* CHECK INEXACT PALINDROME: FILTER OUT NON-LETTERS AND NUMBERS */
INEXACT$PALINDROME: PROCEDURE(PTR) BYTE;
/* 256 BYTES OUGHT TO BE ENOUGH FOR EVERYONE */
DECLARE (PTR, OPTR) ADDRESS;
DECLARE FILTER (256) BYTE;
DECLARE (IN BASED PTR, OUT BASED OPTR) BYTE;
OPTR = .FILTER;
 
DO WHILE IN <> '$';
OUT = IN OR 32;
/* LOWERCASE CHARACTERS ARE NOT IN THE PL/M CHARSET,
BUT WE CAN JUST WRITE THE ASCII VALUES AS NUMBERS */
IF (OUT >= '0' AND OUT <= '9')
OR (OUT >= 97 AND OUT <= 122) THEN
OPTR = OPTR + 1;
PTR = PTR + 1;
END;
OUT = '$';
RETURN PALINDROME(.FILTER);
END INEXACT$PALINDROME;
 
/* CP/M BDOS CALLS */
BDOS: PROCEDURE(FUNC, ARG);
DECLARE FUNC BYTE, ARG ADDRESS;
GO TO 5;
END BDOS;
 
PRINT: PROCEDURE(STRING);
DECLARE STRING ADDRESS;
CALL BDOS(9, STRING);
END PRINT;
/* TEST SOME STRINGS */
DECLARE STRINGS (8) ADDRESS;
STRINGS(0) = .'ROTOR$';
STRINGS(1) = .'RACECAR$';
STRINGS(2) = .'LEVEL$';
STRINGS(3) = .'REDDER$';
STRINGS(4) = .'RACECAR$';
STRINGS(5) = .'A MAN, A PLAN, A CANAL: PANAMA$';
STRINGS(6) = .'EGAD, A BASE TONE DENOTES A BAD AGE.$';
STRINGS(7) = .'ROSETTA$';
 
DECLARE N BYTE;
DO N = 0 TO LAST(STRINGS);
CALL PRINT(STRINGS(N));
CALL PRINT(.': $');
IF PALINDROME(STRINGS(N)) THEN
CALL PRINT(.'EXACT$');
ELSE IF INEXACT$PALINDROME(STRINGS(N)) THEN
CALL PRINT(.'INEXACT$');
ELSE
CALL PRINT(.'NOT A PALINDROME$');
CALL PRINT(.(13,10,'$'));
END;
 
CALL BDOS(0,0);
EOF</syntaxhighlight>
{{out}}
<pre>ROTOR: EXACT
RACECAR: EXACT
LEVEL: EXACT
REDDER: EXACT
RACECAR: EXACT
A MAN, A PLAN, A CANAL: PANAMA: INEXACT
EGAD, A BASE TONE DENOTES A BAD AGE.: INEXACT
ROSETTA: NOT A PALINDROME</pre>
 
=={{header|Plain English}}==
Strings and substrings all come with two byte pointers by default:
* <code>first</code>, which points to the first byte in the string.
* <code>last</code>, which points to the last byte in the string.
 
 
<code>first</code> is an address, while <code>first's target</code> is the byte at that address.
No need to actually reverse the string; just compare the first's target with the last's target until they meet in the middle.
<syntaxhighlight lang="plainenglish">To decide if a string is palindromic:
Slap a substring on the string.
Loop.
If the substring's first is greater than the substring's last, say yes.
If the substring's first's target is not the substring's last's target, say no.
Add 1 to the substring's first.
Subtract 1 from the substring's last.
Repeat.</syntaxhighlight>
 
=={{header|Pointless}}==
'''Basic Function'''
<syntaxhighlight lang="pointless">isPalindrome(chars) =
chars == reverse(chars)</syntaxhighlight>
 
'''With Pre-processing'''
<syntaxhighlight lang="pointless">output =
"A man, a plan, a canal -- Panama"
|> toList
|> filter(inFunc(alNums))
|> map(toLower)
|> isPalindrome
|> println</syntaxhighlight>
 
{{out}}
<pre>true</pre>
 
=={{header|Potion}}==
<langsyntaxhighlight Potionlang="potion"># The readable recursive version
palindrome_i = (s, b, e):
if (e <= b): true.
Line 2,566 ⟶ 4,557:
palindrome_i(s, 0, s length - 1).
 
palindrome(argv(1))</langsyntaxhighlight>
 
=={{header|PowerBASIC}}==
Line 2,572 ⟶ 4,563:
The output is identical to the [[#BASIC|QBasic]] version, above.
 
<langsyntaxhighlight lang="powerbasic">FUNCTION isPalindrome (what AS STRING) AS LONG
DIM whatcopy AS STRING, chk AS STRING, tmp AS STRING * 1, L0 AS LONG
 
Line 2,603 ⟶ 4,594:
END IF
NEXT
END FUNCTION</langsyntaxhighlight>
 
 
=={{header|PowerShell}}==
An exact version based on reversing the string:
<lang PowerShell>
<syntaxhighlight lang="powershell">
Function Test-Palindrome( [String] $Text ){
$CharArray = $Text.ToCharArray()
[Array]::Reverse($CharArray)
$Text.ToCharArray() -eq [string]::join('', $CharArray)
}
</syntaxhighlight>
</lang>
 
===PowerShell (Regex Version)===
This version is much faster because it does not manipulate arrays. [This is not clear; the above version was slowed down by using -join instead of [string]::join, and -like instead of -eq. After changing those it is similar, if not faster, than this version].
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Test-Palindrome
{
Line 2,652 ⟶ 4,642:
$Text -match "^(?'char'[a-z])+[a-z]?(?:\k'char'(?'-char'))+(?(char)(?!))$"
}
</syntaxhighlight>
</lang>
<syntaxhighlight lang="powershell">
<lang PowerShell>
Test-Palindrome -Text 'radar'
</syntaxhighlight>
</lang>
{{Out}}
<pre>
True
</pre>
<syntaxhighlight lang="powershell">
<lang PowerShell>
Test-Palindrome -Text "In girum imus nocte et consumimur igni."
</syntaxhighlight>
</lang>
{{Out}}
<pre>
False
</pre>
<syntaxhighlight lang="powershell">
<lang PowerShell>
Test-Palindrome -Text "In girum imus nocte et consumimur igni." -Inexact
</syntaxhighlight>
</lang>
{{Out}}
<pre>
True
</pre>
===PowerShell (Unicode category aware, no string reverse)===
An inexact version can remove punctuation by looking at Unicode categories for each character, either using .Net methods or a regex.
<syntaxhighlight lang="powershell">Function Test-Palindrome {
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline)]
[string[]]$Text
)
 
process {
:stringLoop foreach ($T in $Text)
{
# Normalize Unicode combining characters,
# so character á compares the same as (a+combining accent)
$T = $T.Normalize([Text.NormalizationForm]::FormC)
# Remove anything from outside the Unicode category
# "Letter from any language"
$T = $T -replace '\P{L}', ''
 
# Walk from each end of the string inwards,
# comparing a char at a time.
# Avoids string copy / reverse overheads.
$Left, $Right = 0, [math]::Max(0, ($T.Length - 1))
while ($Left -lt $Right)
{
if ($T[$Left] -ne $T[$Right])
{
# return early if string is not a palindrome
[PSCustomObject]@{
Text = $T
IsPalindrome = $False
}
continue stringLoop
}
else
{
$Left++
$Right--
}
}
 
# made it to here, then string is a palindrome
[PSCustomObject]@{
Text = $T
IsPalindrome = $True
}
}
}
}
'ánu-ná', 'nowt' | Test-Palindrome</syntaxhighlight>
{{Out}}
<pre>
PS C:\> 'ánu-ná', 'nowt' | Test-Palindrome
 
Text IsPalindrome
---- ------------
ánuná True
now False
</pre>
 
=={{header|Processing}}==
<syntaxhighlight lang="processing">
void setup(){
println(isPalindrome(InsertPalindromeHere));
}
 
boolean isPalindrome(string check){
char[] letters = new char[check.length];
string invert = " ";
string modCheck = " " + check;
for(int i = 0; i < letters.length; i++){
letters[i] = check.charAt(i);
}
for(int i = letters.length-1; i >= 0; i--){
invert = invert + letters[i];
}
if(invert == modCheck){
return true;
} else {
return false;
}
}
</syntaxhighlight>
 
{{out}}
<pre>
"true" or "false" depending
</pre>
 
====Alternative Implementation: using StringBuilder, implementing exact and inexact check====
<syntaxhighlight lang="processing">
void setup(){
println("PalindromeDetection");
 
String[] tests = {
"abcba",
"aa",
"a",
"",
" ",
"ab",
"abcdba",
"A man, a plan, a canal: Panama!",
"Dammit, I’m Mad!",
"Never odd or even",
"ingirumimusnocteetconsumimurigni"
};
 
for (int i = 0; i < tests.length; i++){
println((i + 1) + ". '" + tests[i] + "' isExactPalindrome: " + isExactPalindrome(tests[i]) + " isInexactPalindrome: " + isInexactPalindrome(tests[i]));
}
}
 
/*
* Check for exact palindrome using StringBuilder and String since String in Java does not provide any reverse functionality because Strings are immutable.
*/
boolean isExactPalindrome(String s){
StringBuilder sb = new StringBuilder(s);
return s.equals(sb.reverse().toString());
}
 
/*
* Check for inexact palindrome using the check for exact palindromeabove.
*/
boolean isInexactPalindrome(String s){
// removes all whitespaces and non-visible characters,
// remove anything besides alphabet characters
// ignore case
return isExactPalindrome(s.replaceAll("\\s+","").replaceAll("[^A-Za-z]+", "").toLowerCase());
}
</syntaxhighlight>
 
{{out}}
<pre>
PalindromeDetection
1. 'abcba' isExactPalindrome: true isInexactPalindrome: true
2. 'aa' isExactPalindrome: true isInexactPalindrome: true
3. 'a' isExactPalindrome: true isInexactPalindrome: true
4. '' isExactPalindrome: true isInexactPalindrome: true
5. ' ' isExactPalindrome: true isInexactPalindrome: true
6. 'ab' isExactPalindrome: false isInexactPalindrome: false
7. 'abcdba' isExactPalindrome: false isInexactPalindrome: false
8. 'A man, a plan, a canal: Panama!' isExactPalindrome: false isInexactPalindrome: true
9. 'Dammit, I’m Mad!' isExactPalindrome: false isInexactPalindrome: true
10. 'Never odd or even' isExactPalindrome: false isInexactPalindrome: true
11. 'ingirumimusnocteetconsumimurigni' isExactPalindrome: true isInexactPalindrome: true
</pre>
 
Line 2,680 ⟶ 4,820:
From [http://www2.dcs.hull.ac.uk/NEAT/dnd/AI/prolog/tutorial2.html this tutorial].
 
<langsyntaxhighlight lang="prolog">palindrome(Word) :- name(Word,List), reverse(List,List).</langsyntaxhighlight>
 
'''Recursive'''
 
{{works with|SWI Prolog}}
<langsyntaxhighlight lang="prolog">pali(Str) :- sub_string(Str, 0, 1, _, X), string_concat(Str2, X, Str), string_concat(X, Mid, Str2), pali(Mid).
pali(Str) :- string_length(Str, Len), Len < 2.</langsyntaxhighlight>
 
Changing '''string''' into '''atom''' makes the program run also on GNU Prolog. I.e.
Line 2,692 ⟶ 4,832:
{{works with|GNU Prolog}}
 
<langsyntaxhighlight lang="prolog">pali(Str) :- sub_atom(Str, 0, 1, _, X), atom_concat(Str2, X, Str), atom_concat(X, Mid, Str2), pali(Mid).
pali(Str) :- atom_length(Str, Len), Len < 2.</langsyntaxhighlight>
 
=={{header|PureBasic}}==
{{works with|PureBasic|4.41}}
<langsyntaxhighlight PureBasiclang="purebasic">Procedure IsPalindrome(StringToTest.s)
If StringToTest=ReverseString(StringToTest)
ProcedureReturn 1
Line 2,702 ⟶ 4,843:
ProcedureReturn 0
EndIf
EndProcedure</langsyntaxhighlight>
 
=={{header|Python}}==
Line 2,713 ⟶ 4,854:
but right syntax <tt>string[::-1]</tt>)
 
<langsyntaxhighlight lang="python">def is_palindrome(s):
return s == s[::-1]</langsyntaxhighlight>
 
'''Non-recursive, Ignoring Punctuation/Case/Spaces'''
 
A word is a palindrome if the letters are the same forwards as backwards, but the other methods given here will return False for, e.g., an input of "Go hang a salami, I'm a lasagna hog" or "A man, a plan, a canal: Panama." An implementation that traverses the string and ignores case differences, spaces, and non-alpha characters is pretty trivial.
 
<syntaxhighlight lang="python">def is_palindrome(s):
low = 0
high = len(s) - 1
while low < high:
if not s[low].isalpha():
low += 1
elif not s[high].isalpha():
high -= 1
else:
if s[low].lower() != s[high].lower():
return False
else:
low += 1
high -= 1
return True</syntaxhighlight>
 
'''Recursive'''
 
<langsyntaxhighlight lang="python">def is_palindrome_r(s):
if len(s) <= 1:
return True
Line 2,724 ⟶ 4,885:
return False
else:
return is_palindrome_r(s[1:-1])</langsyntaxhighlight>
 
Python has short-circuit evaluation of Boolean operations
so a shorter and still easy to understand recursive function is
 
<langsyntaxhighlight lang="python">def is_palindrome_r2(s):
return not s or s[0] == s[-1] and is_palindrome_r2(s[1:-1])</langsyntaxhighlight>
 
'''Testing'''
 
<langsyntaxhighlight lang="python">def test(f, good, bad):
assert all(f(x) for x in good)
assert not any(f(x) for x in bad)
Line 2,742 ⟶ 4,903:
notpals = ('aA', 'abA', 'abxBa', 'abxxBa')
for ispal in is_palindrome, is_palindrome_r, is_palindrome_r2:
test(ispal, pals, notpals)</langsyntaxhighlight>
 
''' Palindrome Using Regular Expressions Python 2.7 '''
 
<langsyntaxhighlight lang="python">def p_loop():
import re, string
re1="" # Beginning of Regex
Line 2,773 ⟶ 4,934:
else:
print("Nope!")
return 0</langsyntaxhighlight>
 
 
'''Checking the left half against a reflection of the right half'''
<syntaxhighlight lang="python">'''Palindrome detection'''
 
 
# isPalindrome :: String -> Bool
def isPalindrome(s):
'''True if the string is unchanged under reversal.
(The left half is a reflection of the right half)
'''
d, m = divmod(len(s), 2)
return s[0:d] == s[d + m:][::-1]
 
 
# ------------------------- TEST -------------------------
# main :: IO ()
def main():
'''Test'''
 
print('\n'.join(
f'{repr(s)} -> {isPalindrome(cleaned(s))}' for s in [
"",
"a",
"ab",
"aba",
"abba",
"In girum imus nocte et consumimur igni"
]
))
 
 
# cleaned :: String -> String
def cleaned(s):
'''A lower-case copy of s, with spaces pruned.'''
return [c.lower() for c in s if ' ' != c]
 
 
# MAIN ---
if __name__ == '__main__':
main()
</syntaxhighlight>
{{out}}
<pre>'' -> True
'a' -> True
'ab' -> False
'aba' -> True
'abba' -> True
'In girum imus nocte et consumimur igni' -> True</pre>
 
'''Twiddle Indexing'''
 
I have no idea what this technique is called, so I'm going with "Twiddle Indexing".
 
<pre> Twiddle Indexing v. Negative Indexing
 
0 1 2 3 4 <-- index
[ a, b, c, d, e ]
~4 ~3 ~2 ~1 ~0 <-- twiddle index
 
0 1 2 3 4 <-- index
[ a, b, c, d, e ]
-5 -4 -3 -2 -1 <-- negative index</pre>
 
<syntaxhighlight lang="python">def palindromic(str):
for i in range(len(str)//2):
if str[i] != str[~i]:
return(False)
return(True)</syntaxhighlight>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="quackery"> [ dup reverse = ] is palindromic ( [ --> b )
 
[ [] swap witheach
[ upper dup
dup lower = iff
drop else join ]
palindromic ] is inexactpalindrome ( $ --> b )</syntaxhighlight>
 
===Twiddle Indexing===
 
<syntaxhighlight lang="quackery"> [ true swap
dup size 2 / times
[ dup i peek
over i ~ peek != if
[ dip not conclude ] ]
drop ] is palindromic ( [ --> b )</syntaxhighlight>
 
=={{header|R}}==
Line 2,781 ⟶ 5,030:
R will assume an infinite recursion if a recursion nests deeper than 5,000.
Options may be set in the environment to increase this to 500,000.
<langsyntaxhighlight Rlang="rsplus">palindro <- function(p) {
if ( nchar(p) == 1 ) {
return(TRUE)
Line 2,793 ⟶ 5,042:
}
}
}</langsyntaxhighlight>
 
'''Iterative'''
<langsyntaxhighlight Rlang="rsplus">palindroi <- function(p) {
for(i in 1:floor(nchar(p)/2) ) {
r <- nchar(p) - i + 1
Line 2,802 ⟶ 5,051:
}
TRUE
}</langsyntaxhighlight>
 
'''Comparative'''
Line 2,810 ⟶ 5,059:
Note that this method incorrectly regards an empty string as not a palindrome.
Please leave this bug in the code, and take a look a the [[Testing_a_Function]] page.
<langsyntaxhighlight Rlang="rsplus">revstring <- function(stringtorev) {
return(
paste(
Line 2,817 ⟶ 5,066:
)
}
palindroc <- function(p) {return(revstring(p)==p)}</langsyntaxhighlight>
 
'''Rev'''
 
R has a built-in function for reversing vectors, so we only have to coerce our input in to the proper form.
 
Unicode is supported, but this ignores the "inexact palindromes" extra credit requirement because, without some sort of regex, supporting Unicode while stripping punctuation and white space is hard in R.
<syntaxhighlight lang="rsplus">is.Palindrome <- function(string)
{
characters <- unlist(strsplit(string, ""))
all(characters == rev(characters))
}</syntaxhighlight>
{{out}}
The rev solution is not benchmarked.
<pre>
test <- "ingirumimusnocteetconsumimurigni"
Line 2,838 ⟶ 5,098:
=={{header|Racket}}==
 
<syntaxhighlight lang="racket">
<lang Racket>
(define (palindromb str)
(let* ([lst (string->list (string-downcase str))]
Line 2,853 ⟶ 5,113:
#t
>
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>subset Palindrom of Str where {
.flip eq $_ given .comb(/\w+/).join.lc
}
my @tests = q:to/END/.lines;
A man, a plan, a canal: Panama.
My dog has fleas
Madam, I'm Adam.
1 on 1
In girum imus nocte et consumimur igni
END
for @tests { say $_ ~~ Palindrom, "\t", $_ }</syntaxhighlight>
{{out}}
<pre>True A man, a plan, a canal: Panama.
False My dog has fleas
True Madam, I'm Adam.
False 1 on 1
True In girum imus nocte et consumimur igni
</pre>
 
=={{header|Rascal}}==
The most simple solution:
<langsyntaxhighlight lang="rascal">import String;
 
public bool palindrome(str text) = toLowerCase(text) == reverse(text);</langsyntaxhighlight>
 
A solution that handles sentences with spaces and capitals:
 
<langsyntaxhighlight lang="rascal">import String;
 
public bool palindrome(str text){
Line 2,869 ⟶ 5,152:
return text == reverse(text);
}
</syntaxhighlight>
</lang>
 
Example:
<langsyntaxhighlight lang="rascal">rascal>palindrome("In girum imus nocte et consumimur igni")
bool: true</langsyntaxhighlight>
 
=={{header|REBOL}}==
 
<langsyntaxhighlight REBOLlang="rebol">REBOL [
Title: "Palindrome Recognizer"
Date: 2010-01-03
Author: oofoe
URL: http://rosettacode.org/wiki/Palindrome
]
Line 2,907 ⟶ 5,188:
assert [palindrome? "In girum imus nocte et consumimur igni"] ; Spaces not removed.
 
; I know we're doing palindromes, not alliteration, but who could resist...?</langsyntaxhighlight>
 
{{out}}
Line 2,923 ⟶ 5,204:
=={{header|Retro}}==
 
<syntaxhighlight lang="retro">
<lang Retro>
:palindrome? (s-f) dup s:hash [ s:reverse s:hash ] dip eq? ;
needs hash'
: palindrome? ( $-f ) dup ^hash'hash [ ^strings'reverse ^hash'hash ] dip = ;
 
"'ingirumimusnocteetconsumimurigni" palindrome? putnn:put
</syntaxhighlight>
</lang>
 
=={{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}}==
===version 1===
<langsyntaxhighlight REXXlang="rexx">/*REXX pgm checks if phrase is palindromic; ignores the case of the letters. */
parse arg y /*get (optional) phrase from the C.L. */
if y='' then y='In girum imus nocte et consumimur igni' /*[↓] translation.*/
Line 2,943 ⟶ 5,275:
/*────────────────────────────────────────────────────────────────────────────*/
isTpal: return reverse(arg(1))==arg(1)
isPal: return isTpal(translate(space(x,0)))</langsyntaxhighlight>
{{out|output|text=''':'''}}
'''output'''
<pre>
string = In girum imus nocte et consumimur igni
Line 2,950 ⟶ 5,282:
</pre>
 
===Short version 2 ===
{{works with|ARexx}}
{{works with|Regina}} (3.8 and later, with options: AREXX_BIFS and AREXX_SEMANTICS)
(Works with Regina 3.8 and later, with options: AREXX_BIFS and AREXX_SEMANTICS)
 
It should be noted that the &nbsp; '''COMPRESS''' &nbsp; function is not a Classic REXX BIF and isn't present in many REXXes.
<br>The &nbsp; '''SPACE(string,0)''' &nbsp; BIF can be used instead.
Line 2,958 ⟶ 5,293:
It should also be noted that &nbsp; '''UPPER''' &nbsp; BIF is not present in some REXXes.
<br>Use the &nbsp; '''PARSE UPPER''' &nbsp; statement or &nbsp; '''TRANSLATE()''' &nbsp; BIF instead.
<syntaxhighlight lang="rexx">
<lang REXX>
/* REXX */
 
/*Check whether a string is a palindrome */
parse pull string
Line 2,971 ⟶ 5,308:
parse arg string
return string==reverse(string)
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,980 ⟶ 5,317:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
aString = "radar"
bString = ""
Line 2,989 ⟶ 5,326:
if aString = bString see " is a palindrome." + nl
else see " is not a palindrome" + nl ok
</syntaxhighlight>
</lang>
 
=={{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}}==
 
'''Non-recursive'''
 
<langsyntaxhighlight lang="ruby">def palindrome?(s)
s == s.reverse
end</langsyntaxhighlight>
 
'''Recursive'''
 
<langsyntaxhighlight lang="ruby">def r_palindrome?(s)
if s.length <= 1
true
Line 3,009 ⟶ 5,375:
r_palindrome?(s[1..-2])
end
end</langsyntaxhighlight>
 
'''Testing'''
Note that the recursive method is ''much'' slower -- using the 2151 character palindrome by Dan Hoey [http://www2.vo.lu/homepages/phahn/anagrams/panama.htm here], we have:
<langsyntaxhighlight lang="ruby">str = "A man, a plan, a caret, [...2110 chars deleted...] a canal--Panama.".downcase.delete('^a-z')
puts palindrome?(str) # => true
puts r_palindrome?(str) # => true
Line 3,021 ⟶ 5,387:
b.report('iterative') {10000.times {palindrome?(str)}}
b.report('recursive') {10000.times {r_palindrome?(str)}}
end</langsyntaxhighlight>
 
{{out}}
Line 3,029 ⟶ 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}}==
<langsyntaxhighlight 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
 
FUNCTIONfunction isPalindrome$(str$)
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"</lang>
end function</syntaxhighlight>
{{out}}
<pre>My dog has fleas is not Palindrome
Line 3,051 ⟶ 5,460:
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">fn is_palindrome(string: &str) -> bool {
<lang rust>
let half_len = string.len() / 2;
fn is_palindrome(string: &str) -> bool {
string
string.chars().zip(string.chars().rev()).all(|(x, y)| x == y)
.chars()
.take(half_len)
.eq(string.chars().rev().take(half_len))
}
 
Line 3,061 ⟶ 5,473:
 
fn main() {
test!("",
"a",
"adaa",
"adadada",
"ingirumimusnocteetconsumimurigniadad",
"人人為我,我為人人ingirumimusnocteetconsumimurigni",
"Я иду с мечем人人為我, судия我為人人",
иду "아들딸들아с мечем, судия",
"The quick brown fox아들딸들아");,
"The quick brown fox"
}
);
</lang>
}</syntaxhighlight>
 
{{out}}
<pre>
Line 3,085 ⟶ 5,497:
'The quick brown fox': false
</pre>
The above soluion checks if the codepoints form a pallindrome, but it is perhaps more correct to consider if the graphemes form a pallindrome. This can be accomplished with an external library and a slight modification to <code>is_palindrome</code>.
<syntaxhighlight lang="rust">extern crate unicode_segmentation;
use unicode_segmentation::UnicodeSegmentation;
fn is_palindrome(string: &str) -> bool {
string.graphemes(true).eq(string.graphemes(true).rev())
}</syntaxhighlight>
 
=={{header|SAS}}==
Description
<syntaxhighlight lang="sas">
<lang SAS>
The macro "palindro" has two parameters: string and ignorewhitespace.
string is the expression to be checked.
Line 3,094 ⟶ 5,512:
This macro was written in SAS 9.2. If you use a version before SAS 9.1.3,
the compress function options will not work.
</syntaxhighlight>
</lang>
Code
<syntaxhighlight lang="sas">
<lang SAS>
%MACRO palindro(string, ignorewhitespace);
DATA _NULL_;
Line 3,121 ⟶ 5,539:
RUN;
%MEND;
</syntaxhighlight>
</lang>
Example macro call and output
<syntaxhighlight lang="sas">
<lang SAS>
%palindro("a man, a plan, a canal: panama",y);
 
Line 3,139 ⟶ 5,557:
real time 0.00 seconds
cpu time 0.00 seconds
</syntaxhighlight>
</lang>
 
=={{header|Scala}}==
{{libheader|Scala}}
=== Non-recursive, robustified===
<langsyntaxhighlight Scalalang="scala"> def isPalindrome(s: String): Boolean = (s.size >= 2) && s == s.reverse</langsyntaxhighlight>
===Bonus: Detect and account for odd space and punctuation===
<langsyntaxhighlight lang="scala"> def isPalindromeSentence(s: String): Boolean =
(s.size >= 2) && {
val p = s.replaceAll("[^\\p{L}]", "").toLowerCase
p == p.reverse
}
</syntaxhighlight>
</lang>
 
===Recursive===
<langsyntaxhighlight Scalalang="scala">import scala.annotation.tailrec
 
def isPalindromeRec(s: String) = {
Line 3,162 ⟶ 5,580:
 
(s.size >= 2) && inner(s)
}</langsyntaxhighlight>
'''Testing'''
<langsyntaxhighlight Scalalang="scala"> // Testing
assert(!isPalindrome(""))
assert(!isPalindrome("z"))
Line 3,186 ⟶ 5,604:
assert(!isPalindromeRec("A man a plan a canal Panama."))
 
println("Successfully completed without errors.")</langsyntaxhighlight>
 
=={{header|Scheme}}==
'''Non-recursive'''
 
<langsyntaxhighlight lang="scheme">(define (palindrome? s)
(let ((chars (string->list s)))
(equal? chars (reverse chars))))</langsyntaxhighlight>
 
'''Recursive'''
<langsyntaxhighlight lang="scheme">(define (palindrome? s)
(let loop ((i 0)
(j (- (string-length s) 1)))
Line 3,211 ⟶ 5,629:
(loop (cdr s) (cdr r))))))
 
<lang scheme>> (palindrome? "ingirumimusnocteetconsumimurigni")
#t
> (palindrome? "This is not a palindrome")
#f
></langsyntaxhighlight>
 
=={{header|sed}}==
<syntaxhighlight lang="sed">h
:l
s/^\(.\)\(.*\)\1$/\2/
tl
/../d
x</syntaxhighlight><pre>
$ printf '%s\n' a zz az bag gag none madamimadam otto | sed -f palindrome.sed
a
zz
gag
madamimadam
otto
</pre>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">const func boolean: palindrome (in string: stri) is func
result
var boolean: isPalindrome is TRUE;
Line 3,231 ⟶ 5,664:
end if;
end for;
end func;</langsyntaxhighlight>
 
For palindromes where spaces shuld be ignore use:
<langsyntaxhighlight lang="seed7">palindrome(replace("in girum imus nocte et consumimur igni", " ", ""))</langsyntaxhighlight>
 
=={{header|SequenceL}}==
'''Using the Reverse Library Function'''
<langsyntaxhighlight lang="sequencel">import <Utilities/Sequence.sl>;
 
isPalindrome(string(1)) := equalList(string, reverse(string));</langsyntaxhighlight>
 
'''Version Using an Indexed Function'''
<langsyntaxhighlight lang="sequencel">isPalindrome(string(1)) :=
let
compares[i] := string[i] = string[size(string) - (i - 1)] foreach i within 1 ... (size(string) / 2);
in
all(compares);</langsyntaxhighlight>
 
=={{header|Sidef}}==
 
'''Built-in'''
<langsyntaxhighlight lang="ruby">say "noon".is_palindrome; # true</langsyntaxhighlight>
 
'''Non-recursive'''
 
<langsyntaxhighlight lang="ruby">func palindrome(s) {
s == s.reverse
}</langsyntaxhighlight>
 
'''Recursive'''
 
<langsyntaxhighlight lang="ruby">func palindrome(s) {
if (s.len <= 1) {
true
}
elsif (s.first  != s.last) {
false
}
else {
__FUNC__(s.ftfirst(-1, ).last(-21))
}
}</langsyntaxhighlight>
 
=={{header|Simula}}==
<syntaxhighlight lang="simula">BEGIN
 
BOOLEAN PROCEDURE ISPALINDROME(T); TEXT T;
BEGIN
BOOLEAN RESULT;
INTEGER I, J;
I := 1;
J := T.LENGTH;
RESULT := TRUE;
WHILE RESULT AND I < J DO
BEGIN
CHARACTER L, R;
T.SETPOS(I); L := T.GETCHAR; I := I + 1;
T.SETPOS(J); R := T.GETCHAR; J := J - 1;
RESULT := L = R;
END;
ISPALINDROME := RESULT;
END ISPALINDROME;
 
TEXT T;
FOR T :- "", "A", "AA", "ABA", "SALALAS", "MADAMIMADAM",
"AB", "AAB", "ABCBDA"
DO
BEGIN
OUTTEXT(IF ISPALINDROME(T) THEN "IS " ELSE "ISN'T");
OUTTEXT(" PALINDROME: ");
OUTCHAR('"');
OUTTEXT(T);
OUTCHAR('"');
OUTIMAGE;
END;
 
END.</syntaxhighlight>
{{out}}
<pre>
IS PALINDROME: ""
IS PALINDROME: "A"
IS PALINDROME: "AA"
IS PALINDROME: "ABA"
IS PALINDROME: "SALALAS"
IS PALINDROME: "MADAMIMADAM"
ISN'T PALINDROME: "AB"
ISN'T PALINDROME: "AAB"
ISN'T PALINDROME: "ABCBDA"
</pre>
 
=={{header|Slate}}==
'''Non-Recursive'''
<langsyntaxhighlight lang="slate">s@(String traits) isPalindrome
[
(s lexicographicallyCompare: s reversed) isZero
].</langsyntaxhighlight>
 
'''Recursive'''
Defined on Sequence since we are not using String-specific methods:
<langsyntaxhighlight lang="slate">s@(Sequence traits) isPalindrome
[
s isEmpty
ifTrue: [True]
ifFalse: [(s first = s last) /\ [(s sliceFrom: 1 to: s indexLast - 1) isPalindrome]]
].</langsyntaxhighlight>
 
'''Testing'''
<langsyntaxhighlight lang="slate">define: #p -> 'ingirumimusnocteetconsumimurigni'.
inform: 'sequence ' ; p ; ' is ' ; (p isPalindrome ifTrue: [''] ifFalse: ['not ']) ; 'a palindrome.'.</langsyntaxhighlight>
 
=={{header|Smalltalk}}==
 
{{works with|Squeak}}
<langsyntaxhighlight lang="smalltalk">isPalindrome := [:aString |
str := (aString select: [:chr| chr isAlphaNumeric]) collect: [:chr | chr asLowercase].
str = str reversed.
].
</syntaxhighlight>
</lang>
 
{{works with|GNU Smalltalk}}
<langsyntaxhighlight lang="smalltalk">String extend [
palindro [ "Non-recursive"
^ self = (self reverse)
Line 3,317 ⟶ 5,797:
]
]
].</langsyntaxhighlight>
 
'''Testing'''
 
<langsyntaxhighlight lang="smalltalk">('hello' palindro) printNl.
('hello' palindroR) printNl.
('ingirumimusnocteetconsumimurigni' palindro) printNl.
('ingirumimusnocteetconsumimurigni' palindroR) printNl.</langsyntaxhighlight>
 
{{works with|VisualWorks Pharo Squeak}}
<langsyntaxhighlight lang="smalltalk">SequenceableCollection>>isPalindrome
^self reverse = self
</syntaxhighlight>
</lang>
 
=={{header|SNOBOL4}}==
 
<langsyntaxhighlight SNOBOL4lang="snobol4"> define('pal(str)') :(pal_end)
pal str notany(&ucase &lcase) = :s(pal)
str = replace(str,&ucase,&lcase)
Line 3,349 ⟶ 5,829:
palchk('In girum imus nocte et consumimur igni')
palchk('The quick brown fox jumped over the lazy dogs')
end</langsyntaxhighlight>
 
{{out}}
Line 3,358 ⟶ 5,838:
The quick brown fox jumped over the lazy dogs
Palindrome: False</pre>
 
=={{header|SparForte}}==
As a structured script.
<syntaxhighlight lang="ada">#!/usr/local/bin/spar
pragma annotate( summary, "palindrome" );
pragma annotate( description, "Write at least one function/method (or whatever it is" );
pragma annotate( description, "called in your preferred language) to check if a" );
pragma annotate( description, "sequence of characters (or bytes) is a palindrome or" );
pragma annotate( description, "not. The function must return a boolean value (or" );
pragma annotate( description, "something that can be used as boolean value, like an" );
pragma annotate( description, "integer)." );
pragma annotate( see_also, "http://rosettacode.org/wiki/Palindrome_detection" );
pragma annotate( author, "Ken O. Burtch" );
pragma license( unrestricted );
 
pragma restriction( no_external_commands );
 
procedure palindrome is
 
function is_palindrome( text : string ) return boolean is
begin
for offset in 0..strings.length( text ) / 2 -1 loop
if strings.element( text, offset+1) /= strings.element( text, positive( strings.length( text ) - offset ) ) then
return false;
end if;
end loop;
return true;
end is_palindrome;
 
sentence : string;
result : boolean;
begin
sentence := "this is a test";
result := is_palindrome( sentence );
put( sentence ) @ ( " : " ) @ ( result );
new_line;
 
sentence := "ablewasiereisawelba";
result := is_palindrome( sentence );
put( sentence ) @ ( " : " ) @ ( result );
new_line;
end palindrome;</syntaxhighlight>
 
=={{header|SQL}}==
<langsyntaxhighlight lang="sql">SET @txt = REPLACE('In girum imus nocte et consumimur igni', ' ', '');
SELECT REVERSE(@txt) = @txt;</langsyntaxhighlight>
 
=={{header|Swift}}==
{{works with|Swift|1.2}}
<langsyntaxhighlight Swiftlang="swift">import Foundation
 
// Allow for easy character checking
Line 3,382 ⟶ 5,905:
}
return false
}</langsyntaxhighlight>
 
{{works with|Swift|2.0}}
<langsyntaxhighlight lang="swift">func isPal(str: String) -> Bool {
let c = str.characters
return lazy(c).reverse()
.startsWith(c[c.startIndex...advance(c.startIndex, c.count / 2)])
}</langsyntaxhighlight>
 
=={{header|Tailspin}}==
<syntaxhighlight lang="tailspin">
templates palindrome
[$...] -> #
when <=$(last..first:-1)> do '$...;' !
end palindrome
 
[['rotor', 'racecar', 'level', 'rosetta']... -> palindrome ] -> !OUT::write
</syntaxhighlight>
 
{{out}}
<pre>
[rotor, racecar, level]
</pre>
 
=={{header|Tcl}}==
Line 3,395 ⟶ 5,933:
'''Non-recursive'''
 
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
proc palindrome {s} {
return [expr {$s eq [string reverse $s]}]
}</langsyntaxhighlight>
 
'''Recursive'''
 
<langsyntaxhighlight lang="tcl">proc palindrome_r {s} {
if {[string length $s] <= 1} {
return true
Line 3,410 ⟶ 5,948:
return [palindrome_r [string range $s 1 end-1]]
}
}</langsyntaxhighlight>
 
'''Testing'''
 
<langsyntaxhighlight lang="tcl">set p ingirumimusnocteetconsumimurigni
puts "'$p' is palindrome? [palindrome $p]"
puts "'$p' is palindrome? [palindrome_r $p]"</langsyntaxhighlight>
 
=={{header|TUSCRIPT}}==
<langsyntaxhighlight lang="tuscript">
$$ MODE TUSCRIPT
pal ="ingirumimusnocteetconsumimurigni"
Line 3,429 ⟶ 5,967:
PRINT/ERROR "untrue"
ENDSELECT
</syntaxhighlight>
</lang>
{{out}}
<pre>
true
</pre>
 
=={{header|TypeScript}}==
<syntaxhighlight lang="javascript">const detectNonLetterRegexp=/[^A-ZÀ-ÞЀ-Я]/g;
 
function stripDiacritics(phrase:string){
return phrase.normalize('NFD').replace(/[\u0300-\u036f]/g, "")
}
 
function isPalindrome(phrase:string){
const TheLetters = stripDiacritics(phrase.toLocaleUpperCase().replace(detectNonLetterRegexp, ''));
const middlePosition = TheLetters.length/2;
const leftHalf = TheLetters.substr(0, middlePosition);
const rightReverseHalf = TheLetters.substr(-middlePosition).split('').reverse().join('');
return leftHalf == rightReverseHalf;
}
 
console.log(isPalindrome('Sueño que esto no es un palíndromo'))
console.log(isPalindrome('Dábale arroz a la zorra el abad!'))
console.log(isPalindrome('Я иду с мечем судия'))
</syntaxhighlight>
 
=={{header|Uiua}}==
Does not ignore spaces.
<syntaxhighlight lang="uiua">≍⇌."tacocat"</syntaxhighlight>
 
=={{header|UNIX Shell}}==
<syntaxhighlight lang="bash">if [[ "${text}" == "$(rev <<< "${text}")" ]]; then
echo "Palindrome"
else
echo "Not a palindrome"
fi</syntaxhighlight>
 
=={{header|Ursala}}==
Line 3,442 ⟶ 6,011:
This is done using the built in operator suffixes
for intersection (c), identity (i), reversal (x) and equality (E).
<langsyntaxhighlight Ursalalang="ursala">#import std
 
palindrome = ~&cixE\letters+ * -:~& ~=`A-~rlp letters</langsyntaxhighlight>
This test programs applies the function to each member of a list of three strings,
of which only the first two are palindromes.
<langsyntaxhighlight Ursalalang="ursala">#cast %bL
 
examples = palindrome* <'abccba','foo ba rra bo of','notone'></langsyntaxhighlight>
{{out}}
<pre><true,true,false></pre>
Line 3,455 ⟶ 6,024:
=={{header|Vala}}==
Checks if a word is a palindrome ignoring the case and spaces.
<langsyntaxhighlight lang="vala">bool is_palindrome (string str) {
var tmp = str.casefold ().replace (" ", "");
return tmp == tmp.reverse ();
Line 3,463 ⟶ 6,032:
print (is_palindrome (args[1]).to_string () + "\n");
return 0;
}</langsyntaxhighlight>
 
=={{header|VBA}}==
Line 3,471 ⟶ 6,040:
version it could also work using StrReverse.
 
<syntaxhighlight lang="vba">
<lang VBA>
Public Function isPalindrome(aString as string) as Boolean
dim tempstring as string
Line 3,477 ⟶ 6,046:
isPalindrome = (tempstring = Reverse(tempstring))
End Function
</syntaxhighlight>
</lang>
 
{{out|Example}}
Line 3,487 ⟶ 6,056:
=={{header|VBScript}}==
====Implementation====
<langsyntaxhighlight lang="vb">function Squish( s1 )
dim sRes
sRes = vbNullString
Line 3,504 ⟶ 6,073:
squished = Squish( s1 )
isPalindrome = ( squished = StrReverse( squished ) )
end function</langsyntaxhighlight>
 
====Invocation====
<langsyntaxhighlight lang="vb">wscript.echo isPalindrome( "My dog has fleas")
wscript.echo isPalindrome( "Madam, I'm Adam.")
wscript.echo isPalindrome( "1 on 1")
wscript.echo isPalindrome( "In girum imus nocte et consumimur igni")</langsyntaxhighlight>
{{out}}
<pre>0
Line 3,520 ⟶ 6,089:
This routine checks if current line is a palindrome:
 
<langsyntaxhighlight lang="vedit">:PALINDROME:
EOL #2 = Cur_Col-2
BOL
Line 3,526 ⟶ 6,095:
if (CC(#1) != CC(#2-#1)) { Return(0) }
}
Return(1)</langsyntaxhighlight>
 
Testing:
 
<langsyntaxhighlight lang="vedit">Call("PALINDROME")
if (Return_Value) {
Statline_Message("Yes")
Line 3,536 ⟶ 6,105:
Statline_Message("No")
}
Return</langsyntaxhighlight>
 
=={{header|Visual Basic .NET}}==
{{trans|VBA}}
<syntaxhighlight lang="vbnet">Module Module1
 
Function IsPalindrome(p As String) As Boolean
Dim temp = p.ToLower().Replace(" ", "")
Return StrReverse(temp) = temp
End Function
 
Sub Main()
Console.WriteLine(IsPalindrome("In girum imus nocte et consumimur igni"))
End Sub
 
End Module</syntaxhighlight>
{{out}}
<pre>True</pre>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="javascript">
fn is_pal_1(ss string) bool {
s := ss.runes()
for i in 0..s.len/2 {
if s[i] != s[s.len-1-i]{
return false
}
}
return true
}
 
fn is_pal_2(word string) bool {
if word == word.runes().reverse().string() {return true}
return false
}
fn main() {
words := ["rotor", "rosetta", "step on no pets", "été", "wren", "🦊😀🦊"]
println('Check from is_pal_1:')
for word in words {
println('$word => ${is_pal_1(word)}')
}
println('\nCheck from is_pal_2:')
for word in words {
println('$word => ${is_pal_2(word)}')
}
}
</syntaxhighlight>
 
{{out}}
<pre>
Are the following palindromes?
rotor => true
rosetta => false
step on no pets => true
été => true
wren => false
🦊😀🦊 => true
</pre>
 
=={{header|Wortel}}==
<langsyntaxhighlight lang="wortel">@let {
; Using a hook
pal1 @(= @rev)
Line 3,551 ⟶ 6,178:
!pal3 "In girum imus nocte et consumimur igni"
]]
}</langsyntaxhighlight>
Returns: <pre>[true false true]</pre>
 
=={{header|Wren}}==
<syntaxhighlight lang="wren">var isPal = Fn.new { |word| word == ((word.count > 0) ? word[-1..0] : "") }
 
System.print("Are the following palindromes?")
for (word in ["rotor", "rosetta", "step on no pets", "été", "wren", "🦊😀🦊"]) {
System.print(" %(word) => %(isPal.call(word))")
}</syntaxhighlight>
 
{{out}}
<pre>
Are the following palindromes?
rotor => true
rosetta => false
step on no pets => true
été => true
wren => false
🦊😀🦊 => true
</pre>
 
=={{header|X86 Assembly}}==
<syntaxhighlight lang="x86asm">
; x86_84 Linux nasm
section .text
 
isPalindrome:
mov rsi, rax
mov rdi, rax
 
get_end:
cmp byte [rsi], 0
je get_result
inc rsi
jmp get_end
 
get_result:
mov rax, 0
dec rsi
 
compare:
mov cl, byte [rdi]
cmp byte [rsi], cl
jne not_palindrome
cmp rsi, rdi
je palindrome
inc rdi
cmp rdi, rsi
je palindrome
dec rsi
jmp compare
 
not_palindrome:
mov rax, 0
ret
palindrome:
mov rax, 1
ret
</syntaxhighlight>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
string 0; \use zero-terminated strings
 
Line 3,580 ⟶ 6,265:
CrLf(0);
];
]</langsyntaxhighlight>
 
{{out}}
Line 3,596 ⟶ 6,281:
is_palindrome (by changing case and stripping non-alphabetical characters).
 
<langsyntaxhighlight lang="yorick">func is_palindrome(str) {
s = strchar(str)(:-1);
return allof(s == s(::-1));
Line 3,605 ⟶ 6,290:
w = where(s >= 'a' & s <= 'z');
return strchar(s(w));
}</langsyntaxhighlight>
 
=={{header|Z80 Assembly}}==
{{works with|CP/M 3.1|YAZE-AG-2.51.2 Z80 emulator}}
{{works with|ZSM4 macro assembler|YAZE-AG-2.51.2 Z80 emulator}}
Use the /S8 switch on the ZSM4 assembler for 8 significant characters for labels and names<br><br>
''Inexact'' palindrome detection is integrated - blanks are eliminated and all characters converted to uppercase<br>
Converted string is printed<br>
<syntaxhighlight lang="z80">
;
; Check if input string is a palindrome using Z80 assembly language
;
; Runs under CP/M 3.1 on YAZE-AG-2.51.2 Z80 emulator
; Assembled with zsm4 on same emulator/OS, uses macro capabilities of said assembler
; Created with vim under Windows
;
; 2023-04-17 Xorph
;
 
;
; Useful definitions
;
 
bdos equ 05h ; Call to CP/M BDOS function
strdel equ 6eh ; Set string delimiter
readstr equ 0ah ; Read string from console
wrtstr equ 09h ; Write string to console
 
nul equ 00h ; ASCII control characters
esc equ 1bh
cr equ 0dh
lf equ 0ah
 
buflen equ 30h ; Length of input buffer
 
;
; Macros for BDOS calls
;
 
setdel macro char ; Set string delimiter to char
ld c,strdel
ld e,char
call bdos
endm
 
print macro msg ; Output string to console
ld c,wrtstr
ld de,msg
call bdos
endm
 
newline macro ; Print newline
ld c,wrtstr
ld de,crlf
call bdos
endm
 
readln macro buf ; Read a line from input
ld c,readstr
ld de,buf
call bdos
endm
 
;
; Other macros
;
 
toupper macro
local notlow
cp 'a'
jr c,notlow
cp 'z'+1
jr nc,notlow
add a,'A'-'a'
notlow:
endm
 
;
; =====================
; Start of main program
; =====================
;
 
cseg
 
setdel nul ; Set string delimiter to 00h
 
ld b,buflen ; Clear input buffer
ld hl,bufcont
clrloop:
ld (hl),0
inc hl
djnz clrloop
 
readln inputbuf ; Read a line from input
newline ; Newline is discarded during input, so write one...
 
ld b,buflen ; Convert all to uppercase
ld hl,bufcont
uprloop:
ld a,(hl)
toupper
ld (hl),a
inc hl
djnz uprloop
 
ld a,(inputbuf+1) ; Eliminate all spaces
ld b,a
ld c,0 ; Counter for non-spaces
ld ix,bufcont ; String (buffer) address in ix
ld iy,compress ; Compressed string (without blanks) goes to iy
spcloop:
ld a,(ix)
cp ' '
jr z,isblank
inc c ; If not blank, move to (iy) and increment counter
ld (iy),a
inc iy
isblank:
inc ix
djnz spcloop
 
ld a,c ; Move back to original buffer
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 use block move
ld hl,compress
ldir
ex de,hl ; Add nul terminator - target is in de, but memory load only via hl
ld (hl),nul
 
print bufcont ; Print actual text before start of check
newline
 
ld a,(inputbuf+1) ; Get number of characters entered into bc, if 0 quit
ld b,0 ; bc can be used for adding the text length to iy
cp b ; b is 0 for setting bc correctly and so can also be used for comparison
jr z,isnopali
ld c,a ; bc is now loaded correctly
 
ld ix,bufcont ; ix points to start of string
ld iy,bufcont ; iy points to end of string: Let it point to start...
add iy,bc ; ...and add the string's length - 1
dec iy
 
ld b,c ; Use b as counter for comparison (djnz)
srl b ; Only need to check half the chars - if odd, the middle char need not be checked
 
chkloop:
ld a,(ix) ; Actual comparison: Get (ix) into a and compare with (iy)
cp (iy) ; Upon mismatch, quit immediately
jr nz,isnopali
inc ix
dec iy
djnz chkloop
 
; All comparisons ok, print success - fall through to ispali
 
ispali:
ld de,messagey
jr writeres
 
isnopali:
ld de,messagen
; Fall through to writeres
 
writeres:
ld c,wrtstr ; Echo the text on screen
call bdos
newline
 
ret ; Return to CP/M
 
;
; ===================
; End of main program
; ===================
;
 
;
; ================
; Data definitions
; ================
;
 
dseg
 
inputbuf: ; Input buffer
defb buflen ; Maximum possible length
defb 00h ; Returned length of actual input
bufcont:
defs buflen ; Actual input area
compress:
defs buflen ; For eliminating spaces
 
messagey:
defz 'Yes' ; Is a Palindrome
 
messagen:
defz 'No' ; Is not a Palindrome
 
crlf: defb cr,lf,nul ; Generic newline
</syntaxhighlight>
 
{{out}}
<pre>
E>palindrm
1 2 3 2 1
12321
Yes
 
E>palindrm
Hello World
HELLOWORLD
No
 
E>palindrm
AbC D cBa
ABCDCBA
Yes
 
E>palindrm
aaabbbccc
AAABBBCCC
No
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn pali(text){
n,m :=if (text.len(), n/<2) return(False);
text==text.reverse();
if (n<2) return(False);
}
text[0,m]==text[n-m,*].reverse(); // ignore middle char if n is odd
fcn pali2(text){ pali((text - " \t\n.,").toLower()) } // or whatever punctuation is</syntaxhighlight>
}</lang>
{{out}}
<pre>
pali("red rum sir is murder") //--> False
pali("red rum sir is murder" - " ") //-->True, remove spaces
palipali2("In girum imus nocte et consumimur igni".toLower() - " ") //-->True
</pre>
 
=={{header|Zoea}}==
<syntaxhighlight lang="zoea">
program: palindrome
case: 1
input: abcdcba
output: true
 
case: 2
input: dog
output: false
 
case: 3
input: x
output: true
 
case: 4
input: abc
output: false
</syntaxhighlight>
 
=={{header|Zoea Visual}}==
[http://zoea.co.uk/examples/zv-rc/Palindrome.png Palindrome]
890

edits