Localizando "sub-palíndromos".

24

O código mais curto que encontra todos os "subpalíndromos" exclusivos de uma sequência, ou seja: qualquer substring com comprimento> 1 que seja um palíndromo.

eg.1

input: "12131331"
output: "33", "121", "131", "313", "1331"

eg.2

input: "3333"
output: "33", "333", "3333"
Eelvex
fonte
11
Uma string pode ser seu próprio sub-palíndromo? Como uma string é sua própria substring.
precisa saber é o seguinte
@JPvdMerwe: Sim, é claro.
Eelvex 29/01
Na verdade, o mais importante: qual deve ser a saída 333? Ingenuamente você acaba imprimindo 33duas vezes
JPvdMerwe
@JPvdMerwe: '333' -> '33', '333'. Vou editar a pergunta de acordo. Obrigado.
Ejetx 29/01
Como a saída é especificada? Delimitados por vírgula com aspas são encontrados em cada sub-palíndromo, como você demonstra aqui? Um sub-p por linha?
Joey

Respostas:

11

J, 24 31 40

~.(#~(1<#*]-:|.)&>),<\\.

Uso da amostra:

   ~.(#~(1<#*]-:|.)&>),<\\. '12131331'
┌───┬───┬───┬────┬──┐
│121│131│313│1331│33│
└───┴───┴───┴────┴──┘
   ~.(#~(1<#*]-:|.)&>),<\\. '3333'
┌──┬───┬────┐
│33│333│3333│
└──┴───┴────┘

Tome isso, GolfScript!

JB
fonte
Admiti-lo, basta colocar um despejo de /dev/randomaqui para nos enganar ;-)
Joey
@Joey experimentar por si próprio; p (TBH, eu não acreditava que poderia funcionar tanto em primeira)
JB
Tenho certeza de que é um código real. Passei um fim de semana tentando entender J, mas falhei miseravelmente. Ainda assim, reconheço código; Eu só não entendo o que ele faz ;-)
Joey
2
Não pode ser reduzido para ~.(#~(1<#*]-:|.)&>),<\\.(24 caracteres)?
Ephemient 4/04/12
@hemhemient De fato. (Parece que fiquei preso na mentalidade "a resposta deve ser uma função", que não se aplica aqui.) Editado, obrigado!
JB
7

Python 124

r=raw_input()
l=range(len(r))
print', '.join(set('"'+r[i:j+1]+'"'for i in l for j in l if i<j and r[i:j+1]==r[i:j+1][::-1]))
Alexandru
fonte
5

Haskell 98, 88 91 96

import List
main=interact$show.filter(\x->length x>1&&x==reverse x).nub.(tails=<<).inits
JB
fonte
3

Python - 138 136

Este código não duplica sub-palíndromos.

r=raw_input()
i,l=0,len(r)
j=l
a=[]
while i<l-1:
 t=r[i:j];j-=1
 if t==t[::-1]:a+=['"'+t+'"']
 if j<i+2:i+=1;j=l
print", ".join(set(a))
JPvdMerwe
fonte
11
Mude '"'+t+'"'para tpara economizar espaço, embora use aspas simples.
Thomas O
3

Ruby - 126 102 97 caracteres

s=gets
*m=*0..s.size
puts m.product(m).map{|h,j|(c=s[h,j+1]).size>1&&c==c.reverse ? c:0}.uniq-[0]
Nemo157
fonte
3

Golfscript, 48 caracteres

subpalindrome.gs

{,}{(;}/{{,}{);}/}%{+}*{.,1>\.-1%=*},.&{`}%", "*

Uso:

echo "12131331" | ruby golfscript.rb subpalindrome.gs

A primeira operação {,}{(;}/transforma uma string em uma lista de substrings finais. Uma transformação de substrings principais semelhante é mapeada sobre o resultado. Em seguida, aplane com {+}*, filtre os palíndromos usando o predicado .,1>\.-1%=*, obtenha valores exclusivos .&e depois imprima.

Seria melhor extrair a transformação de substrings finais como um bloco e reutilizá-los como um substituto para substrings principais depois de reverter cada substring final, mas não consigo descobrir uma maneira sucinta de fazer isso.

roobs
fonte
2

Haskell - 170 , 153

import Data.List
import Data.Set
p a=fromList$[show x|x<-subsequences a,x==reverse x,length x>1]
main=getLine>>=(\x->putStrLn$intercalate", "$toList$p x)
Jonathan Sternberg
fonte
Substitua main=getLine>>=(\x->putStrLn$intercalate", "$toList$p x)por main=getLine>>=putStrLn.intercalate", ".toList.p. Eu também substituiria uma ligação pcom seu corpo.
Yasir Arsanukaev
Substrings / = subsequences! Seu programa relata mais subpalíndromos do que a saída de referência, por exemplo 1. ("1111", por exemplo)
JB
2

J, 48

f=:,@:".
h=:\\.
~.(#~10&<)((]h-:"0&f|.h)#[:f]h)

por exemplo

~.(#~10&<)((]h-:"0&f|.h)#[:f]h) '12131331'
121 131 313 1331 33
Eelvex
fonte
2

Prolog, 92

f(S,P):-append([_,X,_],S),X=[_,_|_],reverse(X,X),atom_codes(P,X).
p(S,R):-setof(P,f(S,P),R).

Uso da amostra:

?- p("12131331",R).
R = ['121', '131', '1331', '313', '33'].

?- p("3333",R).
R = ['33', '333', '3333'].
JB
fonte
2

Windows PowerShell, 104 109 111

0..($l=($s="$input").length-1)|%{($a=$_)..$l|%{-join$s[$a..$_]}}|sort -u|?{$_[1]-and$_-eq-join$_[$l..0]}

Isso espera a entrada no stdin e lançará todos os palíndromos encontrados um por linha no stdout:

PS Home:\SVN\Joey\Public\SO\CG183> '12131331'| .\subp.ps1
33
121
131
313
1331

(Quando executado, cmdele se torna echo 12131331|powershell -file subp.ps1- é apenas que $inputassume um significado ligeiramente diferente, dependendo de como o script foi chamado, mas pode ser stdin, mas não de maneira interativa.)

2011-01-30 13:57 (111) - Primeira tentativa.

2011-01-30 13:59 (109) - Declaração variável embutida.

02-06-2011 13:18 (104) - Refone a descoberta de substring juntando-se a uma matriz char em vez de chamar .Substring()e inline um pouco mais.

Joey
fonte
2

Q, 78

{a::x;(?)(,/)b@'(&:')({x~(|:)x}'')b:-1_1_'({(sublist[;a]')x,'1+c}')c::(!)(#)a}

uso

q){a::x;(?)(,/)b@'(&:')({x~(|:)x}'')b:-1_1_'({(sublist[;a]')x,'1+c}')c::(!)(#)a}"12131331"
"121"
"131"
"313"
"1331"
"33"
q){a::x;(?)(,/)b@'(&:')({x~(|:)x}'')b:-1_1_'({(sublist[;a]')x,'1+c}')c::(!)(#)a}"3333"
"33"
"333"
"3333"
tmartin
fonte
2

Retina , 34 27 bytes

&@!`(.)+.?(?<-1>\1)+(?(1)^)

Experimente online!

O conjunto de testes precisa de um Mporque é seguido por outro estágio para inserir linhas vazias entre os casos de teste.

Explicação

&@!`(.)+.?(?<-1>\1)+(?(1)^)

Imprima ( !) todas as correspondências exclusivas ( @), sobrepostas ( &) da regex (.)+.?(?<-1>\1)+(?(1)^). Isso corresponde a um palíndromo de comprimento 2 ou mais usando grupos de balanceamento. Há uma ressalva na parte "todas as partidas sobrepostas": podemos obter no máximo uma partida por posição inicial. No entanto, se dois palíndromos de comprimento diferente começarem na mesma posição, o palíndromo mais curto aparecerá novamente no final do palíndromo mais longo. E como a ganância de +priorizar correspondências mais longas, estamos recebendo todos os palíndromos de qualquer maneira.

Martin Ender
fonte
2

05AB1E , 11 10 bytes

ŒÙʒÂQ}žQSK

Experimente online!

Urna de polvo mágico
fonte
11
9 bytes
scottinet
@scottinet falha para solteiros, EG1234142141410010101000
Magic Octopus Urn
11
Seu também, mas não da mesma maneira. o_O Há algo acontecendo que precisa de investigação. Enquanto isso, aqui está uma versão de 10 bytes que parece funcionar
scottinet
Houve um erro com uniquify, eu consertei. Agora ambos os seus 11 bytes responder e meu 9 bytes um trabalho :-)
scottinet
@ scottinet Seu 10-byter também pode ser de 9-byter mudando 1›para . :)
Kevin Cruijssen
1

Perl, 112

$_=<>;chop;s/./$&$' /g;
map{/../&&$_ eq reverse&&$h{$_}++}split/ /
  for grep{s/./$`$& /g}split/ /;
print for keys %h
novo
fonte
1

JavaScript (ES6), 120 bytes

a=>{for(b=0,c=d=a.length,e=[];b<d;--c<b+2?(b++,c=d):1)(f=a.slice(b,c))==f.split``.reverse().join``&&e.push(f);return e}

Esta função pega uma string como entrada e gera uma matriz.

Luke
fonte
1

Clojure, 81 bytes

#(set(for[i(range 2(+(count %)1))p(partition i 1 %):when(=(reverse p)(seq p))]p))

forfoi uma combinação perfeita aqui :) Poderia usar :when(=(reverse p)p)se a entrada fosse uma lista de caracteres OU uma sequência completa não contasse como um palíndromo, na verdade, nesse caso, o intervalo máximo de também ipoderia ser (count %).

Estojo mais compacto para referência:

#(set(for[i(range 2(count %))p(partition i 1 %):when(=(reverse p)p)]p))
NikoNyrh
fonte
1

Python, 83 102 caracteres

s=lambda t:(t[1:]or())and(t,)*(t==t[::-1])+s(t[1:])+s(t[:-1])
print set(s(input()))

A frase (t[1:]or())and...é equivalente (...)if t[1:]else()e salva um caractere! Estou muito orgulhoso disso, dada a economia.

Exemplo:

python x
"51112232211161"
set(['11', '22', '11122322111', '161', '111', '112232211', '1223221', '22322', '232'])
boothby
fonte
1

Scala 127

object p extends App{val s=args(0);print(2.to(s.size).flatMap(s.sliding(_).toSeq.filter(c=>c==c.reverse)).toSet.mkString(" "))}

Para manter essa comparação de maçãs com maçãs com a outra resposta do Scala, também fiz do meu um objeto que estende o App. Em vez de iterar a sequência de entrada manualmente e usar substring, aproveitei o slide () para criar uma sequência de todas as substrings para mim.

bkuder
fonte
1

Scala 156 170

object o extends App{val l=args(0).length-2;val r=for(i<-0 to l;j<-i to l;c=args(0).substring(i,j+2);if(c==c.reverse))yield c;print(r.toSet.mkString(" "))}

object o{def main(s:Array[String]){val l=s(0).length-2;val r=for(i<-0 to l;j<-i to l;c=s(0).substring(i,j+2);if(c==c.reverse)) yield c;println(r.distinct.mkString(" "))}}

Lalith
fonte
Oi Lalith, eu encurtado seu código um pouco: No branco antes rendimento e estendendo App em vez de substituir principal, println => print e distinta => Toset
desconhecido utilizador
1

Perl 6 ,  35  32 bytes

{unique m:ex/(.+).?<{$0.flip}>/}

Teste-o

{set m:ex/(.+).?<{$0.flip}>/}

Teste-o

Expandido:

{  # bare block lambda with implicit parameter 「$_」

  set             # turn into a Set object (ignores duplicates)

  \             # stringify 「~」 all of these 「«」 (possibly in parrallel)
                  # otherwise it would be a sequence of Match objects

  m               # match
  :exhaustive     # in every way possible
  /
    ( .+ )        # at least one character 「$0」
    .?            # possibly another character (for odd sized sub-palindromes)
    <{ $0.flip }> # match the reverse of the first grouping
  /
}
Brad Gilbert b2gills
fonte
1

Geléia , 9 bytes

ẆQŒḂÐfḊÐf

Experimente online!

Erik, o Outgolfer
fonte
A saída do seu link permanente está incorreta.
Dennis
@ Dennis por que isso se torne um alvo dupe seguida> _> fixo
Erik o Outgolfer
7 bytes com o novo Jelly.
User202729 de
1

APL (Dyalog Classic) , 27 bytes

{∪⍵/⍨≡∘⌽¨⍨⍵}∘⊃(,/1↓⍳∘≢,/¨⊂)

Experimente online!

{∪⍵/⍨≡∘⌽¨⍨⍵}∘⊃(,/1↓⍳∘≢,/¨⊂)    Monadic train:
                                Enclose the input, '12131331'
                     ⍳∘≢          Range from 1 to length of input
                     ⍳∘≢,/¨⊂      List of list of substrings of each length
                   1            Remove the first list (length-1 substrings)
                ,/              Put the rest of the substrings into a single list.
{∪⍵/⍨≡∘⌽¨⍨⍵}                   To the result, apply this function which
                                   keeps all palindromes from a list:
      ≡∘⌽¨⍨⍵                    Boolean value of whether each (¨) string in argument
      ≡∘⌽                      is equal to its own reverse

  ⍵/⍨                           Replicate (filter) argument by those values.
                                 This yields the length >1 palindromes.
                                Remove duplicates from the list of palindromes.
lirtosiast
fonte
Devido à OP chamada por "código", o snippet ∪w/⍨≡∘⌽¨⍨w←⊃,/1↓(⍳∘≢,/¨⊂)é válido.
Adám 07/02
@ Adám Acho que vou manter essa resposta, pois é uma questão de padrões modernos de sites, especialmente porque ela não obtém a vitória geral.
lirtosiast
1

Japonês , 14 bytes

Êò2@ãX fêSÃc â

Experimente online!

Explicação:

Êò2               #Get the range [2...length(input)]
   @      Ã       #For each number in that range:
    ãX            # Get the substrings of the input with that length
       fêS        # Keep only the palindromes
           c      #Flatten
             â    #Keep unique results
Kamil Drakari
fonte
1

PowerShell , 99 bytes

$args|% t*y|%{$s+=$_
0..$n|%{if($n-$_-and($t=-join$s[$_..$n])-eq-join$s[$n..$_]){$t}}
$n++}|sort -u

Experimente online!

Menos golfe:

$args|% toCharArray|%{
    $substring+=$_
    0..$n|%{
        if( $n-$_ -and ($temp=-join$substring[$_..$n]) -eq -join$substring[$n..$_] ){
            $temp
        }
    }
    $n++
}|sort -Unique
confuso
fonte
1

Braquilog , 11 bytes

{s.l>1∧.↔}ᵘ

Experimente online!

(O cabeçalho do link está quebrado no momento da postagem, então aqui está o predicado (função equivalente no Brachylog) apenas no primeiro caso de teste, com um wno final para realmente imprimir a saída.)

               The output is
{        }ᵘ    a list containing every possible unique
 s.            substring of
               the input
   l           the length of which
    >          is greater than
     1         one
      ∧        and
       .       which
        ↔      reversed
               is itself. (implicit output within the inline sub-predicate)

Sinto que há uma maneira mais curta de verificar se o comprimento é maior que 1. (Se não filtrasse palíndromos triviais, seria apenas {s.↔}ᵘ).

String não relacionada
fonte
1

APL (NARS), 65 caracteres, 130 bytes

{0=≢m←∪b/⍨{1≥≢⍵:0⋄∧/⍵=⌽⍵}¨b←↑∪/{x[⍵;]⊂y}¨⍳≢x←11 1‼k k⊢k←≢y←⍵:⍬⋄m}

teste:

  r←{0=≢m←∪b/⍨{1≥≢⍵:0⋄∧/⍵=⌽⍵}¨b←↑∪/{x[⍵;]⊂y}¨⍳≢x←11 1‼k k⊢k←≢y←⍵:⍬⋄m}
  o←⎕fmt
  o r '1234442'
┌2───────────┐
│┌2──┐ ┌3───┐│
││ 44│ │ 444││
│└───┘ └────┘2
└∊───────────┘
  o r '3333'
┌3───────────────────┐
│┌4────┐ ┌3───┐ ┌2──┐│
││ 3333│ │ 333│ │ 33││
│└─────┘ └────┘ └───┘2
└∊───────────────────┘
  o r  "12131331"
┌5─────────────────────────────────┐
│┌4────┐ ┌3───┐ ┌2──┐ ┌3───┐ ┌3───┐│
││ 1331│ │ 121│ │ 33│ │ 313│ │ 131││
│└─────┘ └────┘ └───┘ └────┘ └────┘2
└∊─────────────────────────────────┘
  o r '1234'
┌0─┐
│ 0│
└~─┘


{0=≢m←∪b/⍨{1≥≢⍵:0⋄∧/⍵=⌽⍵}¨b←↑∪/{x[⍵;]⊂y}¨⍳≢x←11 1‼k k⊢k←≢y←⍵:⍬⋄m}
 y←⍵  assign the argument to y (because it has to be used inside other function)
 x←11 1‼k k⊢k←≢y   assign the lenght of y to k, call the function 11 1‼k k
                   that seems here find all partition of 1 2 ..k
 {x[⍵;]⊂y}¨⍳≢      make partition of arg ⍵ using that set x
 ∪/                set union with precedent to each element of partition y (i don't know if this is ok)
 b←↑               get first assign to b
 {1≥≢⍵:0⋄∧/⍵=⌽⍵}¨ for each element of b return 1 only if the argument ⍵ is such that 
                   "∧/⍵=⌽⍵" ⍵ has all subset palindrome, else return 0
 b/⍨               get the elements in b for with {1≥≢⍵:0⋄∧/⍵=⌽⍵} return 1
 m←∪               make the set return without ripetition element, and assign to m
 0=≢               if lenght of m is 0 (void set) than 
 :⍬⋄m              return ⍬ else return m

alguém sabe melhor o porquê e pode explicar isso melhor, livre de alterações, tudo isso ... Não tenho tanta certeza desse código, possível se os exemplos de teste forem mais numerosos, algo vai dar errado ...

RosLuP
fonte
1

Japonês , 9 bytes

ã â fÅfêU

Tente

ã â fÅfêU     :Implicit input of string
ã             :Substrings
  â           :Deduplicate
    f         :Filter elements that return truthy
     Å        :  Slice off first character
       f      :Filter elements that return true
        êU    :  Test for palindrome
Shaggy
fonte
0

Java 8, 202 201 199 bytes

import java.util.*;s->{Set r=new HashSet();String x;for(int l=s.length(),i=0,j;i<l;i++)for(j=i;++j<=l;)if((x=s.substring(i,j)).contains(new StringBuffer(x).reverse())&x.length()>1)r.add(x);return r;}

Experimente aqui.

Se uma função não for permitida e um programa completo for necessário, serão 256 255 253 bytes :

import java.util.*;interface M{static void main(String[]a){Set r=new HashSet();String x;for(int l=a[0].length(),i=0,j;i<l;i++)for(j=i;++j<=l;)if((x=a[0].substring(i,j)).contains(new StringBuffer(x).reverse())&x.length()>1)r.add(x);System.out.print(r);}}

Experimente aqui.

Explicação:

import java.util.*;      // Required import for Set and HashSet

s->{                     // Method with String parameter and Set return-type
  Set r=new HashSet();   //  Return-Set
  String t;              //  Temp-String
  for(int l=s.length(),  //  Length of the input-String
          i=0,j;         //  Index-integers (start `i` at 0)
      i<l;i++)           //  Loop (1) from `0` to `l` (exclusive)
    for(j=i;++j<=l;)     //   Inner loop (2) from `i+1` to `l` (inclusive)
      if((t=s.substring(i,j) 
                         //    Set `t` to the substring from `i` to `j` (exclusive)
         ).contains(new StringBuffer(t).reverse())
                         //    If this substring is a palindrome,
         &t.length()>1)  //    and it's length is larger than 1:
        r.add(t);        //     Add the String to the Set
                         //   End of inner loop (2) (implicit / single-line body)
                         //  End of loop (1) (implicit / single-line body)
  return r;              //  Return the result-Set
}                        // End of method
Kevin Cruijssen
fonte
0

JavaScript (ES6), 107 bytes

Retorna um conjunto .

s=>new Set((g=(s,r=[...s].reverse().join``)=>s[1]?(r==s?[s]:[]).concat(g(s.slice(1)),g(r.slice(1))):[])(s))

Casos de teste

Arnauld
fonte