Palindrome detection: Difference between revisions
→{{header|langur}}
Langurmonkey (talk | contribs) |
|||
(38 intermediate revisions by 29 users not shown) | |||
Line 30:
{{trans|Python}}
<
R s == reversed(s)</
=={{header|360 Assembly}}==
<
PALINDRO CSECT
USING PALINDRO,R13 base register
Line 65:
MSG DC CL23'IT IS A TRUE PALINDROME'
YREGS
END PALINDRO</
{{out}}
<pre>
Line 74:
=={{header|8080 Assembly}}==
<
jmp demo
;;; Is the $-terminated string at DE a palindrome?
Line 132:
w2: db 'racecar$'
w3: db 'level$'
w4: db 'rosetta$'</
{{out}}
Line 142:
=={{header|8086 Assembly}}==
<
org 100h
section .text
Line 190:
.w3: db 'level$'
.w4: db 'redder$'
.w5: db 'rosetta$'</
{{out}}
Line 201:
=={{header|ACL2}}==
<
(if (zp i)
(mv xs ys)
Line 217:
(if (= (mod lngth 2) 1)
(equal (rest xs) ys)
(equal xs ys)))))</
=={{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!}}==
<
BYTE l,r
Line 287 ⟶ 373:
Test("This sentence is not a palindrome.")
Test("123 456 789 897 654 321")
RETURN</
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Palindrome_detection.png Screenshot from Atari 8-bit computer]
Line 306 ⟶ 392:
=={{header|ActionScript}}==
The following function handles non-ASCII characters properly, since charAt() returns a single Unicode character.
<
{
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;
}</
=={{header|Ada}}==
<
begin
for Offset in 0..Text'Length / 2 - 1 loop
Line 322 ⟶ 408:
end loop;
return True;
end Palindrome;</
----
Ada 2012 version:
<
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}}==
Line 337 ⟶ 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}}
<
PROC palindrome = (STRING s)BOOL:(
FOR i TO UPB s OVER 2 DO
Line 362 ⟶ 448:
printf((template, t, palindrome(t)));
printf((template, t, palindrome r(t)))
)</
{{out}}
<pre>
Line 371 ⟶ 457:
=={{header|APL}}==
NARS2000 APL, dynamic function "if the argument matches the reverse of the argument", with Unicode character support:
<
0
{⍵≡⌽⍵} '⍋racecar⍋'
1</
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):
<
0
(⊢≡⌽) 'nun'
1</
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:
<
inexact 'abc,-cbA2z'
0
inexact 'abc,-cbA2'
1</
Dyalog APL has a Unicode-aware uppercase/lowercase function (819 I-beam), AFAIK no support for looking up Unicode character classes.
Line 391 ⟶ 477:
Using post-Yosemite AppleScript (to pull in lowercaseStringWithLocale from Foundation classes)
<
------ CASE-INSENSITIVE PALINDROME, IGNORING SPACES ? ----
Line 465 ⟶ 551:
((ca's NSString's stringWithString:(str))'s ¬
lowercaseStringWithLocale:(ca's NSLocale's currentLocale())) as text
end toLower</
{{Out}}
<pre>true</pre>
Line 471 ⟶ 557:
===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:
<
set txt to join(txt, "") -- In case the input's a list (array).
return (txt = join(reverse of txt's characters, ""))
Line 484 ⟶ 570:
end join
return isPalindrome("Radar")</
Text comparisons in AppleScript are case-insensitive by default, so:
{{output}}
<syntaxhighlight lang
If case is to be taken into account, the call to the handler can be enclosed in a 'considering case' control statement.
<
return isPalindrome("Radar")
end considering</
{{output}}
<syntaxhighlight lang
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):
<
return isPalindrome("Was it a 😀car, or a c😀at-I-saw?")
end ignoring</
{{output}}
<syntaxhighlight lang
=={{header|Applesoft BASIC}}==
<
110 DATA"MADAM, I'M ADAM."
120 DATA"1 ON 1"
Line 534 ⟶ 620:
350 PA = MID$(W$, L0, 1) = MID$(W$, L - L0 + 1, 1)
360 IF PALINDROME THEN NEXT L0
370 RETURN</
=={{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
Line 590 ⟶ 676:
w4: .asciz "redder"
w5: .asciz "rosetta"
words: .word w1,w2,w3,w4,w5,0</
{{out}}
Line 601 ⟶ 687:
=={{header|Arturo}}==
<
loop ["abba" "boom" "radar" "civic" "great"] 'wrd [
print [wrd ": palindrome?" palindrome? wrd]
]</
{{out}}
Line 617 ⟶ 703:
=={{header|AutoHotkey}}==
Reversing the string:
<
Loop, Parse, Str
ReversedStr := A_LoopField . ReversedStr
return, (ReversedStr == Str)?"Exact":(RegExReplace(ReversedStr,"\W")=RegExReplace(Str,"\W"))?"Inexact":"False"
}</
=={{header|AutoIt}}==
<
Global $aString[7] = [ _
Line 656 ⟶ 742:
Return True
EndFunc
</syntaxhighlight>
{{out}}
<syntaxhighlight lang="text">
"In girum imus nocte, et consumimur igni" is an inexact palindrome.
"Madam, I'm Adam." is an inexact palindrome.
Line 666 ⟶ 752:
"Ein Neger mit Gazelle zagt im Regen nie." is an inexact palindrome.
"something wrong" is not a palindrome.
</syntaxhighlight>
--[[User:BugFix|BugFix]] ([[User talk:BugFix|talk]]) 14:26, 13 November 2013 (UTC)
Line 675 ⟶ 761:
See [[Reversing a string]].
<
{
if ( s == reverse(s) ) return 1
return 0
}</
'''Recursive'''
<
{
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))
}</
'''Testing'''
<
pal = "ingirumimusnocteetconsumimurigni"
print is_palindro(pal)
print is_palindro_r(pal)
}</
=={{header|BaCon}}==
<
OPTION COMPARE TRUE
Line 710 ⟶ 796:
PRINT "Not a palindrome."
ENDIF
</syntaxhighlight>
{{out}}
<pre>
Line 724 ⟶ 810:
=={{header|Bash}}==
<
#! /bin/bash
# very simple way to detect a palindrome in Bash
Line 755 ⟶ 841:
echo "$input is a palindrome"
fi
</syntaxhighlight>
=={{header|BASIC}}==
{{works with|QBasic}}
<
DIM txt$
Line 839 ⟶ 925:
RvrsText$ = NewText$
END FUNCTION</
{{out}}
Line 853 ⟶ 939:
==={{header|IS-BASIC}}===
<syntaxhighlight lang="is-basic">
100 PROGRAM "Palindr.bas"
110 LINE INPUT PROMPT "Text: ":TX$
Line 874 ⟶ 960:
280 IF TX$(I)<>TX$(LEN(TX$)-I+1) THEN LET PALIND=0:EXIT FOR
290 NEXT
300 END DEF</
==={{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.
<
20 FOR I=1 TO LEN S$/2
30 IF S$(I)<>S$(LEN S$-I+1) THEN GOTO 60
Line 885 ⟶ 971:
50 GOTO 70
60 PRINT "NOT A ";
70 PRINT "PALINDROME"</
====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.
<
80 STOP
90 LET T$=""
Line 895 ⟶ 981:
120 NEXT I
130 LET S$=T$
140 RETURN</
==={{header|BBC BASIC}}===
<
PRINT """" test$ """" ;
IF FNpalindrome(FNletters(test$)) THEN
Line 924 ⟶ 1,010:
ENDIF
NEXT
= B$</
{{out}}
<pre>"A man, a plan, a canal: Panama!" is a palindrome</pre>
Line 930 ⟶ 1,016:
=={{header|Batch File}}==
<
setlocal enabledelayedexpansion
set /p string=Your string :
Line 944 ⟶ 1,030:
echo %string% %palindrome% a palindrome.
pause
exit</
Or, recursive (and without setlocal enabledelayedexpansion) (compatible with ReactOS cmd.exe)
<
set /p testString=Your string (all same case please) :
call :isPalindrome result %testString: =%
Line 965 ⟶ 1,051:
call :isPalindrome %1 %string:~1,-1%
)
goto :eof</
=={{header|BCPL}}==
<
let palindrome(s) = valof
Line 1,010 ⟶ 1,096:
for i = 0 to 8 do
writef("'%S': %S*N", tests!i, check(tests!i))
$)</
{{out}}
<pre>'rotor': exact palindrome
Line 1,027 ⟶ 1,113:
The following code reads a line from stdin and prints "True" if it is a palindrome, or False" otherwise.
<
~->p5p ^ 0v1p80-1g80vj!-g5g80g5_0'ev
:a^80+1:g8<>8g1+:18pv>0"eslaF">:#,_@
[[relet]]-2010------>003-x -^"Tru"<</
{{works with|Befunge|93}}
Line 1,041 ⟶ 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''.)
<
2^ < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < <
4 ^_v ^_v ^_v ^_v ^_v ^_v ^_v ^_v ^_v ^_v ^_v ^_v
Line 1,058 ⟶ 1,144:
>09g8p09g1+09pv
|: < <
^<</
=={{header|BQN}}==
Line 1,065 ⟶ 1,151:
BQN considers characters as single units, and hence the functions support unicode by default.
<
Pal1 ← ⊢≡⌽
Pal2 ← {𝕩≡⌽𝕩}</
=={{header|Bracmat}}==
<
= a
. @(!arg:(%?a&utf$!a) ?arg !a)
Line 1,103 ⟶ 1,189:
)
&
);</
Output:
<pre>In girum imus nocte et consumimur igni is indeed a palindrome
Line 1,116 ⟶ 1,202:
palindrome
</pre>
=={{header|Bruijn}}==
<syntaxhighlight lang="bruijn">
:import std/String .
main [<~>0 =? 0]
:test (main "tacocat") ([[1]])
:test (main "bruijn") ([[0]])
</syntaxhighlight>
=={{header|Burlesque}}==
<
zz{ri}f[^^<-==
</syntaxhighlight>
=={{header|C}}==
Line 1,132 ⟶ 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).
<
int palindrome(const char *s)
Line 1,143 ⟶ 1,239:
}
return 1;
}</
More idiomatic version:
<
{
const char *t; /* t is a pointer that traverses backwards from the end */
Line 1,154 ⟶ 1,250:
}
return 1;
}</
'''Recursive'''
Line 1,161 ⟶ 1,257:
itself a palindrome.
<
{
if ( (e - 1) <= b ) return 1;
if ( s[b] != s[e-1] ) return 0;
return palindrome_r(s, b+1, e-1);
}</
'''Testing'''
<
#include <string.h>
/* testing */
Line 1,184 ⟶ 1,280:
t, palindrome_r(t, 0, l) ? "" : "n't");
return 0;
}</
=={{header|C sharp|C#}}==
Line 1,190 ⟶ 1,286:
'''Non-recursive'''
<
class Program
Line 1,210 ⟶ 1,306:
Console.WriteLine(IsPalindrome("ingirumimusnocteetconsumimurigni"));
}
}</
'''Using LINQ operators'''
<
using System.Linq;
Line 1,228 ⟶ 1,324:
}
}
</syntaxhighlight>
'''No string reversal'''
Reversing a string is very slow. A much faster way is to simply compare characters.
<
static class Program
Line 1,249 ⟶ 1,345:
Console.WriteLine("ingirumimusnocteetconsumimurigni".IsPalindrome());
}
}</
=={{header|C++}}==
The C solutions also work in C++, but C++ allows a simpler one:
<
#include <algorithm>
Line 1,259 ⟶ 1,355:
{
return std::equal(s.begin(), s.end(), s.rbegin());
}</
Or, checking half is sufficient (on odd-length strings, this will ignore the middle element):
<
#include <algorithm>
Line 1,268 ⟶ 1,364:
{
return std::equal(s.begin(), s.begin()+s.length()/2, s.rbegin());
}</
=={{header|Clojure}}==
<
(= s (clojure.string/reverse s)))</
'''lower-level, but somewhat faster'''
<
(loop [front 0 back (dec (.length s))]
(or (>= front back)
(and (= (.charAt s front) (.charAt s back))
(recur (inc front) (dec back)))))</
'''Test'''
Line 1,290 ⟶ 1,386:
=={{header|CLU}}==
<
str_reverse = proc (s: string) returns (string)
chs: array[char] := array[char]$predict(0, string$size(s))
Line 1,343 ⟶ 1,439:
end
end
end start_up</
{{out}}
<pre>"rotor": exact palindrome
Line 1,356 ⟶ 1,452:
=={{header|COBOL}}==
{{works with|GnuCOBOL}}
<
function-id. palindromic-test.
Line 1,375 ⟶ 1,471:
goback.
end function palindromic-test.
</syntaxhighlight>
=={{header|CoffeeScript}}==
<
String::isPalindrome = ->
for i in [0...@length / 2] when @[i] isnt @[@length - (i + 1)]
Line 1,391 ⟶ 1,487:
'There is no spoon.'
]
</syntaxhighlight>
{{out}}
Line 1,399 ⟶ 1,495:
=={{header|Common Lisp}}==
<
(string= s (reverse s)))</
===Alternate solution===
I use [https://franz.com/downloads/clp/survey Allegro CL 10.1]
<
;; Project : Palindrome detection
Line 1,418 ⟶ 1,514:
(palindrome x)
(terpri)
</syntaxhighlight>
Output:
<pre>
Line 1,427 ⟶ 1,523:
=={{header|Component Pascal}}==
BlackBox Component Builder
<
MODULE BbtPalindrome;
IMPORT StdLog;
Line 1,464 ⟶ 1,560:
END Do;
END BbtPalindrome.
</syntaxhighlight>
Execute: ^Q BbtPalindrome.Do<br/>
{{out}}
Line 1,474 ⟶ 1,570:
=={{header|Cowgol}}==
<
# Check if a string is a palindrome
Line 1,543 ⟶ 1,639:
end if;
i := i + 1;
end loop;</
{{out}}
Line 1,557 ⟶ 1,653:
=={{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
Line 1,576 ⟶ 1,672:
true
end
</syntaxhighlight>
Also
<
mid = s.size // 2
mid.times { |j| return false if s[j] != s[-1 - j] }
true
end</
Performance comparison
<syntaxhighlight lang="ruby">
require "benchmark"
Benchmark.ips do |x|
Line 1,594 ⟶ 1,690:
x.report("imperative2") { palindrome_2("hannah")}
end
</syntaxhighlight>
<pre>declarative 45.45M ( 22.00ns) (±11.16%) 32.0B/op fastest
Line 1,602 ⟶ 1,698:
=={{header|D}}==
===High-level 32-bit Unicode Version===
<
bool isPalindrome1(C)(in C[] s) pure /*nothrow*/
Line 1,623 ⟶ 1,719:
assert(pali("ingirumimusnocteetconsumimurigni"));
assert(pali("salà las"));
}</
===Mid-level 32-bit Unicode Version===
<
bool isPalindrome2(C)(in C[] s) pure if (isSomeChar!C) {
Line 1,651 ⟶ 1,747:
assert(pali("ingirumimusnocteetconsumimurigni"));
assert(pali("salà las"));
}</
===Low-level 32-bit Unicode Version===
<
// assume alloca() to be pure for this program
Line 1,692 ⟶ 1,788:
assert(pali("ingirumimusnocteetconsumimurigni"));
assert(pali("salà las"));
}</
===Low-level ASCII Version===
<
if (str.length == 0) return true;
immutable(char)* s = str.ptr;
Line 1,717 ⟶ 1,813:
assert(pali("ingirumimusnocteetconsumimurigni"));
//assert(pali("salà las"));
}</
=={{header|Dart}}==
<
bool isPalindrome(String s){
for(int i = 0; i < s.length/2;i++){
Line 1,729 ⟶ 1,825:
return true;
}
</syntaxhighlight>
=={{header|Delphi}}==
<syntaxhighlight lang="delphi">uses
SysUtils, StrUtils;
Line 1,738 ⟶ 1,834:
begin
Result := SameText(aSrcString, ReverseString(aSrcString));
end;</
=={{header|Dyalect}}==
<
str == str.Reverse()
}
print(isPalindrom("ingirumimusnocteetconsumimurigni"))</
=={{header|Déjà Vu}}==
<
local :seq chars
local :len-seq -- len seq
Line 1,760 ⟶ 1,856:
!. palindrome? "ingirumimusnocteetconsumimurigni"
!. palindrome? "nope"</
{{out}}
<pre>true
Line 1,771 ⟶ 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>.
<
def upper := string.toUpperCase()
def last := upper.size() - 1
Line 1,778 ⟶ 1,874:
}
return true
}</
=={{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}}==
<
;; returns #t or #f
(define (palindrome? string)
Line 1,790 ⟶ 1,910:
;;(let ((string (string-replace string "/\ /" "" "g")))
;;(equal? (string->list string) (reverse (string->list string)))))
</syntaxhighlight>
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
is_palindrome (a_string: STRING): BOOLEAN
-- Is `a_string' a palindrome?
Line 1,812 ⟶ 1,932:
end
end
</syntaxhighlight>
=={{header|Ela}}==
<
isPalindrome xs = xs == reverse xs
isPalindrome <| toList "ingirumimusnocteetconsumimurigni"
</syntaxhighlight>
Function <code>reverse</code> is taken from list module and is defined as:
<
foldl f z (x::xs) = foldl f (f z x) xs
foldl _ z [] = z
</syntaxhighlight>
=={{header|Elixir}}==
<
defmodule PalindromeDetection do
def is_palindrome(str), do: str == String.reverse(str)
end
</syntaxhighlight>
Note: Because of Elixir's strong Unicode support, this even supports graphemes:
<pre>
Line 1,847 ⟶ 1,967:
=={{header|Elm}}==
<
import Html exposing (Html, Attribute, text, div, input)
import Html.Attributes exposing (placeholder, value, style)
Line 1,891 ⟶ 2,011:
, ("font-size", "1em")
, ("text-align", "left")
]</
Link to live demo: http://dc25.github.io/palindromeDetectionElm/
=={{header|Emacs Lisp}}==
<
(string= s (reverse s)))</
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">
-module( palindrome ).
Line 1,919 ⟶ 2,053:
display( String1, String2 ) -> io:fwrite( "Is ~p a palindrom? ~p~n", [String1, is_palindrome(String2)] ).
</syntaxhighlight>
{{out}}
<pre>
Line 1,929 ⟶ 2,063:
=={{header|Euphoria}}==
<
for i = 1 to length(s)/2 do
if s[i] != s[$-i+1] then
Line 1,936 ⟶ 2,070:
end for
return 1
end function</
<
include std/sequence.e -- reverse
include std/console.e -- display
Line 1,952 ⟶ 2,086:
s = remove_all(' ',upper(s))
display(iif(equal(s,reverse(s)),"true","false"))
end procedure</
{{out}}
<pre>
Line 1,968 ⟶ 2,102:
{{Works with| Office 265 Betas 2021}}
<
=LAMBDA(s,
LET(
Line 1,978 ⟶ 2,112:
CONCAT(lcs) = CONCAT(REVERSE(lcs))
)
)</
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:
<
=LAMBDA(s,
MID(s, ROW(INDIRECT("1:" & LEN(s))), 1)
Line 2,005 ⟶ 2,139:
)
)
)</
{{Out}}
{| class="wikitable"
Line 2,046 ⟶ 2,180:
=={{header|F Sharp|F#}}==
<
let arr = s.ToCharArray()
arr = Array.rev arr</
Examples:
<
val it : bool = true
isPalindrome ("In girum imus nocte et consumimur igni".Replace(" ", "").ToLower());;
val it : bool = true
isPalindrome "abcdef"
val it : bool = false</
=={{header|Factor}}==
<
: palindrome? ( str -- ? ) dup reverse = ;</
=={{header|Falcon}}==
'''VBA/Python programmer's approach not sure if it's the most falconic way'''
<
/* created by Aykayayciti Earl Lamont Montgomery
April 9th, 2018 */
Line 2,076 ⟶ 2,210:
a = "mom"
> is_palindrome(a)
</syntaxhighlight>
{{out}}
<pre>
Line 2,084 ⟶ 2,218:
'''more falconic'''
<
/* created by Aykayayciti Earl Lamont Montgomery
April 9th, 2018 */
Line 2,090 ⟶ 2,224:
b = "mom"
> strUpper(b).replace(" ", "") == strUpper(b[-1:0]) ? "Is a palindrome" : "Is not a palindrome"
</syntaxhighlight>
{{out}}
<pre>
Line 2,099 ⟶ 2,233:
=={{header|Fantom}}==
<
class Palindrome
{
Line 2,120 ⟶ 2,254:
}
}
</syntaxhighlight>
=={{header|FBSL}}==
<
FUNCTION stripNonAlpha(BYVAL s AS STRING) AS STRING
Line 2,151 ⟶ 2,285:
PAUSE
</syntaxhighlight>
{{out}}
<pre>
Line 2,160 ⟶ 2,294:
=={{header|Forth}}==
<
: last >r 2dup + 1- c@ r> swap ;
: palindrome? ( c-addr u -- f )
Line 2,168 ⟶ 2,302:
1 /string 1-
again ;
</syntaxhighlight>
FIRST and LAST are once-off words that could be beheaded immediately afterwards.
Line 2,178 ⟶ 2,312:
'''Below is a separate Forth program that detects palindrome phrases as well as single word palindromes. It was programmed using gforth.'''
<
variable temp-addr
Line 2,210 ⟶ 2,344:
else ." << Not >> a Palindrome."
then cr ;
</syntaxhighlight>
Example:
Line 2,221 ⟶ 2,355:
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<
implicit none
Line 2,234 ⟶ 2,368:
print *, is_palindro("last test")
contains</
'''Non-recursive'''
<
function is_palindro(t)
logical :: is_palindro
Line 2,263 ⟶ 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</
'''Recursive'''
<
implicit none
Line 2,274 ⟶ 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</
<syntaxhighlight lang
=={{header|FreeBASIC}}==
<
' compile with: fbc -s console "filename".bas
Line 2,354 ⟶ 2,488:
Print : Print : Print "Hit any key to end program"
Sleep
End</
{{out}}
<pre> reverse(test) = FALSE
Line 2,366 ⟶ 2,500:
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.
<
</syntaxhighlight>
Test in Frink with upper-plane Unicode:
<
<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}}==
<
local upper, lower, c, i, n, t;
upper := "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Line 2,411 ⟶ 2,665:
t := ZapGremlins(s);
return t = Reversed(t);
end;</
=={{header|GML}}==
<syntaxhighlight lang="go">
//Setting a var from an argument passed to the script
var str;
Line 2,430 ⟶ 2,684:
//returns true if the sequence is a palindrome else returns false
return (str == inv);
</syntaxhighlight>
Palindrome detection using a [http://rosettacode.org/wiki/Loop/Downward_For#GML Downward For-Loop]
<syntaxhighlight lang="go">
//Remove everything except for letters and digits and convert the string to lowercase. source is what will be compared to str.
Line 2,446 ⟶ 2,700:
//Return if it is a palindrome.
return source == str;
</syntaxhighlight>
=={{header|Go}}==
<
func IsPal(s string) bool {
Line 2,460 ⟶ 2,714:
}
return true
}</
This version works with Unicode,
<syntaxhighlight lang="go">
func isPalindrome(s string) bool {
runes := []rune(s)
Line 2,474 ⟶ 2,728:
}
return true
}</
Or using more slicing,
<syntaxhighlight lang="go">
func isPalindrome(s string) bool {
runes := []rune(s)
Line 2,488 ⟶ 2,742:
}
return true
}</
=={{header|GolfScript}}==
===Recursive===
<syntaxhighlight lang="golfscript">{.,1>{(\)@={pal}0if}1if\;}:pal;</syntaxhighlight>
Test program:
<syntaxhighlight lang="groovy">"ABBA" pal
"a" pal
"13231+464+989=989+464+13231" pal
"123 456 789 897 654 321" pal</syntaxhighlight>
{{out}}
<pre>1
1
1
0</pre>
=={{header|Groovy}}==
Line 2,494 ⟶ 2,767:
Solution:
<
s == s?.reverse()
}</
Test program:
<
println isPalindrome("a")
println isPalindrome("abcdefgfedcba")
println isPalindrome("abcdeffedcba")
println isPalindrome("abcedfgfedcb")</
{{out}}
Line 2,517 ⟶ 2,790:
Solution:
<
def n = s.size()
n < 2 || s[0..<n/2] == s[-1..(-n/2)]
}</
Test program and output are the same.
Line 2,528 ⟶ 2,801:
Solution follows the [[#C|C palindrome_r]] recursive solution:
<
isPalindrome = { String s ->
def n = s.size()
n < 2 || (s[0] == s[n-1] && isPalindrome(s[1..<(n-1)]))
}</
Test program and output are the same.
Line 2,543 ⟶ 2,816:
A string is a palindrome if reversing it we obtain the same string.
<
Or, applicative and point-free, with some pre-processing of data (shedding white space and upper case):
<
import Data.Char (toLower)
Line 2,582 ⟶ 2,855:
prepared cs = [toLower c | c <- cs, ' ' /= c]
showResult f s = (show s) <> " -> " <> show (f s)</
{{Out}}
<pre>"" -> True
Line 2,600 ⟶ 2,873:
'''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).
<syntaxhighlight lang="haskell">is_palindrome_r x | length x <= 1 = True
| head x == last x = is_palindrome_r . tail. init $ x
| otherwise = False</
=={{header|HicEst}}==
{{incorrect|HicEst|The stripping of spaces and case conversion should be outside the palindrome detection.}}
<
END
Line 2,625 ⟶ 2,902:
IF( Palindrome == 0 ) RETURN
ENDDO
END</
=={{header|Icon}} and {{header|Unicon}}==
<
every writes(s := !arglist) do write( if palindrome(s) then " is " else " is not", " a palindrome.")
end</
The following simple procedure uses the built-in reverse. Reverse creates a transient string which will get garbage collected.
<
return s == reverse(s)
end</
{{libheader|Icon Programming Library}}
Line 2,641 ⟶ 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.
<
local i
every if x[i := 1 to (*x+ 1)/2] ~== x[-i] then fail
return x
end</
=={{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}}==
<
=={{header|J}}==
Line 2,654 ⟶ 2,943:
Reverse and match method
<
Example usage
<
1
isPalin0 -.&' ' tolower 'In girum imus nocte et consumimur igni'
1</
'''Recursive'''
Tacit and explicit verbs:
<
isPalin2=: monad define
if. 1>:#y do. 1 return. end.
if. ({.={:)y do. isPalin2 }.}:y else. 0 end.
)</
Note that while these recursive verbs are bulkier and more complicated, they are also several thousand times more inefficient than isPalin0.
<
ts=:6!:2,7!:2 NB. time and space required to execute sentence
ts 'isPalin0 foo'
Line 2,684 ⟶ 2,973:
1599.09 1164.23
'isPalin2 foo' %&ts 'isPalin0 foo'
3967.53 2627.04</
=={{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 2,690 ⟶ 3,005:
'''Non-Recursive'''
<
StringBuilder sb = new StringBuilder(testMe);
return testMe.equals(sb.reverse().toString());
}</
'''Non-Recursive using indexes (supports upper-plane Unicode)'''
<
for (int i = 0, j = input.length() - 1; i < j; i++, j--) {
char startChar = input.charAt(i);
Line 2,714 ⟶ 3,029:
}
return true;
}</
'''Recursive (this version does not work correctly with upper-plane Unicode)'''
<
if(testMe.length()<=1){
return true;
Line 2,726 ⟶ 3,041:
}
return rPali(testMe.substring(1, testMe.length()-1));
}</
'''Recursive using indexes (this version does not work correctly with upper-plane Unicode)'''
<
int strLen = testMe.length();
return rPaliHelp(testMe, strLen-1, strLen/2, 0);
Line 2,744 ⟶ 3,059:
return rPaliHelp(testMe, strLen, testLen, index + 1);
}
</syntaxhighlight>
'''Regular Expression'''
([http://stackoverflow.com/questions/3664881/how-does-this-java-regex-detect-palindromes source])
<
return testMe.matches("|(?:(.)(?<=(?=^.*?(\\1\\2?)$).*))+(?<=(?=^\\2$).*)");
}</
=={{header|JavaScript}}==
<
return str === str.split("").reverse().join("");
}
console.log(isPalindrome("ingirumimusnocteetconsumimurigni"));</
ES6 implementation
<
Or, ignoring spaces and variations in case:
<
// isPalindrome :: String -> Bool
Line 2,797 ⟶ 3,112:
// MAIN ---
return main();
})();</
{{Out}}
<pre>true</pre>
=={{header|jq}}==
The definitional implementation would probably be fine except for very long strings:
<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
Line 2,809 ⟶ 3,137:
=={{header|Jsish}}==
<
function isPalindrome(str:string, exact:boolean=true) {
if (!exact) {
Line 2,836 ⟶ 3,164:
isPalindrome('Never odd or even', false) ==> true
=!EXPECTEND!=
*/</
Most of that code is for testing, using echo mode lines (semicolon in column 1)
Line 2,854 ⟶ 3,182:
=={{header|Julia}}==
<
<b> Non-Recursive </b>
<
function palindrome(s)
len = length(s)
Line 2,866 ⟶ 3,194:
return true
end
</syntaxhighlight>
<b> Recursive </b>
<
function palindrome(s)
len = length(s)
Line 2,878 ⟶ 3,206:
end
return false
end</
=={{header|k}}==
<syntaxhighlight lang
=={{header|Kotlin}}==
<
/* These functions deal automatically with Unicode as all strings are UTF-16 encoded in Kotlin */
Line 2,912 ⟶ 3,240:
println("'$candidate' is ${if (isInexactPalindrome(candidate)) "an" else "not an"} inexact palindrome")
}
}</
{{out}}
Line 2,931 ⟶ 3,259:
=={{header|langur}}==
<
val .tests =
"": false,
"z": true,
Line 2,953 ⟶ 3,281:
val .foundpal = .ispal(.word)
writeln .word, ": ", .foundpal, if(.foundpal == .tests[.word]: ""; " (FAILED TEST)")
}</
{{out}}
Line 2,972 ⟶ 3,300:
=={{header|Lasso}}==
<
local(_text = string(#text)) // need to make copy to get rid of reference issues
Line 2,987 ⟶ 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!')</
{{out}}
<pre>true
Line 2,994 ⟶ 3,322:
=={{header|Liberty BASIC}}==
<
print isPalindrome(removePunctuation$("In girum imus nocte et consumimur igni", "S"))
print isPalindrome(removePunctuation$("In girum imus nocte et consumimur igni", "SC"))
Line 3,015 ⟶ 3,343:
next i
removePunctuation$ = string$
end function</
{{out}}
Line 3,025 ⟶ 3,353:
=={{header|LiveCode}}==
This implementation defaults to exact match, but has an optional parameter to do inexact.<
if exact is empty or exact is not false then
set caseSensitive to true --default is false
Line 3,040 ⟶ 3,368:
end repeat
return revstr
end reverse</
=={{header|Logo}}==
<
output equal? :w reverse :w
end</
=={{header|Lua}}==
<
=={{header|M4}}==
Line 3,054 ⟶ 3,382:
'''Non-recursive'''
This uses the <code>invert</code> from [[Reversing a string]].
<
palindrorev(`ingirumimusnocteetconsumimurigni')
palindrorev(`this is not palindrome')</
'''Recursive'''
<
define(`cmplast',`ifelse(`striptwo(`$1')',,`yes',dnl
substr(`$1',0,1),substr(`$1',eval(len(`$1')-1),1),`yes',`no')')dnl
Line 3,065 ⟶ 3,393:
ifelse(eval(len(`$1')<1),1,`yes',cmplast(`$1'),`yes',`palindro(striptwo(`$1'))',`no')')dnl
palindro(`ingirumimusnocteetconsumimurigni')
palindro(`this is not palindrome')</
=={{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 3,071 ⟶ 3,464:
This uses functions from Maple's built-in <code>StringTools</code> package.
<syntaxhighlight lang="maple">
with(StringTools):
Line 3,079 ⟶ 3,472:
IsPalindrome(LowerCase(DeleteSpace("In girum imus nocte et consumimur igni")));
</syntaxhighlight>
{{out}}
Line 3,092 ⟶ 3,485:
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Built-in function handling lists, numbers, and strings:
<syntaxhighlight lang
{{out|Examples}}
<pre>PalindromeQ["TNT"]
Line 3,107 ⟶ 3,500:
=={{header|MATLAB}}==
<
trueFalse = all(string == fliplr(string)); %See if flipping the string produces the original string
Line 3,121 ⟶ 3,514:
end
end</
{{out|Sample Usage}}
<
ans =
1
</syntaxhighlight>
=={{header|Maxima}}==
<
palindromep("Sator arepo tenet opera rotas"); /* true */</
=={{header|MAXScript}}==
Line 3,140 ⟶ 3,533:
'''Non-recursive'''
<
(
local reversed = ""
for i in s.count to 1 by -1 do reversed += s[i]
return reversed == s
)</
'''Recursive'''
<
(
if s.count <= 1 then
Line 3,163 ⟶ 3,556:
isPalindrome_r (substring s 2 (s.count-2))
)
)</
'''Testing'''
<
format ("'%' is a palindrome? %\n") p (isPalindrome p)
format ("'%' is a palindrome? %\n") p (isPalindrome_r p)</
=={{header|min}}==
{{works with|min|0.19.3}}
<
(dup "" split reverse "" join ==) :str-palindrome?
Line 3,179 ⟶ 3,572:
"racecar" str-palindrome? puts
(a b c) palindrome? puts
(a b b a) palindrome? puts</
{{out}}
<pre>
Line 3,189 ⟶ 3,582:
=={{header|MiniScript}}==
<
// convert to lowercase, and strip non-letters
stripped = ""
Line 3,208 ⟶ 3,601:
if not isPalindrome(testStr) then answer.push "NOT"
answer.push "a palindrome"
print answer.join</
{{out}}
<pre>
Line 3,215 ⟶ 3,608:
=={{header|Mirah}}==
<
StringBuilder.new(s).reverse.toString()
end
Line 3,226 ⟶ 3,619:
puts palindrome?("Erik") # ==> false
puts palindrome?("palindroom-moordnilap") # ==> true
puts nil # ==> null</
=={{header|ML}}==
==={{header|mLite}}===
<
fun only_alpha s = implode ` filter (fn x = c_alphabetic x) ` explode s
Line 3,260 ⟶ 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");</
Output:
<pre>'In girum imus nocte, et consumimur igni' is a palindrome
Line 3,272 ⟶ 3,665:
==={{header|Standard ML}}===
<
fun palindrome s =
let val cs = explode s in
cs = rev cs
end
</syntaxhighlight>
=={{header|MMIX}}==
<
argv IS $1
Line 3,347 ⟶ 3,740:
1H TRAP 0,Fputs,StdOut % print
3H XOR $255,$255,$255
TRAP 0,Halt,0 % exit(0)</
=={{header|Modula-2}}==
<
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT WriteString,ReadChar;
Line 3,388 ⟶ 3,781:
ReadChar
END Palindrome.</
=={{header|Modula-3}}==
<
IMPORT Text;
Line 3,405 ⟶ 3,798:
RETURN TRUE;
END isPalindrome;
END Palindrome.</
=={{header|Nanoquery}}==
<
temp = ""
for char in s
Line 3,417 ⟶ 3,810:
return list(temp) = list(temp).reverse()
end</
=={{header|Nemerle}}==
<
using System.Console;
using Nemerle.Utility.NString; //contains methods Explode() and Implode() which convert string -> list[char] and back
Line 3,435 ⟶ 3,828:
WriteLine("radar is a palindrome: {0}", IsPalindrome("radar"));
}
}</
And a function to remove spaces and punctuation and convert to lowercase
<
{
def sepchars = Explode(",.;:-?!()' ");
Concat( "", Split(text, sepchars)).ToLower()
}</
=={{header|NetRexx}}==
{{Trans|REXX}}
<
y='In girum imus nocte et consumimur igni'
Line 3,463 ⟶ 3,856:
/* and translate to uppercase. */
return x==x.reverse() /* returns 1 if exactly equal */
</syntaxhighlight>
=={{header|NewLISP}}==
Works likewise for strings and for lists
<
(define (palindrome? s)
(setq r s)
Line 3,476 ⟶ 3,869:
(define (palindrome? s)
(= s (reverse (copy s))))
</syntaxhighlight>
=={{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.
<
Line 3,523 ⟶ 3,916:
check "In girum imus nocte et consumimur igni"
check "Esope reste ici et se repose"
check "This is a palindrom"</
{{out}}
Line 3,535 ⟶ 3,928:
=={{header|Objeck}}==
<
bundle Default {
class Test {
Line 3,556 ⟶ 3,949:
}
}
</syntaxhighlight>
=={{header|OCaml}}==
<
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)</
and here a function to remove the white spaces in the string:
<
let len = String.length str in
let res = Bytes.create len in
Line 3,582 ⟶ 3,975:
in
aux 0 0
</syntaxhighlight>
and to make the test case insensitive, just use the function <tt>String.lowercase_ascii</tt>.
Line 3,588 ⟶ 3,981:
=={{header|Octave}}==
'''Recursive'''
<
if ( length(s) == 1 )
v = true;
Line 3,601 ⟶ 3,994:
v = false;
endif
endfunction</
'''Non-recursive'''
<
v = all( (s == s(length(s):-1:1)) == 1);
endfunction</
'''Testing'''
<
palindro("satorarepotenetoperarotas")</
=={{header|Oforth}}==
<
=={{header|Ol}}==
<
; simple case - only lowercase letters
(define (palindrome? str)
Line 3,645 ⟶ 4,038:
(print (palindrome? "This is not a palindrome"))
; ==> #false
</syntaxhighlight>
=={{header|Oz}}==
<
{Reverse S} == S
end</
=={{header|PARI/GP}}==
<
s=Vec(s);
for(i=1,#v\2,
Line 3,659 ⟶ 4,052:
);
1
};</
A version for numbers:
{{works with|PARI/GP|2.6.0 and above}}
<
my(d=digits(n));
for(i=1,#d\2,
Line 3,669 ⟶ 4,062:
);
1
};</
=={{header|Pascal}}==
{{works with|Free Pascal}}
<
{ RECURSIVE }
Line 3,695 ⟶ 4,088:
else
is_palindro := false
end;</
<
begin
write('"', s, '" is ');
Line 3,715 ⟶ 4,108:
test_r(s1, is_palindro(s1));
test_r(s2, is_palindro(s2))
end.</
<
var
input, output: string;
Line 3,735 ⟶ 4,128:
else
writeln('input was not palindrome');
end.</
=={{header|Perl}}==
Line 3,751 ⟶ 4,144:
before you call these functions.
<
package Palindrome;
Line 3,787 ⟶ 4,180:
{
(@_ ? shift : $_) =~ /^(.?|(.)(?1)\2)$/ + 0
}</
This example shows how to use the functions:
<
use strict;
use warnings;
Line 3,813 ⟶ 4,206:
palindrome_r => sub { palindrome_r $latin },
palindrome_e => sub { palindrome_e $latin },
});</
{{out}} on a machine running Perl 5.10.1 on amd64-openbsd:
Line 3,841 ⟶ 4,234:
=={{header|Phix}}==
<!--<
<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>
<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>
Line 3,866 ⟶ 4,259:
<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>
<!--</
=={{header|Phixmonti}}==
<syntaxhighlight lang="Phixmonti">include ..\Utilitys.pmt
def palindrome? dup reverse == enddef
( "abba" "boom" "radar" "civic" "great" )
len for get
dup print " : palindrome? " print palindrome?
if "true" else "false" endif ?
endfor
def letter? dup 'z' <= swap 'a' >= and enddef
"" >ps
"In girum imus nocte, et consumimur igni" dup ? lower
len for get
dup letter?
if
ps> swap chain >ps
else
drop
endif
endfor
ps> palindrome? if "This is an inexact palindrome!" else "Not a palindrome." endif ?
</syntaxhighlight>
{{out}}
<pre>abba : palindrome? true
boom : palindrome? false
radar : palindrome? true
civic : palindrome? true
great : palindrome? false
In girum imus nocte, et consumimur igni
This is an inexact palindrome!
=== Press any key to exit ===</pre>
=={{header|PHP}}==
<
function is_palindrome($string) {
return $string == strrev($string);
}
?></
Regular expression-based solution ([http://www.polygenelubricants.com/2010/09/matching-palindromes-in-pcre-regex.html source])
<
function is_palindrome($string) {
return preg_match('/^(?:(.)(?=.*(\1(?(2)\2|))$))*.?\2?$/', $string);
}
?></
=={{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}}==
<
(= (setq S (chop S)) (reverse S)) )</
{{out}}
<pre>: (palindrome? "ingirumimusnocteetconsumimurigni")
Line 3,890 ⟶ 4,378:
=={{header|Pike}}==
<
if(pal("rotator")){
write("palindrome!\n");
Line 3,905 ⟶ 4,393:
return 0;
}
}</
=={{header|PL/I}}==
To satisfy the revised specification (which contradicts the preceding explanation)
the following trivially solves the problem in PL/I:
<
The following solution strips spaces:
<syntaxhighlight lang="text">is_palindrome: procedure (text) returns (bit(1));
declare text character (*) varying;
Line 3,930 ⟶ 4,418:
return (substr(text, 1, j));
end remove_blanks;
end is_palindrome;</
=={{header|PL/M}}==
<
/* CHECK EXACT PALINDROME ASSUMING $-TERMINATED STRING */
Line 4,013 ⟶ 4,501:
CALL BDOS(0,0);
EOF</
{{out}}
<pre>ROTOR: EXACT
Line 4,032 ⟶ 4,520:
<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.
<
Slap a substring on the string.
Loop.
Line 4,039 ⟶ 4,527:
Add 1 to the substring's first.
Subtract 1 from the substring's last.
Repeat.</
=={{header|Pointless}}==
'''Basic Function'''
<
chars == reverse(chars)</
'''With Pre-processing'''
<
"A man, a plan, a canal -- Panama"
|> toList
Line 4,053 ⟶ 4,541:
|> map(toLower)
|> isPalindrome
|> println</
{{out}}
Line 4,059 ⟶ 4,547:
=={{header|Potion}}==
<
palindrome_i = (s, b, e):
if (e <= b): true.
Line 4,069 ⟶ 4,557:
palindrome_i(s, 0, s length - 1).
palindrome(argv(1))</
=={{header|PowerBASIC}}==
Line 4,075 ⟶ 4,563:
The output is identical to the [[#BASIC|QBasic]] version, above.
<
DIM whatcopy AS STRING, chk AS STRING, tmp AS STRING * 1, L0 AS LONG
Line 4,106 ⟶ 4,594:
END IF
NEXT
END FUNCTION</
=={{header|PowerShell}}==
An exact version based on reversing the string:
<syntaxhighlight lang="powershell">
Function Test-Palindrome( [String] $Text ){
$CharArray = $Text.ToCharArray()
Line 4,116 ⟶ 4,604:
$Text -eq [string]::join('', $CharArray)
}
</syntaxhighlight>
===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">
function Test-Palindrome
{
Line 4,154 ⟶ 4,642:
$Text -match "^(?'char'[a-z])+[a-z]?(?:\k'char'(?'-char'))+(?(char)(?!))$"
}
</syntaxhighlight>
<syntaxhighlight lang="powershell">
Test-Palindrome -Text 'radar'
</syntaxhighlight>
{{Out}}
<pre>
True
</pre>
<syntaxhighlight lang="powershell">
Test-Palindrome -Text "In girum imus nocte et consumimur igni."
</syntaxhighlight>
{{Out}}
<pre>
False
</pre>
<syntaxhighlight lang="powershell">
Test-Palindrome -Text "In girum imus nocte et consumimur igni." -Inexact
</syntaxhighlight>
{{Out}}
<pre>
Line 4,178 ⟶ 4,666:
===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.
<
[CmdletBinding()]
Param(
Line 4,227 ⟶ 4,715:
}
}
'ánu-ná', 'nowt' | Test-Palindrome</
{{Out}}
<pre>
Line 4,239 ⟶ 4,727:
=={{header|Processing}}==
<
void setup(){
println(isPalindrome(InsertPalindromeHere));
Line 4,261 ⟶ 4,749:
}
}
</syntaxhighlight>
{{out}}
Line 4,269 ⟶ 4,757:
====Alternative Implementation: using StringBuilder, implementing exact and inexact check====
<
void setup(){
println("PalindromeDetection");
Line 4,309 ⟶ 4,797:
return isExactPalindrome(s.replaceAll("\\s+","").replaceAll("[^A-Za-z]+", "").toLowerCase());
}
</syntaxhighlight>
{{out}}
Line 4,332 ⟶ 4,820:
From [http://www2.dcs.hull.ac.uk/NEAT/dnd/AI/prolog/tutorial2.html this tutorial].
<
'''Recursive'''
{{works with|SWI Prolog}}
<
pali(Str) :- string_length(Str, Len), Len < 2.</
Changing '''string''' into '''atom''' makes the program run also on GNU Prolog. I.e.
Line 4,344 ⟶ 4,832:
{{works with|GNU Prolog}}
<
pali(Str) :- atom_length(Str, Len), Len < 2.</
=={{header|PureBasic}}==
{{works with|PureBasic|4.41}}
<
If StringToTest=ReverseString(StringToTest)
ProcedureReturn 1
Line 4,355 ⟶ 4,843:
ProcedureReturn 0
EndIf
EndProcedure</
=={{header|Python}}==
Line 4,366 ⟶ 4,854:
but right syntax <tt>string[::-1]</tt>)
<
return s == s[::-1]</
'''Non-recursive, Ignoring Punctuation/Case/Spaces'''
Line 4,373 ⟶ 4,861:
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.
<
low = 0
high = len(s) - 1
Line 4,387 ⟶ 4,875:
low += 1
high -= 1
return True</
'''Recursive'''
<
if len(s) <= 1:
return True
Line 4,397 ⟶ 4,885:
return False
else:
return is_palindrome_r(s[1:-1])</
Python has short-circuit evaluation of Boolean operations
so a shorter and still easy to understand recursive function is
<
return not s or s[0] == s[-1] and is_palindrome_r2(s[1:-1])</
'''Testing'''
<
assert all(f(x) for x in good)
assert not any(f(x) for x in bad)
Line 4,415 ⟶ 4,903:
notpals = ('aA', 'abA', 'abxBa', 'abxxBa')
for ispal in is_palindrome, is_palindrome_r, is_palindrome_r2:
test(ispal, pals, notpals)</
''' Palindrome Using Regular Expressions Python 2.7 '''
<
import re, string
re1="" # Beginning of Regex
Line 4,446 ⟶ 4,934:
else:
print("Nope!")
return 0</
'''Checking the left half against a reflection of the right half'''
<
Line 4,488 ⟶ 4,976:
if __name__ == '__main__':
main()
</syntaxhighlight>
{{out}}
<pre>'' -> True
Line 4,511 ⟶ 4,999:
-5 -4 -3 -2 -1 <-- negative index</pre>
<
for i in range(len(str)//2):
if str[i] != str[~i]:
return(False)
return(True)</
=={{header|Quackery}}==
<
[ [] swap witheach
Line 4,525 ⟶ 5,013:
dup lower = iff
drop else join ]
palindromic ] is inexactpalindrome ( $ --> b )</
===Twiddle Indexing===
<
dup size 2 / times
[ dup i peek
over i ~ peek != if
[ dip not conclude ] ]
drop ] is palindromic ( [ --> b )</
=={{header|R}}==
Line 4,542 ⟶ 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.
<
if ( nchar(p) == 1 ) {
return(TRUE)
Line 4,554 ⟶ 5,042:
}
}
}</
'''Iterative'''
<
for(i in 1:floor(nchar(p)/2) ) {
r <- nchar(p) - i + 1
Line 4,563 ⟶ 5,051:
}
TRUE
}</
'''Comparative'''
Line 4,571 ⟶ 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.
<
return(
paste(
Line 4,578 ⟶ 5,066:
)
}
palindroc <- function(p) {return(revstring(p)==p)}</
'''Rev'''
Line 4,585 ⟶ 5,073:
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.
<
{
characters <- unlist(strsplit(string, ""))
all(characters == rev(characters))
}</
{{out}}
The rev solution is not benchmarked.
Line 4,610 ⟶ 5,098:
=={{header|Racket}}==
<syntaxhighlight lang="racket">
(define (palindromb str)
(let* ([lst (string->list (string-downcase str))]
Line 4,625 ⟶ 5,113:
#t
>
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku"
.flip eq $_ given .comb(/\w+/).join.lc
}
Line 4,641 ⟶ 5,129:
END
for @tests { say $_ ~~ Palindrom, "\t", $_ }</
{{out}}
<pre>True A man, a plan, a canal: Panama.
Line 4,652 ⟶ 5,140:
=={{header|Rascal}}==
The most simple solution:
<
public bool palindrome(str text) = toLowerCase(text) == reverse(text);</
A solution that handles sentences with spaces and capitals:
<
public bool palindrome(str text){
Line 4,664 ⟶ 5,152:
return text == reverse(text);
}
</syntaxhighlight>
Example:
<
bool: true</
=={{header|REBOL}}==
<
Title: "Palindrome Recognizer"
URL: http://rosettacode.org/wiki/Palindrome
Line 4,700 ⟶ 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...?</
{{out}}
Line 4,716 ⟶ 5,204:
=={{header|Retro}}==
<syntaxhighlight lang="retro">
:palindrome? (s-f) dup s:hash [ s:reverse s:hash ] dip eq? ;
'ingirumimusnocteetconsumimurigni palindrome? n:put
</syntaxhighlight>
=={{header|Refal}}==
<syntaxhighlight lang="refal">$ENTRY Go {
= <Test 'rotor'>
<Test 'racecar'>
<Test 'RACEcar'>
<Test 'level'>
<Test 'rosetta'>
<Test 'A man, a plan, a canal: Panama'>
<Test 'Egad, a base tone denotes a bad age'>
<Test 'This is not a palindrome'>;
};
Test {
e.W, <Palindrome e.W> <InexactPalindrome e.W>: {
True s.1 = <Prout e.W ': exact palindrome'>;
s.1 True = <Prout e.W ': inexact palindrome'>;
False False = <Prout e.W ': not a palindrome'>;
};
};
InexactPalindrome {
e.W = <Palindrome <Filter ('ABCDEFGHIJKLMNOPQRSTUVWXYZ') <Upper e.W>>>;
};
Filter {
(e.Keep) = ;
(e.Keep) s.C e.W, e.Keep: {
e.1 s.C e.2 = s.C <Filter (e.Keep) e.W>;
e.1 = <Filter (e.Keep) e.W>;
};
};
Palindrome {
= True;
s.C = True;
s.C e.W s.C = <Palindrome e.W>;
e.X = False;
};</syntaxhighlight>
{{out}}
<pre>rotor: exact palindrome
marinus@frankenstein:~/refal$ refc palin && refgo palin
Refal-5 Compiler. Version PZ Jan 25 2024
Copyright: Refal Systems Inc.
rotor: exact palindrome
racecar: exact palindrome
RACEcar: inexact palindrome
level: exact palindrome
rosetta: not a palindrome
A man, a plan, a canal: Panama: inexact palindrome
Egad, a base tone denotes a bad age: inexact palindrome
This is not a palindrome: not a palindrome</pre>
=={{header|REXX}}==
===version 1===
<
parse arg y /*get (optional) phrase from the C.L. */
if y='' then y='In girum imus nocte et consumimur igni' /*[↓] translation.*/
Line 4,735 ⟶ 5,275:
/*────────────────────────────────────────────────────────────────────────────*/
isTpal: return reverse(arg(1))==arg(1)
isPal: return isTpal(translate(space(x,0)))</
{{out|output|text=''':'''}}
<pre>
Line 4,753 ⟶ 5,293:
It should also be noted that '''UPPER''' BIF is not present in some REXXes.
<br>Use the '''PARSE UPPER''' statement or '''TRANSLATE()''' BIF instead.
<syntaxhighlight lang="rexx">
/* REXX */
Line 4,768 ⟶ 5,308:
parse arg string
return string==reverse(string)
</syntaxhighlight>
{{out}}
<pre>
Line 4,777 ⟶ 5,317:
=={{header|Ring}}==
<
aString = "radar"
bString = ""
Line 4,786 ⟶ 5,326:
if aString = bString see " is a palindrome." + nl
else see " is not a palindrome" + nl ok
</syntaxhighlight>
=={{header|RPL}}==
≪ ""
OVER SIZE 1 '''FOR''' j
OVER j DUP SUB + -1 '''STEP'''
==
≫ ‘<span style="color:blue">XPAL?</span>’ STO
====Stretch====
RPL does not support Unicode. To detect inexact palindromes, we just need a clean-up word:
≪ ""
1 3 PICK SIZE '''FOR''' j
OVER j DUP SUB
'''IF''' DUP "a" ≥ OVER "z" ≤ AND '''THEN''' NUM 32 - CHR '''END'''
'''IF''' DUP "A" ≥ OVER "Z" ≤ AND '''THEN''' + '''ELSE''' DROP '''END'''
'''NEXT''' SWAP DROP
≫ ‘<span style="color:blue">AZONLY</span>’ STO
≪ <span style="color:blue">AZONLY</span> ""
OVER SIZE 1 '''FOR''' j
OVER j DUP SUB + -1 '''STEP'''
==
≫ ‘<span style="color:blue">IPAL?</span>’ STO
"rotor" <span style="color:blue">XPAL?</span>
"In girum imus nocte et consumimur igni." <span style="color:blue">IPAL?</span>
{{out}}
<pre>
2: 1
1: 1
</pre>
=={{header|Ruby}}==
'''Non-recursive'''
<
s == s.reverse
end</
'''Recursive'''
<
if s.length <= 1
true
Line 4,806 ⟶ 5,375:
r_palindrome?(s[1..-2])
end
end</
'''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:
<
puts palindrome?(str) # => true
puts r_palindrome?(str) # => true
Line 4,818 ⟶ 5,387:
b.report('iterative') {10000.times {palindrome?(str)}}
b.report('recursive') {10000.times {r_palindrome?(str)}}
end</
{{out}}
Line 4,826 ⟶ 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}}==
<
for i = 1 to 4
read w$
print w$;" is ";isPalindrome$(w$);" Palindrome"
next
for i = 1 to len(str$)
a$ = upper$(mid$(str$,i,1))
if (a$ >= "A" and a$ <= "Z") or (a$ >= "0" and a$ <= "9") then b$ = b$ + a$: c$ = a$ + c$
next i
if b$ <> c$ then isPalindrome$ = "not"
end function</syntaxhighlight>
{{out}}
<pre>My dog has fleas is not Palindrome
Line 4,848 ⟶ 5,460:
=={{header|Rust}}==
<
let half_len = string.len() / 2;
string
Line 4,872 ⟶ 5,484:
"The quick brown fox"
);
}</
{{out}}
<pre>
Line 4,886 ⟶ 5,498:
</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>.
<
use unicode_segmentation::UnicodeSegmentation;
fn is_palindrome(string: &str) -> bool {
string.graphemes(true).eq(string.graphemes(true).rev())
}</
=={{header|SAS}}==
Description
<syntaxhighlight lang="sas">
The macro "palindro" has two parameters: string and ignorewhitespace.
string is the expression to be checked.
Line 4,900 ⟶ 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>
Code
<syntaxhighlight lang="sas">
%MACRO palindro(string, ignorewhitespace);
DATA _NULL_;
Line 4,927 ⟶ 5,539:
RUN;
%MEND;
</syntaxhighlight>
Example macro call and output
<syntaxhighlight lang="sas">
%palindro("a man, a plan, a canal: panama",y);
Line 4,945 ⟶ 5,557:
real time 0.00 seconds
cpu time 0.00 seconds
</syntaxhighlight>
=={{header|Scala}}==
{{libheader|Scala}}
=== Non-recursive, robustified===
<
===Bonus: Detect and account for odd space and punctuation===
<
(s.size >= 2) && {
val p = s.replaceAll("[^\\p{L}]", "").toLowerCase
p == p.reverse
}
</syntaxhighlight>
===Recursive===
<
def isPalindromeRec(s: String) = {
Line 4,968 ⟶ 5,580:
(s.size >= 2) && inner(s)
}</
'''Testing'''
<
assert(!isPalindrome(""))
assert(!isPalindrome("z"))
Line 4,992 ⟶ 5,604:
assert(!isPalindromeRec("A man a plan a canal Panama."))
println("Successfully completed without errors.")</
=={{header|Scheme}}==
'''Non-recursive'''
<
(let ((chars (string->list s)))
(equal? chars (reverse chars))))</
'''Recursive'''
<
(let loop ((i 0)
(j (- (string-length s) 1)))
Line 5,021 ⟶ 5,633:
> (palindrome? "This is not a palindrome")
#f
></
=={{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}}==
<
result
var boolean: isPalindrome is TRUE;
Line 5,037 ⟶ 5,664:
end if;
end for;
end func;</
For palindromes where spaces shuld be ignore use:
<
=={{header|SequenceL}}==
'''Using the Reverse Library Function'''
<
isPalindrome(string(1)) := equalList(string, reverse(string));</
'''Version Using an Indexed Function'''
<
let
compares[i] := string[i] = string[size(string) - (i - 1)] foreach i within 1 ... (size(string) / 2);
in
all(compares);</
=={{header|Sidef}}==
'''Built-in'''
<
'''Non-recursive'''
<
s == s.reverse
}</
'''Recursive'''
<
if (s.len <= 1) {
true
}
elsif (s.first
false
}
else {
__FUNC__(s.
}
}</
=={{header|Simula}}==
<
BOOLEAN PROCEDURE ISPALINDROME(T); TEXT T;
Line 5,113 ⟶ 5,740:
END;
END.</
{{out}}
<pre>
Line 5,129 ⟶ 5,756:
=={{header|Slate}}==
'''Non-Recursive'''
<
[
(s lexicographicallyCompare: s reversed) isZero
].</
'''Recursive'''
Defined on Sequence since we are not using String-specific methods:
<
[
s isEmpty
ifTrue: [True]
ifFalse: [(s first = s last) /\ [(s sliceFrom: 1 to: s indexLast - 1) isPalindrome]]
].</
'''Testing'''
<
inform: 'sequence ' ; p ; ' is ' ; (p isPalindrome ifTrue: [''] ifFalse: ['not ']) ; 'a palindrome.'.</
=={{header|Smalltalk}}==
{{works with|Squeak}}
<
str := (aString select: [:chr| chr isAlphaNumeric]) collect: [:chr | chr asLowercase].
str = str reversed.
].
</syntaxhighlight>
{{works with|GNU Smalltalk}}
<
palindro [ "Non-recursive"
^ self = (self reverse)
Line 5,170 ⟶ 5,797:
]
]
].</
'''Testing'''
<
('hello' palindroR) printNl.
('ingirumimusnocteetconsumimurigni' palindro) printNl.
('ingirumimusnocteetconsumimurigni' palindroR) printNl.</
{{works with|VisualWorks Pharo Squeak}}
<
^self reverse = self
</syntaxhighlight>
=={{header|SNOBOL4}}==
<
pal str notany(&ucase &lcase) = :s(pal)
str = replace(str,&ucase,&lcase)
Line 5,202 ⟶ 5,829:
palchk('In girum imus nocte et consumimur igni')
palchk('The quick brown fox jumped over the lazy dogs')
end</
{{out}}
Line 5,211 ⟶ 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}}==
<
SELECT REVERSE(@txt) = @txt;</
=={{header|Swift}}==
{{works with|Swift|1.2}}
<
// Allow for easy character checking
Line 5,236 ⟶ 5,905:
}
return false
}</
{{works with|Swift|2.0}}
<
let c = str.characters
return lazy(c).reverse()
.startsWith(c[c.startIndex...advance(c.startIndex, c.count / 2)])
}</
=={{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 5,249 ⟶ 5,933:
'''Non-recursive'''
<
proc palindrome {s} {
return [expr {$s eq [string reverse $s]}]
}</
'''Recursive'''
<
if {[string length $s] <= 1} {
return true
Line 5,264 ⟶ 5,948:
return [palindrome_r [string range $s 1 end-1]]
}
}</
'''Testing'''
<
puts "'$p' is palindrome? [palindrome $p]"
puts "'$p' is palindrome? [palindrome_r $p]"</
=={{header|TUSCRIPT}}==
<
$$ MODE TUSCRIPT
pal ="ingirumimusnocteetconsumimurigni"
Line 5,283 ⟶ 5,967:
PRINT/ERROR "untrue"
ENDSELECT
</syntaxhighlight>
{{out}}
<pre>
Line 5,290 ⟶ 5,974:
=={{header|TypeScript}}==
<
function stripDiacritics(phrase:string){
Line 5,307 ⟶ 5,991:
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}}==
<
echo "Palindrome"
else
echo "Not a palindrome"
fi</
=={{header|Ursala}}==
Line 5,323 ⟶ 6,011:
This is done using the built in operator suffixes
for intersection (c), identity (i), reversal (x) and equality (E).
<
palindrome = ~&cixE\letters+ * -:~& ~=`A-~rlp letters</
This test programs applies the function to each member of a list of three strings,
of which only the first two are palindromes.
<
examples = palindrome* <'abccba','foo ba rra bo of','notone'></
{{out}}
<pre><true,true,false></pre>
Line 5,336 ⟶ 6,024:
=={{header|Vala}}==
Checks if a word is a palindrome ignoring the case and spaces.
<
var tmp = str.casefold ().replace (" ", "");
return tmp == tmp.reverse ();
Line 5,344 ⟶ 6,032:
print (is_palindrome (args[1]).to_string () + "\n");
return 0;
}</
=={{header|VBA}}==
Line 5,352 ⟶ 6,040:
version it could also work using StrReverse.
<syntaxhighlight lang="vba">
Public Function isPalindrome(aString as string) as Boolean
dim tempstring as string
Line 5,358 ⟶ 6,046:
isPalindrome = (tempstring = Reverse(tempstring))
End Function
</syntaxhighlight>
{{out|Example}}
Line 5,368 ⟶ 6,056:
=={{header|VBScript}}==
====Implementation====
<
dim sRes
sRes = vbNullString
Line 5,385 ⟶ 6,073:
squished = Squish( s1 )
isPalindrome = ( squished = StrReverse( squished ) )
end function</
====Invocation====
<
wscript.echo isPalindrome( "Madam, I'm Adam.")
wscript.echo isPalindrome( "1 on 1")
wscript.echo isPalindrome( "In girum imus nocte et consumimur igni")</
{{out}}
<pre>0
Line 5,401 ⟶ 6,089:
This routine checks if current line is a palindrome:
<
EOL #2 = Cur_Col-2
BOL
Line 5,407 ⟶ 6,095:
if (CC(#1) != CC(#2-#1)) { Return(0) }
}
Return(1)</
Testing:
<
if (Return_Value) {
Statline_Message("Yes")
Line 5,417 ⟶ 6,105:
Statline_Message("No")
}
Return</
=={{header|Visual Basic .NET}}==
{{trans|VBA}}
<
Function IsPalindrome(p As String) As Boolean
Line 5,432 ⟶ 6,120:
End Sub
End Module</
{{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}}==
<
; Using a hook
pal1 @(= @rev)
Line 5,449 ⟶ 6,178:
!pal3 "In girum imus nocte et consumimur igni"
]]
}</
Returns: <pre>[true false true]</pre>
=={{header|Wren}}==
<
System.print("Are the following palindromes?")
for (word in ["rotor", "rosetta", "step on no pets", "été", "wren", "🦊😀🦊"]) {
System.print(" %(word) => %(isPal.call(word))")
}</
{{out}}
Line 5,472 ⟶ 6,201:
=={{header|X86 Assembly}}==
<
; x86_84 Linux nasm
section .text
Line 5,508 ⟶ 6,237:
mov rax, 1
ret
</syntaxhighlight>
=={{header|XPL0}}==
<
string 0; \use zero-terminated strings
Line 5,536 ⟶ 6,265:
CrLf(0);
];
]</
{{out}}
Line 5,552 ⟶ 6,281:
is_palindrome (by changing case and stripping non-alphabetical characters).
<
s = strchar(str)(:-1);
return allof(s == s(::-1));
Line 5,561 ⟶ 6,290:
w = where(s >= 'a' & s <= 'z');
return strchar(s(w));
}</
=={{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}}==
<
if (text.len()<2) return(False);
text==text.reverse();
}
fcn pali2(text){ pali((text - " \t\n.,").toLower()) } // or whatever punctuation is</
{{out}}
<pre>
Line 5,577 ⟶ 6,531:
=={{header|Zoea}}==
<syntaxhighlight lang="zoea">
program: palindrome
case: 1
Line 5,594 ⟶ 6,548:
input: abc
output: false
</syntaxhighlight>
=={{header|Zoea Visual}}==
|