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.