Task: Longest palindromic substrings




Go: 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[0]), longest)
    }
}




Python: 



def longestPalindromes(s):
    
    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)



def palindromicNuclei(s):
    
    cs = list(s)
    return [
        
        (i, 1 + i) for (i, (a, b))
        in enumerate(zip(cs, cs[1:]))
        if a == b
    ] + [
        
        (i, 2 + i) for (i, (a, b, c))
        in enumerate(zip(cs, cs[1:], cs[2:]))
        if a == c
    ]



def palExpansion(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[0]:ab[1] + 1]
    return go




def main():
    
    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',
            ''
        ])
    )





def until(p):
    
    def go(f):
        def g(x):
            v = x
            while not p(v):
                v = f(v)
            return v
        return g
    return go






def fTable(s):
    
    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



if __name__ == '__main__':
    main()