Triángulos totalmente palindrómicos


18

Considera la cuerda 160615051. Se puede "triangular" como tal:

  1
 606
15051

Entonces, cada fila es un palíndromo. También tenga en cuenta que cada lado del perímetro también es un palíndromo:

  1  |   1   |   
 6   |    6  |      
1    |     1 | 15051 

Por lo tanto, esta cadena se puede considerar como un triángulo totalmente palindrómico. No se preocupe por la altitud 100en este caso, no tiene que ser palindrómico.

Entrada: una cadena de caracteres ASCII imprimibles de 0x20 a 0x7E. Puede ser una matriz de caracteres, una sola cadena o una matriz de puntos de código ASCII. Su entrada siempre podrá ser triangulada (es decir, su longitud siempre será un cuadrado perfecto).

Salida : un valor verdadero si la cadena es un triángulo totalmente palindrómico, o un valor falsey de lo contrario.

Casos de prueba

input => output

1 => true
A => true
AAAA => true
nope => false
{{}} => false
1101 => true
1011 => false
1202 => false
111110001 => true
160615051 => true
160625052 => false
1111111111111111 => true
1121123211234321123454321 => true
HHeHHeleHHellleHHellolleH => true
HellolleHHellleHHeleHHeHH => false
111111111111111111111111111111111111 => true
abcbdefeddefgfedbcdefedcbabcdefedcba => true

Respuestas:


10

Jalea , 14 12 bytes

J’ƲœṗZ⁻¦µU⁼

Pruébalo en línea!

Antecedentes

Comenzamos mirando los índices basados ​​en 0 de la cadena de entrada.

 H  H  e  H  H  e  l  e  H  H  e  l  l  l  e  H  H  e  l  l  o  l  l  e  H
 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

Para obtener las filas del triángulo, podemos dividir la cadena antes de los índices 1 , 1 + 3 = 4 , 1 + 3 + 5 = 9 y 1 + 3 + 5 + 7 = 16 . Como (n + 1) ² = n² + (2n + 1) , estas sumas son precisamente los cuadrados positivos y perfectos en la lista de índice. Si también dividimos la cadena antes de 0 , esto es tan simple como dividir antes de todos los índices basados ​​en 0 que son cuadrados perfectos.

Después de dividir, obtenemos las siguientes cadenas.

""
"H"
"HeH"
"HeleH"
"HellleH"
"HellolleH"

A continuación, reemplazamos la cadena vacía al principio con todos los caracteres en la primera columna.

"HHHHH"
"H"
"HeH"
"HeleH"
"HellleH"
"HellolleH"

La tarea ahora se reduce a verificar si invertir todas las cadenas produce la misma matriz de cadenas.

Cómo funciona

Primero Jgenera todos los índices basados ​​en 1 de la cadena de entrada J, luego los disminuye ’para producir todos los índices basados ​​en 0. Ʋprueba todos los índices basados ​​en 0 para la cuadratura. Para nuestro ejemplo de arriba, esto produce la siguiente matriz booleana.

 1  1  0  0  1  0  0  0  0  1  0  0  0  0  0  0  1  0  0  0  0  0  0  0  0

A continuación, llamamos œṗa particionar la cadena de entrada, por ejemplo,

 H  H  e  H  H  e  l  e  H  H  e  l  l  l  e  H  H  e  l  l  o  l  l  e  H

antes de todos los 1 '(en realidad, todos los elementos de verdad). Para nuestro ejemplo, esto produce la siguiente matriz de cadenas.

['', 
 'H',
 'HeH',
 'HeleH',
 'HellleH',
 'HellolleH'
]

Z⁻¦es posiblemente la parte más interesante de esta respuesta. Analicemos el más directo Z1¦primero.

¦Es el escaso rápido. Consume dos enlaces de la pila, específicamente 1y Zen este caso. Primero Zse aplica a su argumento: la matriz de cadenas de antes. Zes el átomo zip y lee la matriz de cadenas / matriz de caracteres 2D por columnas, produciendo

