Triângulos totalmente palíndricos


18

Considere a string 160615051. Pode ser "triangulado" como tal:

  1
 606
15051

Então, cada linha é um palíndromo. Observe também que cada lado do perímetro também é um palíndromo:

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

Portanto, essa cadeia pode ser considerada um triângulo totalmente palindrômico. Não se preocupe com a altitude 100, neste caso, ela não precisa ser palindrômica.

Entrada: uma sequência de caracteres ASCII imprimíveis de 0x20 a 0x7E. Pode ser uma matriz de caracteres, uma única sequência ou uma matriz de pontos de código ASCII. Sua entrada sempre poderá ser triangulada (ou seja, seu comprimento sempre será um quadrado perfeito).

Saída : Um valor verdadeiro se a sequência for um triângulo totalmente palindrômico ou um valor falsey de outra forma.

Casos de teste

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

Respostas:


10

Geléia , 14 12 bytes

J’ƲœṗZ⁻¦µU⁼

Experimente online!

fundo

Começamos examinando os índices baseados em 0 da sequência 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 obter as linhas do triângulo, podemos dividir a sequência antes dos índices 1 , 1 + 3 = 4 , 1 + 3 + 5 = 9 e 1 + 3 + 5 + 7 = 16 . Como (n + 1) ² = n² + (2n + 1) , essas somas são precisamente os quadrados perfeitos positivos na lista de índices. Se também dividirmos a string antes de 0 , isso é tão simples quanto dividir antes de todos os índices baseados em 0 que são quadrados perfeitos.

Após a divisão, obtemos as seguintes strings.

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

Em seguida, substituímos a sequência vazia no início por todos os caracteres na primeira coluna.

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

A tarefa agora é reduzida para verificar se a reversão de todas as cadeias produz a mesma matriz de cadeias.

Como funciona

Primeiro Jgera todos os índices baseados em 1 da sequência de entrada Je depois os diminui para gerar todos os índices baseados em 0. Ʋtesta todos os índices baseados em 0 quanto à esquadria. Para o nosso exemplo acima, isso gera a seguinte 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

Em seguida, chamamos œṗpara particionar a sequência de entrada, por exemplo,

 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 1 's (na verdade, todos os elementos truthy). Para o nosso exemplo, isso gera a seguinte matriz de strings.

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

Z⁻¦é sem dúvida a parte mais interessante desta resposta. Vamos analisar o mais direto Z1¦primeiro.

¦é o esparso rápido. Consome dois links da pilha, especificamente 1e Zneste caso. Primeiro Zé aplicado ao seu argumento: a matriz de strings de antes. Zé o átomo zip e lê a matriz de cadeias / matriz de caracteres 2D por colunas, produzindo

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

O que costumava ser o lado esquerdo da sequência de entrada e a primeira coluna da matriz de sequências agora se torna a primeira sequência .

Agora ¦espreita 1e encontra um único índice: 1 . Portanto, a primeira string na matriz original é substituída pela primeira no valor de retorno Z; seqüências de caracteres em outros índices permanecem inalteradas.

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

Vamos chamar essa matriz A .

Usamos em Z⁻¦vez de Z1¦, mas isso não faz diferença: compara a matriz de strings com a string de entrada pela desigualdade, produzindo 1, uma vez que elas não são iguais. A diferença entre os dois é que Z⁻¦é diádico porque é, permitindo-nos escrever em œṗZ⁻¦vez de œṗ¹Z1¦. Isso ocorre porque uma díade ( œṗ) seguida por uma mônada ( œṗ¹Z1¦) é uma bifurcação (a mônada é aplicada ao argumento da cadeia / sequência de entrada e o valor retornado é passado como o argumento correto œṗ), enquanto uma díade seguida por outra díade (ou no final da cadeia) é um gancho , ou seja, seu argumento correto é o argumento da cadeia.

Tudo o que resta a fazer é verificar a palindromicidade. µcomeça uma nova cadeia (monádico), que é argumento é Um . O átomo de reversãoU inverte todas as seqüências em A (mas não o próprio A ) e compara o resultado com A para obter igualdade. O Booleano 1 retornado indica um triângulo totalmente palindrômico; outras seqüências retornariam 0 .


Eu realmente deveria aprender a ler Jelly. (Explicação, por favor?)
CAD97 9/17

