Un rompecabezas de semi-palíndromo

23

Un palíndromo es una palabra que es su propio reverso.

Ahora hay algunas palabras que pueden parecer palíndromos pero no lo son. Por ejemplo, considere la palabra sheesh, sheeshno es un palíndromo porque su reverso es hseehsdiferente, sin embargo, si consideramos shque es una sola letra, entonces es reverso sheesh. Este tipo de palabra la llamaremos semi-palíndromo.

Específicamente, una palabra es un semi-palíndromo si podemos dividir la palabra en un cierto número de fragmentos, de modo que cuando se invierte el orden de los fragmentos, se forma la palabra original. (Para sheeshesos fragmentos son sh e e sh) También requeriremos que ningún fragmento contenga letras de ambas mitades de la palabra (de lo contrario, cada palabra sería un semi-palíndromo). Por ejemplo, rearno es un semi-palíndromo porque r ea rtiene un fragmento ( ea) que contiene letras de ambos lados de la palabra original. Consideramos que el carácter central en una palabra de longitud impar no está en ninguno de los lados de la palabra, por lo tanto, para las palabras con longitud impar, el carácter central siempre debe estar en su propio fragmento.

Su tarea será tomar una lista de enteros positivos y determinar si son semi-palíndromos. Su código debería generar dos valores desiguales consistentes, uno si la entrada es un semi-palíndromo y el otro en caso contrario. Sin embargo, la secuencia de bytes de su código debe ser un semi-palíndromo .

Las respuestas se puntuarán en bytes, siendo menos bytes mejores

Casos de prueba

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

Programa para generar más casos de prueba.


Borrible señaló que estos son similares a los palíndromos generalizados de Smarandache . Entonces, si desea leer más, ese es un lugar para comenzar.

Asistente de trigo
fuente
2
¿Por qué definiste semi-palíndromos usando cadenas pero tus entradas son matrices de enteros? Además de ser confuso, esto significa que no podemos probar nuestro código fuente usando nuestro propio programa.
BradC
Los Palindromes de @BradC y similares a menudo se explican en términos de palabras, ya que es un poco más fácil hacerlo.
Erik the Outgolfer
Las cadenas @BradC tienden a introducir casos extremos extraños, particularmente en términos de caracteres frente a bytes. Elijo el número porque son más simples. Pensé que las palabras serían más fáciles para propósitos de explicación.
Wheat Wizard
2
Estos tipos de palíndromos se conocen como palíndromos generalizados de Smarandache en la literatura.
borrible el
1
@RosLuP Sí, los palíndromos "verdaderos" también son semi-palíndromos, solo trata a cada personaje / número entero tal como está sin "fragmentación" adicional.
BradC

Respuestas:

6

Retina 0.8.2 , 85 69 bytes

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

Pruébalo en línea! Explicación:

M`

Selecciona el modo Match. De hecho, Retina usa el modo Match para un programa de una sola línea, pero la segunda copia del código siempre coincidiría si no fuera por estos caracteres adicionales.

^

El partido debe comenzar desde el principio.

(.+,)*

Captura una serie de carreras de personajes. Cada ejecución debe terminar en una coma.

(\d+,)?

Opcionalmente, haga coincidir una serie de dígitos y una coma.

(?<-1>\1)*

Opcionalmente, haga coincidir todas las capturas en orden inverso, haciendo estallar cada una a medida que coinciden.

$

El partido debe terminar al final.

(?(1)^)

Retroceda a menos que todas las capturas se hayan reventado. Funciona al requerir que la coincidencia aún esté al comienzo de la cadena si tenemos una captura sin reventar, lo cual es imposible.

Neil
fuente
5

Jalea , 27 23 bytes

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

Devuelve 1 para semi-palíndromos, 0 de lo contrario.

Pruébalo en línea!

Cómo funciona

Ṗ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.
Dennis
fuente
4

Python 2 , 157 153 147 143 bytes

-4 bytes gracias 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)

Pruébalo en línea!

ovs
fuente
1
Cambiar x==x[::-1]para len(x)<2guardar 2 * 2 bytes; 143 bytes
tsh
4

05AB1E , 59 47 43 41 bytes

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

-12 bytes gracias a @Emigna .

Pruébalo en línea o verifique todos los casos de prueba .

Explicación:

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
Kevin Cruijssen
fuente
Puede solucionar el problema con listas de longitud impar con øøε.œ} `, ahorrando 6 bytes. También parece haber dejado 30 bytes sin usar en ...
Emigna
@Emigna, las no-operaciones al final deben cumplir con el requisito de fuente restringida del desafío
Kamil Drakari
@KamilDrakari: Oh cierto. Olvidé esa parte. La buena noticia es que el guardado de 6 bytes será de 12 bytes entonces :)
Emigna
@Emigna Muy inteligente con el truco de doble cremallera. No estaba contento con esa parte, ¡pero esto es mucho mejor! Por cierto, dado que el Elixir reescribe los comandos de 2 bytes se pueden usar en lugar de ε }. :)
Kevin Cruijssen
@KevinCruijssen: Ah, genial. No lo sabia.
Emigna
4

