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.