I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Longest palindromic substrings

Longest palindromic substrings is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Let given a string s. The goal is to find the longest palindromic substring in s.

## 11l

`F longest_palindrome(s)   V t = Array(‘^’s‘\$’).join(‘#’)   V n = t.len   V p =  * n   V c = 0   V r = 0   L(i) 1 .< n - 1      p[i] = (r > i) & min(r - i, p[2 * c - i]) != 0       L t[i + 1 + p[i]] == t[i - 1 - p[i]]         p[i]++       I i + p[i] > r         (c, r) = (i, i + p[i])    V (max_len, center_index) = max(enumerate(p).map((i, n) -> (n, i)))   R s[(center_index - max_len) I/ 2 .< (center_index + max_len) I/ 2] L(s) [‘three old rotators’,      ‘never reverse’,      ‘stable was I ere I saw elbatrosses’,      ‘abracadabra’,      ‘drome’,      ‘the abbatial palace’]   print(‘'’s‘' -> '’longest_palindrome(s)‘'’)`
Output:
```'three old rotators' -> 'rotator'
'never reverse' -> 'ever reve'
'stable was I ere I saw elbatrosses' -> 'table was I ere I saw elbat'
'drome' -> 'e'
'the abbatial palace' -> 'abba'
```

## ALGOL 68

Palindromes of length 1 or more are detected, finds the left most palindrome if there are several of the same length.
Treats upper and lower case as distinct and does not require the characters to be letters.

`BEGIN # find the longest palindromic substring of a string #    # returns the length of s #    OP   LENGTH = ( STRING s )INT: ( UPB s + 1 ) - LWB s;    # returns s right-padded with blanks to at least w characters or s if it is already wide enough #    PRIO PAD = 1;    OP   PAD = ( STRING s, INT w )STRING:         BEGIN            STRING result := s;            WHILE LENGTH result < w DO result +:= " " OD;            result         END # PAD # ;    # returns the longest palindromic substring of s #    #         if there are multiple substrings with the longest length, the leftmost is returned #    PROC longest palindromic substring = ( STRING s )STRING:         IF   LENGTH s < 2         THEN s         ELSE            INT lwb s = LWB s;            INT upb s = UPB s;            STRING result := s[ lwb s ];            IF s[ lwb s + 1 ] = s[ lwb s ] THEN                # the first two characters are a palindrome #                result +:= s[ lwb s + 1 ]            FI;            FOR i FROM lwb s + 1 TO upb s - 1 DO                INT  p start := i;                INT  p end   := i + 1;                IF  IF   s[ i - 1 ] = s[ i + 1 ] THEN                         # odd length palindrome at i - 1 #                         p start -:= 1;                         TRUE                    ELIF s[ i ] = s[ i + 1 ] THEN                         # even length palindrome at i #                         TRUE                    ELSE FALSE                    FI                THEN                    # have a palindrome at p start : p end #                    # attempt to enlarge the range #                    WHILE IF   p start = lwb s OR p end = upb s                          THEN FALSE                          ELSE s[ p start - 1 ] = s[ p end + 1 ]                          FI                    DO    # can extend he palindrome #                          p start -:= 1;                          p end   +:= 1                    OD;                    IF ( p end + 1 ) - p start > LENGTH result                    THEN                        # have a longer palindrome #                        result := s[ p start : p end ]                    FI                FI            OD;            result         FI # longest palindromic substring # ;    # finds the longest palindromic substring of s and checks it is the expacted value #    PROC test = ( STRING s, expected value )VOID:         BEGIN            STRING palindrome = longest palindromic substring( s );            print( ( ( """" + s + """" ) PAD 38, " -> ", ( """" + palindrome + """" ) PAD 36                   , IF palindrome = expected value THEN "" ELSE " NOT " + expected value + " ???" FI                   , newline                   )                 )         END # test longest palindromic substring # ;    test( "three old rotators",                 "rotator"                     );    test( "never reverse",                      "ever reve"                   );    test( "stable was I ere I saw elbatrosses", "table was I ere I saw elbat" );    test( "abracadabra",                        "aca"                         );    test( "drome",                              "d"                           );    test( "x",                                  "x"                           );    test( "the abbatial palace",                "abba"                        );    test( "",                                   ""                            );    test( "abcc",                               "cc"                          );    test( "abbccc",                             "ccc"                         )END`
Output:
```"three old rotators"                   -> "rotator"
"never reverse"                        -> "ever reve"
"stable was I ere I saw elbatrosses"   -> "table was I ere I saw elbat"
"drome"                                -> "d"
"x"                                    -> "x"
"the abbatial palace"                  -> "abba"
""                                     -> ""
"abcc"                                 -> "cc"
"abbccc"                               -> "ccc"
```

