Trovare "sotto-palindromi".


24

Il codice più breve che trova tutti i "sotto-palindromi" univoci di una stringa, ovvero: qualsiasi sottostringa con lunghezza> 1 che sia un palindromo.

eg.1

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

eg.2

input: "3333"
output: "33", "333", "3333"

1
Una stringa può essere il suo proprio sotto-palindromo? Poiché una stringa è la sua sottostringa.
JPvd Merwe

@JPvdMerwe: Sì, certo.
Eelvex,

In realtà, cosa ancora più importante: quale deve essere l'output di 333essere? Ingenuamente finiresti per stampare 33due volte
JPvd Merwe

@JPvdMerwe: '333' -> '33', '333'. Modificherò la domanda di conseguenza. Grazie.
Eelvex,

Come viene specificato l'output? Virgolette con virgolette sono presenti in ogni sotto-palindromo come si dimostra qui? Una sub-p per riga?
Joey,

Risposte:


11

J, 24 31 40

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

Esempio di utilizzo:

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

Prendi questo, GolfScript!


Ammettilo, hai appena messo una discarica da /dev/randomqui per ingannarci ;-)
Joey,

@Joey provalo tu stesso; p (TBH, all'inizio non credevo che potesse funzionare neanche)
JB

Sono abbastanza sicuro che sia il codice attuale. Ho trascorso un fine settimana cercando di avvolgere la testa attorno a J, ma ho fallito miseramente. Riconosco ancora il codice; Semplicemente non capisco cosa faccia ;-)
Joey,

2
Non può essere abbreviato in ~.(#~(1<#*]-:|.)&>),<\\.(24 caratteri)?
effimero

@ephemient Lo fa davvero. (Sembra che fossi bloccato nella mentalità "la risposta deve essere una funzione", che non si applica qui.) Modificato, grazie!
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

Questo codice non duplica i sotto-palindromi.

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

1
Passare '"'+t+'"'a tper risparmiare spazio, sebbene utilizzi virgolette singole.
Thomas O

3

Rubino - 126 102 97 caratteri

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 caratteri

subpalindrome.gs

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

Uso:

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

La prima operazione {,}{(;}/trasforma una stringa in un elenco di sottostringhe finali. Una trasformazione simile di sottostringhe iniziali viene quindi mappata sul risultato. Quindi appiattisci con {+}*, filtra i palindromi usando il predicato .,1>\.-1%=*, prendi valori univoci con .&, quindi stampa carina.

Sarebbe più ordinato estrarre la trasformazione delle sottostringhe finali come blocco e riutilizzarla come sostituto delle sottostringhe principali dopo aver invertito ciascuna sottostringa finale, ma non riesco a capire un modo breve per farlo.


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)

Sostituisci main=getLine>>=(\x->putStrLn$intercalate", "$toList$p x)con main=getLine>>=putStrLn.intercalate", ".toList.p. Vorrei anche sostituire una chiamata pcon il suo corpo.
Yasir Arsanukaev,

Sottostringhe / = subsequences! Il tuo programma riporta più sottopalindromi rispetto all'output di riferimento per esempio 1. ("1111" per esempio)
JB

2

J, 48

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

per esempio

~.(#~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).

Esempio di utilizzo:

?- 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]}

Questo si aspetta l'input su stdin e lancerà tutti i palindromi trovati uno per riga su stdout:

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

(Quando eseguito da cmdesso diventa echo 12131331|powershell -file subp.ps1- è solo che $inputha un significato leggermente diverso a seconda di come è stato chiamato lo script, ma può essere stdin, semplicemente non interattivamente.)

30/01/2011 13:57 (111) - Primo tentativo.

30/01/2011 13:59 (109) - Dichiarazione di variabili incorporata.

2011-06-02 13:18 (104) - Rifatto della ricerca della sottostringa unendo un array di caratteri invece di chiamare .Substring()e inline un po 'di più.


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 byte

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

Provalo online!

La suite di test ha bisogno di un Mperché è seguita da un'altra fase per inserire righe vuote tra i casi di test.

Spiegazione

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

