Un puzzle semi-palindromo


23

Un palindromo è una parola che è il suo contrario.

Ora ci sono alcune parole che potrebbero sembrare palindromi ma non lo sono. Ad esempio, considera la parola sheesh, sheeshnon è un palindromo perché il suo contrario è hseehsche è diverso, tuttavia se consideriamo shuna singola lettera, allora è il contrario sheesh. Questo tipo di parola chiameremo un semi-palindromo.

In particolare una parola è un semi-palindromo se possiamo dividere la parola in un certo numero di blocchi in modo tale che quando l'ordine dei blocchi viene invertito, si forma la parola originale. (Per sheeshquei pezzi lo sono sh e e sh) Inoltre non richiederemo che nessun pezzo contenga lettere di entrambe le metà della parola (altrimenti ogni parola sarebbe un semi-palindromo). Ad esempio rearnon è un semi-palindromo perché r ea rha un pezzo ( ea) che contiene lettere da entrambi i lati della parola originale. Consideriamo il carattere centrale in una parola di lunghezza dispari che non si trova su entrambi i lati della parola, quindi per le parole di lunghezza dispari il carattere centrale deve essere sempre nel suo blocco.

Il tuo compito sarà quello di prendere un elenco di numeri interi positivi e determinare se sono semi-palindromi. Il codice dovrebbe generare due valori diseguali coerenti, uno se l'input è un semi-palindromo e l'altro in caso contrario. Tuttavia, la sequenza di byte del codice deve essere un semi-palindromo stesso.

Le risposte verranno classificate in byte con un numero inferiore di byte migliori.

Casi test

[] -> True
[1] -> True
[2,1,2] -> True
[3,4,2,2,3,4] -> True
[3,5,1,3,5] -> True
[1,2,3,1] -> False
[1,2,3,3,4,1] -> False
[11,44,1,1] -> False
[1,3,2,4,1,2,3] -> False

Programma per generare più testcase.


Borrible ha sottolineato che questi sono simili ai palindromi generalizzati di Smarandache . Quindi, se vuoi fare qualche ulteriore lettura, questo è un punto da cui iniziare.


2
Perché hai definito i semi-palindromi usando le stringhe ma i tuoi input sono array di numeri interi? Oltre ad essere confuso, questo significa che non possiamo testare il nostro codice sorgente usando il nostro programma.
BradC,

@BradC Palindromi e simili sono spesso spiegati in termini di parole, poiché è un po 'più facile farlo.
Erik the Outgolfer,

Le stringhe @BradC tendono a introdurre casi di bordi strani, in particolare in termini di caratteri vs byte. Scelgo il numero perché sono più semplici. Ho pensato che le parole sarebbero state più facili a scopo di spiegazione.
Wheat Wizard

2
Questi tipi di palindromi sono noti come Palindromi generalizzati di Smarandache in letteratura.
orribile

1
@RosLuP Sì, i palindromi "veri" sono anche semi-palindromi, basta trattare ogni carattere / intero com'è senza nessun "chunking" aggiuntivo.
BradC,

Risposte:


6

Retina 0.8.2 , 85 69 byte

M`^(.+,)*(\d+,)?(?<-1>\1)*$(?(1)^)|M`^(.+,)*(\d+,)?(?<-1>\1)*$(?(1)^)

Provalo online! Spiegazione:

