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"

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!


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]))

5

Haskell 98, 88 91 96

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

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))

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]

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.


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)

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

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'].

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.


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"

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.


2

05AB1E , 11 10 bytes

ŒÙʒÂQ}žQSK

Experimente online!



@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

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.


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))

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'])

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.


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(" "))}}


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
  /
}



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.

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

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

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.↔}ᵘ).


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 ...


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

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

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.