['HHHHH',
 'eeee',
 'Hlll',
 'ell',
 'Hlo',
 'el',
 'Hl',
 'e',
 'H'
]

Lo que solía ser el lado izquierdo de la cadena de entrada y la primera columna de la matriz de cadenas ahora se convierte en la primera cadena .

Ahora ¦mira 1y encuentra un solo índice: 1 . Por lo tanto, la primera cadena en la matriz de cadenas original se reemplaza con la primera cadena en el valor de retorno de Z; Las cadenas de otros índices no se ven afectadas.

['HHHHH',
 'H',
 'HeH',
 'HeleH',
 'HellleH',
 'HellolleH'
]

Vamos a llamar a esta matriz A .

Usamos en Z⁻¦lugar de Z1¦, pero esto no hace ninguna diferencia: ⁻compara la matriz de cadenas con la cadena de entrada para la desigualdad, produciendo 1 ya que no son iguales. La diferencia entre los dos es que Z⁻¦es diádica porque ⁻nos permite escribir en œṗZ⁻¦lugar de œṗ¹Z1¦. Esto se debe a que una díada ( œṗ) seguida de una mónada ( œṗ¹Z1¦) es una bifurcación (la mónada se aplica al argumento de la cadena / la cadena de entrada, y el valor devuelto se pasa como el argumento correcto a œṗ), mientras que una díada seguida por otra díada (o al final de la cadena) es un gancho , es decir, su argumento correcto es el argumento de la cadena.

Todo lo que queda por hacer es verificar la palindrómica. µcomienza una nueva cadena (monádico) que está argumento es una . El átomo invertidoU invierte todas las cadenas en A (pero no A en sí), luego ⁼compara el resultado con A para la igualdad. El 1 booleano devuelto indica un triángulo totalmente palindrómico; otras cadenas devolverían 0 .


Realmente debería aprender a leer Jelly. (¿Explicación, por favor?)
— CAD97

1
He editado mi respuesta.
— Dennis

6

Japt , 25 21 17 bytes

Guardado 2 bytes gracias a @obarakon

ò@°T ¬v1
pUmg)eêP

¡Pruébalo en línea!

Cómo funciona

 ò@  ° T ¬ v1   // Implicit: U = input string, T = 0
UòXY{++T q v1}  // First line; reset U to the result of this line.
UòXY{        }  // Partition U at indices where
     ++T q      //   the square root of T incremented
           v1   //   is divisible by 1.
                // This breaks U at square indices, giving rows of 1, 3, 5, ... chars.
 pUmg)eêP
UpUmg)eêP
  Umg           // Take the first char of every item of U.
Up   )          // Append this to U.
      e         // Check that every item in the resulting array
       êP       // is a palindrome.
                // Implicit: output result of last expression

Tenga en cuenta que no necesitamos verificar ambos lados; Si los lados no son iguales, al menos una de las filas no es un palíndromo.


¿Es esta cosa multilínea una nueva característica de Japt?
— Luke

@Luke Sí, lo acabo de agregar el martes. Esta es mi primera oportunidad de mostrarlo :-)
— ETHproductions

No importa mi consejo de golf. Simplemente comprobar si cada línea era capicúa, que también pasó a dar resultados correctos ...
— Lucas


4

Jalea , 18 16 bytes

J²‘Ṭœṗ⁸ZḢ$ṭ$ŒḂ€Ạ

Pruébalo en línea!

Gracias a Jonathan Allan por los ahorros triviales pero no tan obvios de -2 bytes.


Usar la construcción de mi triángulo y guardar un byte:JƲ0;œṗ⁸ZḢ$ṭ$ŒḂ€Ạ
— Jonathan Allan

... de hecho combinan esa idea con la falsedad y guardar otro byte, ya particionamiento "zip más corto":J²‘Ṭœṗ⁸ZḢ$ṭ$ŒḂ€Ạ
— Jonathan Allan

@JonathanAllan Umm ... ¿por qué tengo que hacerlo ½? Ahora Jtiene más sentido ...
— Erik the Outgolfer

3