M`

Seleziona la modalità Match. In effetti, Retina passa automaticamente alla modalità Match per un programma a riga singola, ma la seconda copia del codice corrisponderebbe sempre se non per questi caratteri extra.

^

La partita deve iniziare all'inizio.

(.+,)*

Cattura un numero di serie di personaggi. Ogni corsa deve terminare con una virgola.

(\d+,)?

Facoltativamente, abbina una serie di cifre e una virgola.

(?<-1>\1)*

Facoltativamente, abbina tutte le acquisizioni in ordine inverso, facendo scattare ciascuna mentre viene abbinata.

$

La partita deve terminare alla fine.

(?(1)^)

Backtrack a meno che non siano state scattate tutte le catture. Funziona richiedendo che la corrispondenza sia ancora all'inizio della stringa se abbiamo una cattura non trattata, il che è impossibile.


5

Gelatina , 27 23 byte

ṖUṁ@Ƒ€ṚẸHḢŒŒHḢŒṖUṁ@Ƒ€ṚẸ

Restituisce 1 per semi-palindromi, 0 altrimenti.

Provalo online!

Come funziona

ṖUṁ@Ƒ€ṚẸHḢŒŒHḢŒṖUṁ@Ƒ€ṚẸ  Main link. Argument: A (array)

          Œ              Invalid token. Everything to its left is ignored.
           ŒH            Halve; divide A into two halves similar lengths. The middle
                         element (if there is one) goes into the first half.
             Ḣ           Head; extract the first half.
              ŒṖ         Generate all partitions of the first half.
                U        Upend; reverse each chunk of each partition.
                         Let's call the result C.

                     Ṛ   Yield R, A reversed.
                   Ƒ€    Fixed each; for each array P in C, call the link to the left
                         with arguments P and R.
                         Return 1 if the result is P, 0 if not.
                 ṁ@          Mold swapped; replace the n integers of C, in reading
                             order, with the first n integers of R.
                     Ẹ   Exists; check if one of the calls returned 1.

4

Python 2 , 157 153 147 143 byte

-4 byte grazie a tsh .

s=lambda x,i=0:len(x)<2or[]<x[i:]and(x[-i:]==x[:i])&s(x[i:-i])|s(x,i+1)
s=lambda x,i=0:len(x)<2or[]<x[i:]and(x[-i:]==x[:i])&s(x[i:-i])|s(x,i+1)

Provalo online!


1
Cambia x==x[::-1]per len(x)<2salvare 2 * 2 byte; 143 byte
tsh

4

05AB1E , 59 47 43 41 byte

2äøø€.œ`âʒ`RQ}gĀIg_^q2äøø€.œ`âʒ`RQ}gĀIg_^

-12 byte grazie a @Emigna .

Provalo online o verifica tutti i casi di test .

Spiegazione:

2ä               # Split the input into two parts
                 #  i.e. [3,4,2,0,2,3,4] → [[3,4,2,0],[2,3,4]]
  øø             # Zip twice without filler
                 # This will remove the middle item for odd-length inputs
                 #  i.e. [[3,4,2,0],[2,3,4]] → [[3,2],[4,3],[2,4]] → [[3,4,2],[2,3,4]]
    €.œ          #  Then take all possible partitions for each inner list
                 #   i.e. [[3,4,2],[2,3,4]]
                 #    → [[[[3],[4],[2]],[[3],[4,2]],[[3,4],[2]],[[3,4,2]]],
                 #       [[[2],[3],[4]],[[2],[3,4]],[[2,3],[4]],[[2,3,4]]]]
`                # Push both lists of partitions to the stack
 â               # Take the cartesian product (all possible combinations) of the partitions
                 #  i.e. [[[[3],[4],[2]],[[2],[3],[4]]],
                 #        [[[3],[4],[2]],[[2],[3,4]]],
                 #        ...,
                 #        [[[3,4,2]],[[2,3,4]]]]
  ʒ   }          # Filter this list of combinations by:
   `             #  Push both parts to the stack
    RQ           #  Check if the second list reversed, is equal to the first
                 #   i.e. [[3,4],[2]] and [[2],[3,4]] → 1 (truthy)
       gĀ        # After the filter, check if there are any combinations left
                 #  i.e. [[[[3,4],[2]],[[2],[3,4]]]] → 1 (truthy)
         Ig_     # Check if the length of the input was 0 (empty input-list edge-case)
                 #  i.e. [3,4,2,0,2,3,4] → 7 → 0 (falsey)
            ^    # Bitwise-XOR
                 #  i.e. 1 XOR 0 → 1 (truthy)
             q   # Stop the program (and then implicitly output the top of the stack)
2äøø€.œ`âʒ`RQ}gĀIg_^
                 # Everything after the `q` are no-ops to comply to the challenge rules

Puoi aggirare il problema con elenchi di lunghezza dispari con øøε.œ} `, risparmiando 6 byte. Sembra anche che tu abbia lasciato 30 byte inutilizzati in ...
Emigna,

@Emigna i no-ops alla fine devono rispettare il requisito di fonte limitata della sfida
Kamil Drakari,

@KamilDrakari: Oh giusto. Ho dimenticato quella parte. La buona notizia è che il salvataggio di 6 byte sarà di 12 byte allora :)
Emigna,

@Emigna Molto intelligente con il trucco a doppia zip. Non ero contento di quella parte, ma è molto meglio! A proposito, poiché l'Elisir riscrive i comandi a 2 byte possono essere usati con invece di ε }. :)
Kevin Cruijssen,

@KevinCruijssen: Ah fantastico. Non lo sapevo.
Emigna,

4

05AB1E , 37 byte

Utilizza approssimativamente la stessa tecnica inventata da Jonathan .

.œʒ€gηOZ;îå}εÂQ}ZĀqĀZ}QÂε}åî;ZOηg€ʒ.œ

Provalo online!


.œʒ€gηOZ;îå}εÂQ}ZĀqĀZ}QÂε}åî;ZOηg€ʒ.œ

Programma completo. Riceve un elenco da STDIN, invia 1 o 0 a STDOUT.

.œʒ        }