## AutoHotkey

`LPS(str){	found := [], result := [], maxL := 0	while (StrLen(str) >= 2 && StrLen(str) >= maxL){		s := str		loop {			while (SubStr(s, 1, 1) <> SubStr(s, 0))	; while 1st chr <> last chr				s := SubStr(s, 1, StrLen(s)-1)		; trim last chr			if (StrLen(s) < 2 || StrLen(s) < maxL )				break			if (s = reverse(s)){				found.Push(s)				maxL := maxL < StrLen(s) ? StrLen(s) : maxL				break			}			s := SubStr(s, 1, StrLen(s)-1)			; trim last chr		}		str := SubStr(str, 2)						; trim 1st chr and try again	}	maxL := 0	for i, str in found		maxL := maxL < StrLen(str) ? StrLen(str) : maxL	for i, str in found		if (StrLen(str) = maxL)			result.Push(str)	return result}reverse(s){	for i, v in StrSplit(s)		output := v output	return output}`
Examples:
`db =(three old rotatorsnever reversestable was I ere I saw elbatrossesabracadabradromexthe abbatial palace) for i, line in StrSplit(db, "`n", "`r"){	result := "[""", i := 0	for i, str in LPS(line)		result .= str """, """	output .= line "`t> " Trim(result, """, """) (i?"""":"") "]`n"}MsgBox % outputreturn`
Output:
```three old rotators			> ["rotator"]
never reverse				> ["ever reve"]
stable was I ere I saw elbatrosses	> ["table was I ere I saw elbat"]
drome					> []
x					> []
the abbatial palace			> ["abba"]
```

## F#

### Manacher Function

` // Manacher Function. Nigel Galloway: October 1st., 2020let Manacher(s:string) = let oddP,evenP=Array.zeroCreate s.Length,Array.zeroCreate s.Length                         let rec fN i g e (l:int[])=match g>=0 && e<s.Length && s.[g]=s.[e] with true->l.[i]<-l.[i]+1; fN i (g-1) (e+1) l |_->()                         let rec fGo n g Ʃ=match Ʃ<s.Length with                                            false->oddP                                           |_->if Ʃ<=g then oddP.[Ʃ]<-min (oddP.[n+g-Ʃ]) (g-Ʃ)                                               fN Ʃ (Ʃ-oddP.[Ʃ]-1) (Ʃ+oddP.[Ʃ]+1) oddP                                               match (Ʃ+oddP.[Ʃ])>g with true->fGo (Ʃ-oddP.[Ʃ]) (Ʃ+oddP.[Ʃ]) (Ʃ+1) |_->fGo n g (Ʃ+1)                         let rec fGe n g Ʃ=match Ʃ<s.Length with                                            false->evenP                                           |_->if Ʃ<=g then evenP.[Ʃ]<-min (evenP.[n+g-Ʃ]) (g-Ʃ)                                               fN Ʃ (Ʃ-evenP.[Ʃ]) (Ʃ+evenP.[Ʃ]+1) evenP                                               match (Ʃ+evenP.[Ʃ])>g with true->fGe (Ʃ-evenP.[Ʃ]+1) (Ʃ+evenP.[Ʃ]) (Ʃ+1) |_->fGe n g (Ʃ+1)                         (fGo 0 -1 0,fGe 0 -1 0) `