JavaScript (ES6), 112 bytes

f=(s,n=1,t='',u='',g=([...a])=>''+a==a.reverse())=>s?g(s.slice(0,n))&f(s.slice(n),n+2,t+s[0],u+s[n-1]):g(t)&g(u)

ty urecoger los lados para que puedan ser probados al final.


2

C #, 184 bytes

using System.Linq;
b=a=>string.Concat(a.Reverse())==a
f=>{string c=f[0]+"",d=c,e="";for(int i=1,k=1,s=f.Length;i<s;)
{c+=f[i];d+=f[(i+=k+=2)-1];e=f.Substring(s-k);}return b(c)&b(d)&b(e);}

Pensé que la solución se veía bien hasta que llegué a la parte del palíndromo

Versión sin golf:

Func<string, bool> b = a => string.Concat(a.Reverse()) == a;
        Func<string, bool> func = f => {

            string c = f[0] + "", d = c, e = "";

            for (int i = 1, k = 1, s = f.Length; i < s;) {
                c += f[i];
                d += f[(i += k += 2) - 1];
                e = f.Substring(s - k);
            }

            return b(c) & b(d) & b(e);
        };

¿Se puede pasar e=..a la línea de bucle for para guardar un byte? No es necesario contar las nuevas líneas en el recuento de bytes, así que supongo que no.
— TheLethalCoder

No, no estoy contando nuevas líneas, no puedo mover la e al bucle porque lo necesito en la declaración de devolución.
— LiefdeWen