05AB1E , 37 bytes

Utiliza aproximadamente la misma técnica que se le ocurrió a Jonathan .

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

Pruébalo en línea!


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

Programa completo Recibe una lista de STDIN, emite 1 o 0 a STDOUT.

.œʒ        }

Filtrar-mantener las particiones que satisfacen ...

   €gηOZ;îå

Esta condición: las longitudes de cada ( €g) se almacenan en una lista, cuyos prefijos ( η) se suman ( O), lo que nos da las sumas acumulativas de la lista de longitudes. Luego, la mitad máxima del máximo de esa lista se inserta en la pila, pero manteniendo también la lista original ( Z;î) y, si aparece ( å) en las sumas acumulativas, la función devuelve la verdad.

εÂQ}

Para cada uno, compare ( Q) a con un reverso, que son empujados por separado en la pila Â. Devuelve una lista de 0 sy 1 s.

ZĀq

Máximo. Si alguno es verdadero, entonces 1 más 0 . Fin de la ejecución. Todo lo que sigue es completamente ignorado.

Sr. Xcoder
fuente
3

Python 2 , 275 251 205 bytes

-24 bytes gracias a @KevinCruijssen

-44 bytes gracias a @PostLeftGhostHunter

-2 bytes más gracias 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])

Devuelve True para semi-palíndromo, ninguno de lo contrario

Pruébalo en línea!

Agujero de vaca
fuente
1
O simplemente regrese 1
Jo King
¿Por qué s (x) se define dos veces?
Dr. Y Wit
¿Porque dicen contar como palíndromo ... pero es posible definir una función con el mismo nombre?
RosLuP
@RosLuP Sí puedes. El segundo solo sobrescribe al primero
Jo King
3

Gelatina ,  33  32 bytes

-1 Gracias a Erik the Outgolfer
Gracias también a Dennis por una corrección de errores y buscando cambiar un detalle de implementación en Jelly.

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

Semi-palíndromos ceden 1, otros ceden 0.

Pruébalo en línea! (lento como esO(2norte) en longitud de entrada)

O ver el conjunto de pruebas .

Los únicos trozos son los ŒḂs ({3 ª y 4 ª } {vs 29 º y 30 º } bytes), para permitir que el código para analizar.

¿Cómo?

Todo el trabajo se realiza por el lado derecho: el "Enlace principal":

ŒṖẈÄċṀ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?
Jonathan Allan
fuente
3

Perl 6 , 87 79 bytes

-8 bytes con algunos trucos de la respuesta de Jo King

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

Pruébalo en línea!

La respuesta de JavaScript del puerto de tsh. Devuelve dos objetos Regex diferentes.

nwellnhof
fuente
2

Rubí , 129 bytes

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

Pruébalo en línea!

GB
fuente
1

C (gcc) (X86), 216 bytes

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)

Pruébalo en línea!

p(L,a,n)devuelve 0 si la matriz ade longitud Les un semi-palíndromo, 1 de lo contrario. Dado que todos los prefijos de longitud >nya están marcados, compara el prefijo de longitud ncon el sufijo de longitud n. p(L,a)Es el punto de entrada.

Desafortunadamente, la solución más interesante es más larga:

224 bytes

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

Pruébalo en línea!

Sin golf:

(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)) //(
eush77
fuente
1

Japt , 66 bytes


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

Intérprete Japt

Gran mejora de esta versión, en realidad supera a la mayoría de los lenguajes prácticos ahora. Ahora opera en una matriz de enteros ya que el método anterior tenía un error.

Explicación:

@        }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
Kamil Drakari
fuente
0

PHP 237 bytes

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

función recursiva, retornos true(para entradas que contienen menos de dos elementos) o 1para verdadero,
0para falso. Pruébalo en línea (contiene desglose).

La longitud real del código es de 118 bytes; semi-palíndromo creado por duplicación de código.

Para un mejor rendimiento, reemplace &con &&e insertar !$x&&antes ++$i.

Titus
fuente
0

Scala, 252 bytes

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}

Pruébalo en línea!

PD. Aparentemente, la solución es 2 veces más larga solo para satisfacer el requisito de que el código fuente también sea semi-palíndromo.

PPS No es un candidato de código de golf, sino una solución puramente funcional que utiliza la coincidencia de patrones:

  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
    }
  }
Dr. Y Wit
fuente
El desafío requiere que su código sea también un semi-palíndromo. Eso es lo más divertido en el desafío.
Wheat Wizard
@PostLeftGhostHunter, agregué el código fuente original en el comentario para satisfacer el requisito. Por cierto, ¿cuál es la diversión de hacer que el código fuente sea semi palíndromo? Si no me equivoco, cada solución en este hilo sería dos veces más corta sin este requisito. ¿Conoces alguna solución que no sea así?
Dr. Y Wit
0

Perl 6 , 81 bytes

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

Pruébalo en línea!

Devuelve la expresión regular /../para True y la expresión regular /^(.+)(.*)$0$/para False. Funciona de manera similar a la respuesta de nwellnhof , pero convierte la lista a una cadena de antemano.

Jo King
fuente