` let fN g=if g=[||] then (0,0) else g|>Array.mapi(fun n g->(n,g))|>Array.maxBy sndlet lpss s=let n,g=Manacher s in let n,g=fN n,fN g in if (snd n)*2+1>(snd g)*2 then s.[(fst n)-(snd n)..(fst n)+(snd n)] else s.[(fst g)-(snd g)+1..(fst g)+(snd g)]let test = ["three old rotators"; "never reverse"; "stable was I ere I saw elbatrosses"; "abracadabra"; "drome"; "the abbatial palace"; ""]test|>List.iter(fun n->printfn "A longest palindromic substring of \"%s\" is \"%s\"" n (lpss n)) `
Output:
```A longest palindromic substring of "three old rotators" is "rotator"
A longest palindromic substring of "never reverse" is "ever reve"
A longest palindromic substring of "stable was I ere I saw elbatrosses" is "table was I ere I saw elbat"
A longest palindromic substring of "abracadabra" is "aca"
A longest palindromic substring of "drome" is "d"
A longest palindromic substring of "the abbatial palace" is "abba"
A longest palindromic substring of "" is ""
```

## Go

Translation of: Wren
`package main import (    "fmt"    "sort") func reverse(s string) string {    var r = []rune(s)    for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {        r[i], r[j] = r[j], r[i]    }    return string(r)} func longestPalSubstring(s string) []string {    var le = len(s)    if le <= 1 {        return []string{s}    }    targetLen := le    var longest []string    i := 0    for {        j := i + targetLen - 1        if j < le {            ss := s[i : j+1]            if reverse(ss) == ss {                longest = append(longest, ss)            }            i++        } else {            if len(longest) > 0 {                return longest            }            i = 0            targetLen--        }    }    return longest} func distinct(sa []string) []string {    sort.Strings(sa)    duplicated := make([]bool, len(sa))    for i := 1; i < len(sa); i++ {        if sa[i] == sa[i-1] {            duplicated[i] = true        }    }    var res []string    for i := 0; i < len(sa); i++ {        if !duplicated[i] {            res = append(res, sa[i])        }    }    return res} func main() {    strings := []string{"babaccd", "rotator", "reverse", "forever", "several", "palindrome", "abaracadaraba"}    fmt.Println("The palindromic substrings having the longest length are:")    for _, s := range strings {        longest := distinct(longestPalSubstring(s))        fmt.Printf("  %-13s Length %d -> %v\n", s, len(longest), longest)    }}`
Output:
```The palindromic substrings having the longest length are:
babaccd       Length 3 -> [aba bab]
rotator       Length 7 -> [rotator]
reverse       Length 5 -> [rever]
forever       Length 5 -> [rever]
several       Length 3 -> [eve]
palindrome    Length 1 -> [a d e i l m n o p r]
```

A list version, written out of curiosity. A faster approach could be made with an indexed datatype.

`-------------- LONGEST PALINDROMIC SUBSTRINGS ------------ longestPalindromes :: String -> ([String], Int)longestPalindromes [] = ([], 0)longestPalindromes s = go \$ palindromes s  where    go xs      | null xs = (return <\$> s, 1)      | otherwise = (filter ((w ==) . length) xs, w)      where        w = maximum \$ length <\$> xs palindromes :: String -> [String]palindromes = fmap go . palindromicNuclei  where    go (pivot, (xs, ys)) =      let suffix = fmap fst (takeWhile (uncurry (==)) (zip xs ys))      in reverse suffix <> pivot <> suffix palindromicNuclei :: String -> [(String, (String, String))]palindromicNuclei =  concatMap go .  init . tail . ((zip . scanl (flip ((<>) . return)) []) <*> scanr (:) [])  where    go (a@(x:_), b@(h:y:ys))      | x == h = [("", (a, b))]      | otherwise =        [ ([h], (a, y : ys))        | x == y ]    go _ = []  --------------------------- TEST -------------------------main :: IO ()main =  putStrLn \$  fTable    "Longest palindromic substrings:\n"    show    show    longestPalindromes    [ "three old rotators"    , "never reverse"    , "stable was I ere I saw elbatrosses"    , "abracadabra"    , "drome"    , "the abbatial palace"    , ""    ] ------------------------ FORMATTING ----------------------fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> StringfTable s xShow fxShow f xs =  unlines \$  s : fmap (((++) . rjust w ' ' . xShow) <*> ((" -> " ++) . fxShow . f)) xs  where    rjust n c = drop . length <*> (replicate n c ++)    w = maximum (length . xShow <\$> xs)`
Output:
```Longest palindromic substrings:

"three old rotators" -> (["rotator"],7)
"never reverse" -> (["ever reve"],9)
"stable was I ere I saw elbatrosses" -> (["table was I ere I saw elbat"],27)
"drome" -> (["d","r","o","m","e"],1)
"the abbatial palace" -> (["abba"],4)
"" -> ([],0)```