Stampa ( !) tutte le corrispondenze univoche ( @), sovrapposte ( &) del regex (.)+.?(?<-1>\1)+(?(1)^). Questo corrisponde a un palindromo di lunghezza 2 o più utilizzando gruppi di bilanciamento. C'è un avvertimento nella parte "tutte le partite sovrapposte": possiamo ottenere al massimo una partita per posizione di partenza. Tuttavia, se due palindromi di diversa lunghezza iniziano nella stessa posizione, il palindromo più breve apparirà di nuovo alla fine del palindromo più lungo. E dal momento che l'avidità delle +priorità corrisponde a partite più lunghe, otteniamo comunque tutti i palindromi.


2

05AB1E , 11 10 byte

ŒÙʒÂQ}žQSK

Provalo online!



@scottinet fallisce per i single, EG1234142141410010101000
Magic Octopus Urn

1
Anche il tuo, ma non allo stesso modo. o_O Sta succedendo qualcosa che ha bisogno di essere investigato. Nel frattempo, ecco una versione da 10 byte che sembra funzionare
scottinet il

Si è verificato un errore con uniquify, l'ho risolto. Ora entrambi i tuoi 11 byte rispondono e i miei 9 byte uno funzionano :-)
scottinet,

@scottinet Il tuo 10 byte può essere anche un 9 byte cambiando 1›in . :)
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 byte

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}

Questa funzione accetta una stringa come input e genera un array.


1

Clojure, 81 byte

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

forè stata una corrispondenza perfetta qui :) Potrebbe essere utile :when(=(reverse p)p)se l'input fosse un elenco di caratteri O una stringa completa non contasse come un palindromo, in realtà in quel caso anche l'intervallo massimo di ipotrebbe essere (count %).

Custodia più compatta per riferimento:

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

1

Python, 83 102 caratteri

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

La frase (t[1:]or())and...equivale a (...)if t[1:]else()e salva un personaggio! Ne sono troppo orgoglioso, visti i risparmi.

Esempio:

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

Per mantenere questo confronto tra mele e mele con l'altra risposta alla Scala, ho anche reso il mio un oggetto che estende l'App. Invece di iterare manualmente la stringa di input e utilizzare la sottostringa, ho sfruttato scorrevole () per creare una sequenza di tutte le sottostringhe per me.


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


Ciao Lalith, ho abbreviato un po 'il tuo codice: nessuno spazio vuoto prima di cedere ed estendere l'App invece di sovrascrivere main, println => print e distinto => toSet
utente sconosciuto

1

Perl 6 ,  35  32 byte

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

Provalo

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

Provalo

Allargato:

{  # 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 byte

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

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

A causa della chiamata OP per "codice", lo snippet ∪w/⍨≡∘⌽¨⍨w←⊃,/1↓(⍳∘≢,/¨⊂)è valido.
Adám,

@ Adám Penso che terrò questa risposta per il bene dei moderni standard del sito, soprattutto perché non ottiene la vittoria complessiva.
Lirtosiast

1

Japt , 14 byte

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

Provalo online!

Spiegazione:

Êò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 byte

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

Provalo online!

Meno golf:

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

1

Brachylog , 11 byte

{s.l>1∧.↔}ᵘ

Provalo online!

(L'intestazione nel link è rotta al momento della pubblicazione, quindi ecco il predicato (equivalente di funzione in Brachylog) solo sul primo caso di test, con un walla fine per stampare effettivamente l'output.)

               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)

Sento che c'è un modo più breve per verificare che la lunghezza sia maggiore di 1. (Se non filtrasse i banali palindromi, sarebbe solo {s.↔}ᵘ.)


1

APL (NARS), 65 caratteri, 130 byte

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

test:

  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

qualcuno sa meglio perché, e può spiegarlo meglio, senza cambiare tutto ... Non sono così sicuro di questo codice, possibile se gli esempi di test sono più numerosi, qualcosa andrà storto ...


1

Japt , 9 byte

ã â fÅfêU

Provalo

ã â 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 byte

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

Provalo qui.

Se una funzione non è consentita ed è richiesto un programma completo, è invece 256 255 253 byte :

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

Provalo qui.

Spiegazione:

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 byte

Restituisce un set .

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

Casi test

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.