Filtra-mantieni le partizioni che soddisfano ...

   €gηOZ;îå

Questa condizione: le lunghezze di ogni ( €g) sono memorizzate in un elenco, i cui prefissi ( η) vengono quindi sommati ( O), dandoci quindi le somme cumulative dell'elenco delle lunghezze. Quindi, la metà cementata del massimo dell'elenco viene inserita nello stack, ma mantenendo anche l'elenco originale su di esso ( Z;î) e se si verifica ( å) nelle somme cumulative, la funzione restituisce la verità.

εÂQ}

Per ciascuno, confronta ( Q) a con un invertito, che viene spinto separatamente nello stack di Â. Restituisce un elenco di 0 s e 1 s.

ZĀq

Massimo. Se c'è del vero, allora 1 altro 0 . Termina l'esecuzione. Tutto ciò che segue viene completamente ignorato.


3

Pitone 2 , 275 251 205 byte

-24 byte grazie a @KevinCruijssen

-44 byte grazie a @PostLeftGhostHunter

-2 byte in più grazie a @KevinCruijssen

def s(x):
 l=len(x)
 if l<2:return 1>0
 for i in range(1,l/2+1):
	if x[l-i:]==x[:i]:return s(x[i:l-i])
def s(x):
 l=len(x)
 if l<2:return 1>0
 for i in range(1,l/2+1):
	if x[l-i:]==x[:i]:return s(x[i:l-i])

Restituisce True per semi-palindrome, nessuno altrimenti

Provalo online!


1
O semplicemente ritorno 1
Jo King

Perché s (x) definito due volte?
Dr Y Wit,

Perché dicono contare come palindromo ... ma è possibile definire una funzione con lo stesso nome ???
RosLuP,

@RosLuP Sì, puoi. Il secondo sovrascrive il primo
Jo King,

3

Gelatina ,  33  32 byte

-1 Grazie a Erik the Outgolfer
Grazie anche a Dennis per la correzione di bug e per aver cercato di modificare un dettaglio di implementazione in Jelly.

ẸƇŒḂƇƊ$ƊĊHṀċÄẈṖŒŒṖẈÄċṀHĊƊ$ƊƇŒḂƇẸ

Resa semi-palindromi 1, resa altri 0.

O(2n)

Oppure vedi la suite di test .

Gli unici blocchi sono gli ŒḂs ({3 ° e 4 ° } contro {29 ° e 30 ° } byte), solo per consentire l'analisi del codice.

Come?

Tutto il lavoro viene eseguito dal lato destro - il "collegamento principale":

ŒṖẈÄċṀHĊƊ$ƊƇŒḂƇẸ - Main Link: list
ŒṖ               - all partitions
           Ƈ     - filter keep those for which this is truthy (i.e. non-zero):
          Ɗ      -   last three links as a monad:
  Ẉ              -     length of each
         $       -     last two links as a monad:
   Ä             -       cumulative addition
        Ɗ        -       last three links as a monad:
     Ṁ           -         maximum
      H          -         halve
       Ċ         -         ceiling
    ċ            -     count
              Ƈ  - filter keep those for which this is truthy:
            ŒḂ   -   is palindrome?
               Ẹ - any?

3

Perl 6 , 87 79 byte

-8 byte con alcuni trucchi dalla risposta di Jo King

$!={/\s/&&/^(.+)\s[(.+)\s]*$0$/&&$1.$!}#$!={/\s/&&/^(.+)\s[(.+)\s]*$0$/&&$1.$!}

Provalo online!

Porta della risposta JavaScript di tsh. Restituisce due diversi oggetti Regex.


2

Rubino , 129 byte

f=->l{!l[1]||(1...l.size).any?{|x|l[0,x]==l[-x,x]&&f[l[x..~x]]}}#f=->l{!l[1]||(1...l.size).any?{|x|l[0,x]==l[-x,x]&&f[l[x..~x]]}}

Provalo online!



1

C (gcc) (X86), 216 byte

p(L,a,n)int*a;{return n?(memcmp(a,a+L-n,n*4)|p(L-2*n,a+n,L/2-n))&&p(L,a,n-1):1<L;}
#define p(L,a)p(L,a,L/2)//p(L,a,n)int*a;{return n?(memcmp(a,a+L-n,n*4)|p(L-2*n,a+n,L/2-n))&&p(L,a,n-1):1<L;}
#define p(L,a)p(L,a,L/2)

Provalo online!

p(L,a,n)restituisce 0 se la matrice adi lunghezza Lè un semi-palindromo, 1 altrimenti. Dato che tutti i prefissi di lunghezza >nsono già controllati, confronta il prefisso di lunghezza ncon il suffisso di lunghezza n. p(L,a)è il punto di ingresso.