## Julia

`function allpalindromics(s)    list, len = String[], length(s)    for i in 1:len-1, j in i+1:len        substr = s[i:j]        if substr == reverse(substr)            push!(list, substr)        end    end    return listend for teststring in ["babaccd", "rotator", "reverse", "forever", "several", "palindrome"]    list = sort!(allpalindromics(teststring), lt = (x, y) -> length(x) < length(y))    println(isempty(list) ? "No palindromes of 2 or more letters found in \"\$teststring." :        "The longest palindromic substring of \$teststring is: \"",        join(list[findall(x -> length(x) == length(list[end]), list)], "\" or \""), "\"")end `
Output:
```The longest palindromic substring of babaccd is: "bab" or "aba"
The longest palindromic substring of rotator is: "rotator"
The longest palindromic substring of reverse is: "rever"
The longest palindromic substring of forever is: "rever"
The longest palindromic substring of several is: "eve"
No palindromes of 2 or more letters found in "palindrome."
```

### Manacher algorithm

` function manacher(str)    s =  "^" * join(split(str, ""), "#") * "\\$"    len = length(s)    pals = fill(0, len)    center, right = 1, 1    for i in 2:len-1        pals[i] = right > i && right - i > 0 && pals[2 * center - i] > 0        while s[i + pals[i] + 1] == s[i - pals[i] - 1]            pals[i] += 1        end        if i + pals[i] > right            center, right = i, i + pals[i]        end    end    maxlen, centerindex = findmax(pals)    start = isodd(maxlen) ? (centerindex-maxlen) ÷ 2 + 1 : (centerindex-maxlen) ÷ 2    return str[start:(centerindex+maxlen)÷2]end for teststring in ["babaccd", "rotator", "reverse", "forever", "several", "palindrome", "abaracadabra"]    pal = manacher(teststring)    println(length(pal) < 2 ? "No palindromes of 2 or more letters found in \"\$teststring.\"" :        "The longest palindromic substring of \$teststring is: \"\$pal\"")end `
Output:
```The longest palindromic substring of babaccd is: "aba"
The longest palindromic substring of rotator is: "rotator"
The longest palindromic substring of reverse is: "rever"
The longest palindromic substring of forever is: "rever"
The longest palindromic substring of several is: "eve"
No palindromes of 2 or more letters found in "palindrome."
The longest palindromic substring of abaracadabra is: "ara"
```

## Nim

Simple algorithm but working on Unicode code points.

`import sequtils, strutils, unicode func isPalindrome(s: seq[Rune]): bool =  ## Return true if a sequence of runes is a palindrome.  for i in 1..(s.len shr 1):    if s[i - 1] != s[^i]:      return false  result = true func lps(s: string): seq[string] =  var maxLength = 0  var list: seq[seq[Rune]]  let r = s.toRunes  for first in 0..r.high:    for last in first..r.high:      let candidate = r[first..last]      if candidate.isPalindrome():        if candidate.len > maxLength:          list = @[candidate]          maxLength = candidate.len        elif candidate.len == maxLength:          list.add candidate  if maxLength > 1:    result = list.mapIt(\$it) for str in ["babaccd", "rotator", "several", "palindrome", "piété", "tantôt", "étêté"]:  let result = lps(str)  if result.len == 0:    echo str, " → ", "<no palindromic substring of two of more letters found>"  else:    echo str, " → ", result.join(", ")`
Output:
```babaccd → bab, aba
rotator → rotator
several → eve
palindrome → <no palindromic substring of two of more letters found>
piété → été
tantôt → tôt
étêté → étêté```

## Perl

The short one - find all palindromes with one regex.