....; i < s;e = f.Substring(s - k)){c+=....
— Quise

2

Java 8, 358301 bytes

import java.util.*;s->{List<String>l=new Stack();for(int i=0,p=1,t=1;p<=s.length();p+=t+=2)l.add(s.substring(i,i=p));String a="",b=a;for(String q:l){a+=q.charAt(0);b+=q.charAt(q.length()-1);}return p(a)&p(b)&p(l.get(l.size()-1));}boolean p(String s){return s.equals(new StringBuffer(s).reverse()+"");}

La entrada es a String, la salida es a boolean.

Explicación:

Pruébalo aquí

import java.util.*;               // Required import for List and Stack

s->{                              // Method (1) with String parameter and boolean return-type
  List<String>l=new Stack();      //  Create a String-list
  for(int i=0,p=1,t=1;            //  Initialize some index/counter integers
      p<=s.length();              //  Loop (1) over the String in sections
      p+=t+=2)                    //    And increase `p` like this after every iteration: 1,4,9,16,25,etc.
    l.add(s.substring(i,i=p));    //   And add a substring-section to the list (0,1 -> 1,4 -> 4,9 -> 9,16 -> etc.)
                                  //  End of loop (1) (implicit / single-line body)
  String a="",b=a;                //  Two temp Strings
  for(String q:l){                //  Loop (2) over the list
    a+=q.charAt(0);               //   And append the first character to String `a`
    b+=q.charAt(q.length()-1);    //   And the last character to String `b`
  }                               //  End of loop (2)
  return p(a)                     //  Return if String `a` is a palindrome
        &p(b)                     //   as well as String `b`
        &p(l.get(l.size()-1));    //   as well as the last String in the list
}                                 // End of method (1)

boolean p(String s){              // Method (2) with String parameter and boolean return-type
  return s.equals(new StringBuffer(s).reverse()+"");
                                  //  Return if this String is a palindrome
}                                 // End of method (2)

1

Jalea ,  20  21 bytes

+2 bytes: liberé el código defectuoso :(
-1 byte : pasé de moldear como enteros impares a particionar en índices cuadrados

JƲ0;œṗ⁸ZḢ$ṭ$ŒḂ€Ạ

Un enlace monádico que acepta una lista de personajes y devuelve 1(Verdad) o 0(Falsey).
Nota: esto utiliza la parte de la especificación que limita la entrada a una longitud cuadrada.

Pruébalo en línea! o ver el conjunto de pruebas .

Esto puede simplificarse a 17 bytes al observar que si todas las filas son palíndromos, solo un "lado" necesita verificación ( JƲ0;œṗ⁸ZḢ$ṭ$ŒḂ€Ạ), sin embargo, Erik the Outgolfer ya notó este hecho y lo usó en su respuesta, así que les he dado el método de construcción de triángulos para guardar Un byte allí.

Además, eso a su vez puede mejorarse a 16 bytes al observar que a la partición en índices verdaderos no le importa si hay un exceso en el argumento izquierdo ( J²‘Ṭœṗ⁸ZḢ$ṭ$ŒḂ€Ạ).

¿Cómo?

JƲ0;œṗµ2BịЀ⁸Z;⁸ŒḂ€Ạ - Link: list, a      e.g. "abcbazxza"
J                     - range of length of a  = [1,2,3,4,5,6,7,8,9]
 Ʋ                   - is square? (vectorises) [1,0,0,1,0,0,0,0,1]
   0;                 - prepend a zero        [0,1,0,0,1,0,0,0,0,1]
     œṗ               - partition a at 1s     ["a","bcb","azxza"]
       µ              - monadic chain separation, call that t
        2B            - 2 in binary = [1,0]
             ⁸        - chain's left argument, t
          ịЀ         - map with index into    ["aa","bb","aa"] (1st and last of each of t)
              Z       - transpose              ["aba","aba"] (left and right "sides" of t)
               ;⁸     - concatenate t          ["aba","aba","a","bcb","azxza"]
                 ŒḂ€  - palindromic? for €ach  [1,1,1,1,1]
                    Ạ - all?                   1

1
Maldición, estaba a punto de responderle a Jelly. Aunque técnicamente el mío está mal y me gusta el doble de tiempo ... buen trabajo :): P
— HyperNeutrino

"observando que a la partición en índices de verdad no le importa si hay un exceso en el argumento de la izquierda" notó también antes de leer.
— Erik the Outgolfer

1

Mathematica, 156 bytes

B=StringTake;Count[PalindromeQ/@Join[A=Table[B[#,{i^2+1,(i+1)^2}],{i,0,(s=Sqrt@StringLength@#)-1}],{StringJoin@Table[B[A[[i]],1],{i,Length@A}]}],True]==s+1&


entrada

["1101"]


¿No puedes reemplazar If[<stuff>, True, False]con solo <stuff>? Y creo que And@@(...)es más corto que Count[...,True]==s, lo que también significa que no tienes que definirlo scomo una variable.
— No es un árbol

Espera, ¿esto realmente prueba las diagonales? Estoy obteniendo falsos positivos para un par de casos de prueba ( "1202"y "160625052").
— No es un árbol

todos los problemas solucionados
— J42161217


1

Java, 136 bytes

l->{for(int i=0,j,k=1;i<l.size();i=j,k+=2)if(!l.subList(i,j=i+k).equals(l.subList(i,j).asReversed().toList()))return false;return true;}

Utiliza una MutableList<Character>colección de Eclipse

Function<MutableList<Character>, Boolean> func = l->{
   for(int i=0,j,k=1;i<l.size();i=j,k+=2)  // `i` is the start index, `j` is the end index, `k` increments by 2
       if(!l.subList(i,j=i+k).equals( //Check that the first partition equals
           l.subList(i,j).asReversed().toList())  // The same sublist reversed
       )
       return false;
   return true;
};

1

Perl 5 , 81 + 1 ( -p) = 82 bytes

$a[0].=$1while($a[++$q]=substr$_,0,($#i+=2),'')=~/(.)/;$\||=$_ ne reverse for@a}{

Pruébalo en línea!

Salidas undef(es decir, en blanco, nulo) para verdadero, cualquier número para falso


0

Excel VBA, 87 bytes

Función de ventana inmediata anónima de VBE que toma entrada de la celda [A1]y salidas a la ventana inmediata de VBE

k=1:For i=1To[Len(A1)^.5]:s=Mid([A1],j+1,i*2-1):j=j+i*2-1:k=k*(s=StrReverse(s)):Next:?k

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.