Sfortunatamente, la soluzione più interessante è più lunga:

224 byte

(f(L,a,n))//#define p(L,a)(n=L/2,
int*a,n;
{return n?(memcmp(a,a+L-n,n*4)|f(L-2*n,a+n,L/2-n))&&f(L,a,n-1):1<L;}//{return n?(memcmp(a,a+L-n,n*4)|f(L-2*n,a+n,L/2-n))&&f(L,a,n-1):1<L;}
int*a,n;
#define p(L,a)(n=L/2,f(L,a,n))//(

Provalo online!

Ungolfed:

(f(L,a,n)) //#define p(L,a)(n=L/2,
int*a,n;
{
  return n 
    ? (memcmp(a, a+L-n, n*4) | f(L-2*n, a+n, L/2-n)) &&
      f(L,a,n-1)
    : 1 < L;
} // { ... } 
int*a,n;
#define p(L,a)(n=L/2,f(L,a,n)) //(

1

Japt , 66 byte


@¯X eUsXn}a1 "
ʧV?UÊ<2:ßUéV sVÑ
@¯X eUsXn}a1 "
ʧV?UÊ<2:ßUéV sVÑ

Interprete Japt

Grande miglioramento di questa versione, attualmente batte la maggior parte delle lingue pratiche. Ora funziona su una matrice di numeri interi poiché il metodo precedente aveva un bug.

Spiegazione:

@        }a1         Find the first number n > 0 such that...
 ¯X                   the first n elements
     UsXn             and the last n elements
    e                 are the same

"
ʧV?UÊ<2:ßUéV sVÑ    String literal to make it a Semi-palindrome
@¯X eUsXn}a1 "

ʧV?                 If n >= length of input...
    UÊ<2              return true if the length is less than 2
        :            Otherwise...
          UéV         move n elements from the end of the input to the start
              sVÑ     remove the first 2*n elements
         ß            and repeat on the remaining elements

0

PHP 237 byte

function f($a){for($x=2>$c=count($a);++$i<=$c/2;)$x|=($s=array_slice)($a,0,$i)==$s($a,-$i)&f($s($a,$i,-$i));return$x;}#function f($a){for($x=2>$c=count($a);++$i<=$c/2;)$x|=($s=array_slice)($a,0,$i)==$s($a,-$i)&f($s($a,$i,-$i));return$x;}

funzione ricorsiva, ritorni true(per input contenente meno di due elementi) o 1per verità,
0per falsità. Provalo online (contiene un'analisi dettagliata).

La lunghezza effettiva del codice è di 118 byte; semi-palindrome creato tramite duplicazione del codice.

Per prestazioni migliori, sostituire &con &&e inserire !$x&&prima ++$i.


0

Scala, 252 byte

def^(s:Seq[Int]):Int={val l=s.size;if(l>1)(1 to l/2).map(i=>if(s.take(i)==s.takeRight(i))^(s.slice(i,l-i))else 0).max else 1}//def^(s:Seq[Int]):Int={val l=s.size;if(l>1)(1 to l/2).map(i=>if(s.take(i)==s.takeRight(i))^(s.slice(i,l-i))else 0).max else 1}

Provalo online!

PS. Apparentemente, la soluzione è 2 volte più lunga solo per soddisfare il requisito che anche il codice sorgente sia semi-palindromo.

PPS. Non è un candidato per il code-golf ma una soluzione puramente funzionale che utilizza la corrispondenza dei modelli:

  def f(s:Seq[Int], i:Int=1):Int = {
    (s, i) match {
      case (Nil ,_) => 1
      case (Seq(_), _) => 1
      case (l, _) if l.take(i) == l.takeRight(i) => f(l.slice(i,l.size-i), 1)
      case (l, j) if j < l.size/2 => f(l, i+1)
      case (_, _) => 0
    }
  }

La sfida richiede che anche il tuo codice sia un semi-palindromo. Questo è il più divertente della sfida.
Wheat Wizard

@PostLeftGhostHunter, ho aggiunto il codice sorgente originale nel commento per soddisfare il requisito. A proposito, qual è il divertimento di rendere il codice sorgente semi-palindromo? Se non sbaglio, ogni soluzione in questo thread sarebbe due volte più breve senza questo requisito. Sei a conoscenza di una soluzione non così?
Dr Y Wit,

0

Perl 6 , 81 byte

($!={/../&&/^(.+)(.*)$0$/&&$1.$!})o&chrs#($!={/../&&/^(.+)(.*)$0$/&&$1.$!})o&chrs

Provalo online!

Restituisce la regex /../per True e la regex /^(.+)(.*)$0$/per False. Funziona in modo simile alla risposta di nwellnhof , ma converte preventivamente l'elenco in una stringa.

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.