`#!/usr/bin/perl use strict; # https://rosettacode.org/wiki/Longest_palindromic_substringsuse warnings; print "Longest Palindrome For \$_ = @{[ longestpalindrome(\$_) ]}\n"  for qw(babaccd rotator reverse forever several palindrome abaracadabra); sub longestpalindrome  {  my @best = {"''" => 0};  pop =~ /(.+) .? (??{reverse \$1}) (?{ \$best[length \$&]{\$&}++ }) (*FAIL)/x;  keys %{pop @best};  }`
Output:
```Longest Palindrome For babaccd = aba bab
Longest Palindrome For rotator = rotator
Longest Palindrome For reverse = rever
Longest Palindrome For forever = rever
Longest Palindrome For several = eve
Longest Palindrome For palindrome = ''
```

The faster one - does the million digits of Pi in under half a second.

`#!/usr/bin/perl use strict; # https://rosettacode.org/wiki/Longest_palindromic_substringsuse warnings; #@ARGV = 'pi.dat'; # uncomment to use this file or add filename to command line my \$forward = lc do { local \$/; @ARGV ? <> : <DATA> };\$forward =~ s/\W+//g; my \$range = 10;my \$backward = reverse \$forward;my \$length = length \$forward;my @best = {"''" => 0};my \$len;for my \$i ( 1 .. \$length - 2 )  {  do    {    my \$right = substr \$forward, \$i, \$range;    my \$left = substr \$backward, \$length - \$i, \$range;    ( \$right ^ \$left ) =~ /^\0\0+/ and                                # evens      (\$len = 2 * length \$&) >= \$#best and      \$best[ \$len ]{substr \$forward, \$i - length \$&, \$len}++;    ( \$right ^ "\0" . \$left ) =~ /^.(\0+)/ and                        # odds      (\$len = 1 + 2 * length \$1) >= \$#best and      \$best[ \$len ]{substr \$forward, \$i - length \$1, \$len}++;    } while \$range < \$#best and \$range = \$#best;  }print "Longest Palindrome (\$#best) : @{[ keys %{ \$best[-1] } ]}\n"; __DATA__this data borrowed from raku... Never odd or evenWas it a car or a cat I saw?Too bad I hid a bootI, man, am regal - a German am ItootWarsaw was raw`
Output:
```Longest Palindrome (27) : ootimanamregalagermanamitoo
```

## Phix

Translation of: Raku
```-- demo/rosetta/Longest_palindromic_substrings.exw (plus two older versions)
with javascript_semantics
function longest_palindromes(string s)
--  s = lower/strip_spaces_and_punctuation/utf8_to_utf32, if rqd
integer longest = 2 -- (do not treat length 1 as palindromic)
--  integer longest = 1 -- (do not treat length 0 as palindromic) [works just fine too]
sequence res = {}
for i=1 to length(s) do
for j=0 to iff(i>1 and s[i-1]=s[i]?2:1) do
integer rev = j,
fwd = 1
while rev<i and i+fwd<=length(s) and s[i-rev]=s[i+fwd] do
rev += 1
fwd += 1
end while
string p = s[i-rev+1..i+fwd-1]
integer lp = length(p)
if lp>=longest then
if lp>longest then
longest = lp
res = {p}
elsif not find(p,res) then -- (or just "else")
res = append(res,p)
end if
end if
end for
end for
return res -- (or "sort(res)" or "unique(res)", as needed)
end function

for i=1 to length(tests) do
printf(1,"%s: %v\n",{tests[i],longest_palindromes(tests[i])})
end for
```
Output:
```babaccd: {"bab","aba"}
rotator: {"rotator"}
reverse: {"rever"}
forever: {"rever"}
several: {"eve"}
palindrome: {}
abbbc: {"bbb"}
```

with longest initialised to 1, you get the same except for `palindrome: {"p","a","l","i","n","d","r","o","m","e"}`

## Python

Defines maximal expansions of any two or three character palindromic nuclei in the string.

(This version ignores case but allows non-alphanumerics).