1
Eu editei minha resposta.
Dennis

6

Japonês , 25 21 17 bytes

Guardado 2 bytes graças a @obarakon

ò@°T ¬v1
pUmg)eêP

Teste online!

Como 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

Observe que não precisamos verificar os dois lados; se os lados não forem os mesmos, pelo menos uma das linhas não é um palíndromo.


Essa coisa multilinha é um novo recurso do Japt?
Lucas

@ Lucas Sim, acabei de adicionar terça-feira. Esta é a minha primeira chance de exibi-lo :-) #
928 ETHproductions

Não importa a minha dica de golfe. Ele simplesmente verificar se cada linha foi palíndromo, que também passou a dar resultados corretos ...
Lucas


4

Geléia , 18 16 bytes

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

Experimente online!

Agradecemos a Jonathan Allan pela economia trivial, mas não tão óbvia, de -2 bytes.


Use minha construção de triângulo e salve um byte: JƲ0;œṗ⁸ZḢ$ṭ$ŒḂ€Ạ
Jonathan Allan

... de fato, combine essa idéia com a mentira e salve outro byte, pois o particionamento será "mais curto": J²‘Ṭœṗ⁸ZḢ$ṭ$ŒḂ€Ạ
Jonathan Allan

@JonathanAllan Umm ... por que eu preciso ½? Agora Jfaz mais sentido ...
Erik, o 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)

te ucolete os lados para que possam ser testados no 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);}

Pensei que a solução estava com boa aparência até chegar à parte do palíndromo

Versão não destruída:

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

Você pode passar e=..para a linha do loop for para salvar um byte? Não há necessidade de contar as novas linhas na contagem de bytes, portanto, suponho que você não esteja.
precisa saber é o seguinte

Não, eu não estou contando novas linhas, não consigo mover o e para o loop porque preciso dele na declaração de retorno.
precisa saber é o seguinte

Eu quis dizer assim #....; i < s;e = f.Substring(s - k)){c+=....
TheLethalCoder 9/17 /

2

Java 8, 358 301 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()+"");}

Entrada é a String, saída é a boolean.

Explicação:

Experimente aqui.

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

Geléia ,  20  21 bytes

+2 bytes - eu liberei o código de buggy :(
-1 byte - movi de moldagem como números inteiros ímpares para particionamento em índices quadrados

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

Um link monádico que aceita uma lista de caracteres e retorna 1(Truthy) ou 0(Falsey).
Nota: isso usa a parte da especificação que limita a entrada a um comprimento quadrado.

Experimente online! ou veja a suíte de testes .

Isso pode ser simplificado para 17 bytes , observando que, se todas as linhas são palíndromos, apenas um "lado" precisa ser JƲ0;œṗ⁸ZḢ$ṭ$ŒḂ€Ạchecado ( ); no entanto, Erik, o Outgolfer, já notou esse fato e o usou na resposta. isso o método de construção do triângulo para eles um byte lá.

Além disso, isso pode ser aprimorado para 16 bytes , observando que o particionamento nos índices de verdade não se importa se houver excesso no argumento esquerdo (J²‘Ṭœṗ⁸ZḢ$ṭ$ŒḂ€Ạ ).

Quão?

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
Droga, eu estava prestes a responder Jelly. Embora tecnicamente o meu esteja errado e goste do dobro do tempo ... bom trabalho :): P
HyperNeutrino 8/17

"notar que o particionamento em índices de verdade não se importa se houver excesso no argumento da esquerda", notado também antes da leitura.
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"]


Você não pode substituir If[<stuff>, True, False]com apenas <stuff>? E acho que And@@(...)é mais curto que Count[...,True]==s, o que também significa que você não precisa definir scomo variável.
Não uma árvore

Espere, isso realmente testa as diagonais? Estou recebendo falsos positivos em alguns dos casos de teste ( "1202"e "160625052").
Não é uma árvore

todos os problemas corrigidos
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;}

Usa uma MutableList<Character>das coleções do 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}{

Experimente online!

Saídas undef(ou seja, em branco, nulo) para true, qualquer número para false


0

Excel VBA, 87 bytes

Função de janela imediata VBE anônima que recebe entrada da célula [A1]e sai para a janela imediata 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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.