`'''Longest palindromic substrings'''  # longestPalindrome :: String -> ([String], Int)def longestPalindromes(s):    '''All palindromes of the maximal length       drawn from a case-flattened copy of       the given string, tupled with the       maximal length.       Non-alphanumerics are included here.    '''    k = s.lower()    palindromes = [        palExpansion(k)(ab) for ab        in palindromicNuclei(k)    ]    maxLength = max([        len(x) for x in palindromes    ]) if palindromes else 1    return (        [            x for x in palindromes if maxLength == len(x)        ] if palindromes else list(s),        maxLength    ) if s else ([], 0)  # palindromicNuclei :: String -> [(Int, Int)]def palindromicNuclei(s):    '''Ranges of all the 2 or 3 character       palindromic nuclei in s.    '''    cs = list(s)    return [        # Two-character nuclei.        (i, 1 + i) for (i, (a, b))        in enumerate(zip(cs, cs[1:]))        if a == b    ] + [        # Three-character nuclei.        (i, 2 + i) for (i, (a, b, c))        in enumerate(zip(cs, cs[1:], cs[2:]))        if a == c    ]  # palExpansion :: String -> (Int, Int) -> Stringdef palExpansion(s):    '''Full expansion of the palindromic       nucleus with the given range in s.    '''    iEnd = len(s) - 1     def limit(ij):        i, j = ij        return 0 == i or iEnd == j or s[i-1] != s[j+1]     def expansion(ij):        i, j = ij        return (i - 1, 1 + j)     def go(ij):        ab = until(limit)(expansion)(ij)        return s[ab:ab + 1]    return go  # ------------------------- TEST -------------------------# main :: IO ()def main():    '''Longest palindromic substrings'''    print(        fTable(main.__doc__ + ':\n')(repr)(repr)(            longestPalindromes        )([            'three old rotators',            'never reverse',            'stable was I ere I saw elbatrosses',            'abracadabra',            'drome',            'the abbatial palace',            ''        ])    )  # ----------------------- GENERIC ------------------------ # until :: (a -> Bool) -> (a -> a) -> a -> adef until(p):    '''The result of repeatedly applying f until p holds.       The initial seed value is x.    '''    def go(f):        def g(x):            v = x            while not p(v):                v = f(v)            return v        return g    return go  # ---------------------- FORMATTING ---------------------- # fTable :: String -> (a -> String) -># (b -> String) -> (a -> b) -> [a] -> Stringdef fTable(s):    '''Heading -> x display function -> fx display function ->       f -> xs -> tabular string.    '''    def gox(xShow):        def gofx(fxShow):            def gof(f):                def goxs(xs):                    ys = [xShow(x) for x in xs]                    w = max(map(len, ys))                     def arrowed(x, y):                        return y.rjust(w, ' ') + ' -> ' + (                            fxShow(f(x))                        )                    return s + '\n' + '\n'.join(                        map(arrowed, xs, ys)                    )                return goxs            return gof        return gofx    return gox  # MAIN ---if __name__ == '__main__':    main()`
Output:
```Longest palindromic substrings:

'three old rotators' -> (['rotator'], 7)
'never reverse' -> (['ever reve'], 9)
'stable was I ere I saw elbatrosses' -> (['table was i ere i saw elbat'], 27)
'drome' -> (['d', 'r', 'o', 'm', 'e'], 1)
'the abbatial palace' -> (['abba'], 4)
'' -> ([], 0)```

## Raku

Works with: Rakudo version 2020.09

This version regularizes (ignores) case and ignores non alphanumeric characters. It is only concerned with finding the longest palindromic substrings so does not exhaustively find all possible palindromes. If a palindromic substring is found to be part of a longer palindrome, it is not captured separately. Showing the longest 5 palindromic substring groups. Run it with no parameters to operate on the default; pass in a file name to run it against that instead.

`my @chars = ( @*ARGS ?? @*ARGS.IO.slurp !! q:to/BOB/ ) .lc.comb: /\w/;    Lyrics to "Bob" copyright Weird Al Yankovic    https://www.youtube.com/watch?v=JUQDzj6R3p4     I, man, am regal - a German am I    Never odd or even    If I had a hi-fi    Madam, I'm Adam    Too hot to hoot    No lemons, no melon    Too bad I hid a boot    Lisa Bonet ate no basil    Warsaw was raw    Was it a car or a cat I saw?     Rise to vote, sir    Do geese see God?    "Do nine men interpret?" "Nine men," I nod    Rats live on no evil star    Won't lovers revolt now?    Race fast, safe car    Pa's a sap    Ma is as selfless as I am    May a moody baby doom a yam?     Ah, Satan sees Natasha    No devil lived on    Lonely Tylenol    Not a banana baton    No "x" in "Nixon"    O, stone, be not so    O Geronimo, no minor ego    "Naomi," I moan    "A Toyota's a Toyota"    A dog, a panic in a pagoda     Oh no! Don Ho!    Nurse, I spy gypsies - run!    Senile felines    Now I see bees I won    UFO tofu    We panic in a pew    Oozy rat in a sanitary zoo    God! A red nugget! A fat egg under a dog!    Go hang a salami, I'm a lasagna hog!    BOB#" my @cpfoa = flat(1 ..^ @chars).race(:1000batch).map: -> \idx {    my @s;    for 1, 2 {       my int (\$rev, \$fwd) = \$_, 1;       loop {            quietly last if (\$rev > idx) || (@chars[idx - \$rev] ne @chars[idx + \$fwd]);            \$rev = \$rev + 1;            \$fwd = \$fwd + 1;        }        @s.push: @chars[idx - \$rev ^..^ idx + \$fwd].join if \$rev + \$fwd > 2;        last if @chars[idx - 1] ne @chars[idx];    }    next unless +@s;    @s} "{.key} ({+.value})\t{.value.unique.sort}".put for @cpfoa.classify( *.chars ).sort( -*.key ).head(5);`
Output:

Returns the length, (the count) and the list:

```29 (2)	doninemeninterpretninemeninod godarednuggetafateggunderadog
26 (1)	gohangasalamiimalasagnahog
23 (1)	arwontloversrevoltnowra
21 (4)	imanamregalagermanami mayamoodybabydoomayam ootnolemonsnomelontoo oozyratinasanitaryzoo
20 (1)	ratsliveonnoevilstar
```

This isn't intensively optimised but isn't too shabby either. When run against the first million digits of pi: 1000000 digits of pi text file (Pass in the file path/name at the command line) we get:

```13 (1)	9475082805749
12 (1)	450197791054
11 (8)	04778787740 09577577590 21348884312 28112721182 41428782414 49612121694 53850405835 84995859948
10 (9)	0045445400 0136776310 1112552111 3517997153 5783993875 6282662826 7046006407 7264994627 8890770988
9 (98)	019161910 020141020 023181320 036646630 037101730 037585730 065363560 068363860 087191780 091747190 100353001 104848401 111262111 131838131 132161231 156393651 160929061 166717661 182232281 193131391 193505391 207060702 211878112 222737222 223404322 242424242 250171052 258232852 267919762 272636272 302474203 313989313 314151413 314424413 318272813 323212323 330626033 332525233 336474633 355575553 357979753 365949563 398989893 407959704 408616804 448767844 450909054 463202364 469797964 479797974 480363084 489696984 490797094 532121235 546000645 549161945 557040755 559555955 563040365 563828365 598292895 621969126 623707326 636414636 636888636 641949146 650272056 662292266 667252766 681565186 684777486 712383217 720565027 726868627 762727267 769646967 777474777 807161708 819686918 833303338 834363438 858838858 866292668 886181688 895505598 896848698 909565909 918888819 926676629 927202729 929373929 944525449 944848449 953252359 972464279 975595579 979202979 992868299```

in right around 7 seconds on my system.

## REXX

`/*REXX program finds and displays the  longest palindromic string(s) in a given string. */parse arg s                                      /*obtain optional argument from the CL.*/if s==''|s==","  then s='babaccd rotator reverse forever several palindrome abaracadaraba'                                                 /* [↑] the case of strings is respected*/    do i=1  for words(s);          x= word(s, i) /*obtain a string to be examined.      */    L= length(x);                  m= 0          /*get the string's length; Set max len.*/                  do LL=2  for L-1               /*start with palindromes of length two.*/                  if find(1)  then m= max(m, LL) /*Found a palindrome?  Set M=new length*/                  end   /*LL*/    LL= max(1, m)    call find 0                                  /*find all palindromes with length  LL.*/    say ' longest palindromic substrings for string: '        x    say '────────────────────────────────────────────'copies('─', 2 + L)          do n=1  for words(@)                   /*show longest palindromic substrings. */          say '    (length='LL")  "  word(@, n)  /*display a         "      substring.  */          end   /*n*/;       say;    say         /*display a two─blank separation fence.*/    end         /*i*/exit 0                                           /*stick a fork in it,  we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/find: parse arg short                            /*if SHORT==1,  only find 1 palindrome.*/      @=                                         /*initialize palindrome list to a null.*/        do j=1  for L-LL+1;  \$= substr(x, j, LL) /*obtain a possible palindromic substr.*/        if \$\==reverse(\$)  then iterate          /*Not a palindrome?       Then skip it.*/        @= @ \$                                   /*add a palindromic substring to a list*/        if short  then return 1                  /*we have found  one   palindrome.     */        end   /*j*/;   return 0                  /* "   "    "    some  palindrome(s).  */`
output   when using the default input:
``` longest palindromic substrings for string:  babaccd
─────────────────────────────────────────────────────
(length=3)   bab
(length=3)   aba

longest palindromic substrings for string:  rotator
─────────────────────────────────────────────────────
(length=7)   rotator

longest palindromic substrings for string:  reverse
─────────────────────────────────────────────────────
(length=5)   rever

longest palindromic substrings for string:  forever
─────────────────────────────────────────────────────
(length=5)   rever

longest palindromic substrings for string:  several
─────────────────────────────────────────────────────
(length=3)   eve

longest palindromic substrings for string:  palindrome
────────────────────────────────────────────────────────
(length=1)   p
(length=1)   a
(length=1)   l
(length=1)   i
(length=1)   n
(length=1)   d
(length=1)   r
(length=1)   o
(length=1)   m
(length=1)   e

longest palindromic substrings for string:  abaracadaraba
───────────────────────────────────────────────────────────
(length=3)   aba
(length=3)   ara
(length=3)   aca
(length=3)   ara
(length=3)   aba
```

## Ring

` load "stdlib.ring" st = "babaccd"palList = [] for n = 1 to len(st)-1    for m = n+1 to len(st)        sub = substr(st,n,m-n)        if ispalindrome(sub) and len(sub) > 1           add(palList,[sub,len(sub)])        ok    nextnext palList = sort(palList,2)palList = reverse(palList)resList = []add(resList,palList) for n = 2 to len(palList)    if palList = palList[n]       add(resList,palList[n])    oknext see "Input: " + st + nlsee "Longest palindromic substrings:" + nlsee resList `
Output:
```Input: babaccd
Longest palindromic substrings:
bab
aba
```

## Wren

Library: Wren-seq
Library: Wren-fmt

I've assumed that the expression 'substring' includes the string itself and that substrings of length 1 are considered to be palindromic. Also that if there is more than one palindromic substring of the longest length, then all such distinct ones should be returned.

The Phix entry examples have been used.

`import "/seq" for Lstimport "/fmt" for Fmt var longestPalSubstring = Fn.new { |s|    var len = s.count    if (len <= 1) return [s]    var targetLen = len    var longest = []    var i = 0    while (true) {        var j = i + targetLen - 1        if (j < len) {            var ss = s[i..j]            if (ss == ss[-1..0]) longest.add(ss)            i = i + 1        } else {            if (longest.count > 0) return longest            i = 0            targetLen = targetLen - 1        }    }} var strings = ["babaccd", "rotator", "reverse", "forever", "several", "palindrome", "abaracadaraba"]System.print("The palindromic substrings having the longest length are:")for (s in strings) {    var longest = Lst.distinct(longestPalSubstring.call(s))    Fmt.print("  \$-13s Length \$d -> \$n", s, longest.count, longest)}`
Output:
```The palindromic substrings having the longest length are:
babaccd       Length 3 -> [bab, aba]
rotator       Length 7 -> [rotator]
reverse       Length 5 -> [rever]
forever       Length 5 -> [rever]
several       Length 3 -> [eve]
palindrome    Length 1 -> [p, a, l, i, n, d, r, o, m, e]