Triangoli completamente palindromici


18

Considera la stringa 160615051. Può essere "triangolato" come tale:

  1
 606
15051

Quindi, ogni riga è un palindromo. Si noti inoltre che ogni lato del perimetro è anche un palindromo:

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

Pertanto, questa stringa può essere considerata un triangolo completamente palindromico. Non preoccuparti dell'altitudine 100in questo caso, non deve essere palindromico.

Input: una stringa di caratteri ASCII stampabili da 0x20 a 0x7E. Può essere una matrice di caratteri, una singola stringa o una matrice di punti di codice ASCII. Il tuo input sarà sempre in grado di essere triangolato (cioè, la sua lunghezza sarà sempre un quadrato perfetto).

Output : un valore di verità se la stringa è un triangolo completamente palindromico o in caso contrario un valore di falsa.

Casi test

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

Risposte:


10

Gelatina , 14 12 byte

J’ƲœṗZ⁻¦µU⁼

Provalo online!

sfondo

Iniziamo osservando gli indici basati su 0 della stringa di input.

 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

Per ottenere le righe del triangolo, possiamo dividere la stringa prima degli indici 1 , 1 + 3 = 4 , 1 + 3 + 5 = 9 e 1 + 3 + 5 + 7 = 16 . Poiché (n + 1) ² = n² + (2n + 1) , queste somme sono esattamente i quadrati positivi e perfetti nell'elenco degli indici. Se dividiamo anche la stringa prima di 0 , questo è semplice come dividere prima di tutti gli indici basati su 0 che sono quadrati perfetti.

Dopo la divisione, otteniamo le seguenti stringhe.

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

Successivamente, sostituiamo la stringa vuota all'inizio con tutti i caratteri nella prima colonna.

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

L'attività è ora ridotta al controllo se l'inversione di tutte le stringhe produce lo stesso array di stringhe.

Come funziona

In primo luogo Jgenera tutti gli indici basati su 1 della stringa di input J, quindi li diminuisce con per produrre tutti gli indici basati su 0. Ʋtesta tutti gli indici basati su 0 per la quadratura. Per il nostro esempio dall'alto, questo produce il seguente array booleano.

 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

Successivamente, chiamiamo œṗper partizionare la stringa di input, ad es.

 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

prima di tutti gli 1 (in realtà, tutti gli elementi di verità). Per il nostro esempio, questo produce il seguente array di stringhe.

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

Z⁻¦è probabilmente la parte più interessante di questa risposta. Analizziamo prima il più semplice Z1¦.

¦è il rado veloce. Consuma due collegamenti dallo stack, in particolare 1e Zin questo caso. Il primo Zviene applicato al suo argomento: l'array di stringhe di prima. Zè l' atomo zip e legge l'array string / array di caratteri 2D per colonne, cedendo

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

Quello che era il lato sinistro della stringa di input e la prima colonna dell'array di stringhe ora diventa la prima stringa .

Ora ¦dà un'occhiata 1e trova un singolo indice: 1 . Quindi la prima stringa nella matrice di stringhe originale viene sostituita con la prima stringa nel valore restituito di Z; le stringhe di altri indici rimangono inalterate.

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

Chiamiamo questo array A .

Abbiamo usato Z⁻¦invece di Z1¦, ma questo non fa alcuna differenza: confronta l'array di stringhe con la stringa di input per disuguaglianza, producendo 1 poiché non sono uguali. La differenza tra i due è che Z⁻¦è diadica perché , permettendoci di scrivere œṗZ⁻¦invece di œṗ¹Z1¦. Questo perché una diade ( œṗ) seguita da una monade ( œṗ¹Z1¦) è un fork (la monade viene applicata all'argomento della catena / stringa di input e il valore restituito viene passato come argomento corretto a œṗ), mentre una diade seguita da un'altra diade (o alla fine della catena) è un gancio , cioè il suo argomento giusto è l'argomento della catena.

Tutto ciò che resta da fare è verificare la palindromicità. µinizia una nuova catena (monade) che è argomento è A . L' atomo ascendenteU inverte tutte le stringhe in A (ma non A stesso), quindi confronta il risultato con A per l'uguaglianza. Il Booleano 1 restituito indica un triangolo completamente palindromico; altre stringhe restituirebbero 0 .


Dovrei davvero imparare a leggere Jelly. (Spiegazione, per favore?)
CAD97

1
Ho modificato la mia risposta.
Dennis,

6

Japt , 25 21 17 byte

Salvato 2 byte grazie a @obarakon

ò@°T ¬v1
pUmg)eêP

Provalo online!

Come funziona

 ò@  ° 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

Si noti che non è necessario controllare entrambi i lati; se i lati non sono uguali, almeno una delle file non è un palindromo.


È questa cosa multilinea una nuova caratteristica di Japt?
Luca,

@Luke Sì, l'ho appena aggiunto martedì. Questa è la mia prima occasione per metterlo in mostra :-)
ETHproductions

Non importa il mio consiglio di golf. Controlla semplicemente se ogni riga era palindromica, cosa che ha anche dato risultati corretti ...
Luca


4

Gelatina , 18 16 byte

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

Provalo online!

Grazie a Jonathan Allan per il banale ma non così ovvio risparmio di -2 byte.


Usa la mia costruzione a triangolo e salva un byte:JƲ0;œṗ⁸ZḢ$ṭ$ŒḂ€Ạ
Jonathan Allan,

... infatti combina quell'idea con la falsità e salva un altro byte, dato che il partizionamento sarà "zip shortest":J²‘Ṭœṗ⁸ZḢ$ṭ$ŒḂ€Ạ
Jonathan Allan il

@JonathanAllan Umm ... perché devo assolutamente farlo ½? Ora Jha più senso ...
Erik the Outgolfer,

3

JavaScript (ES6), 112 byte

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 uraccogliere i lati in modo che possano essere testati alla fine.


2

C #, 184 byte

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

Pensavo che la soluzione fosse bella fino a quando non sono arrivato alla parte del palindromo

Versione non golfata:

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

Puoi spostarti e=..nella riga del ciclo for per salvare un byte? Non è necessario contare le nuove righe nel conteggio dei byte, quindi presumo che tu non lo sia.
TheLethalCoder

No, non conto i newline, non riesco a spostare la e nel ciclo perché ne ho bisogno nell'istruzione return.
Liefde:

Intendevo così....; i < s;e = f.Substring(s - k)){c+=....
TheLethalCoder il

2

Java 8, 358 301 byte

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()+"");}

Input è a String, output è a boolean.

Spiegazione:

Provalo qui.

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

Gelatina ,  20  21 byte

+2 byte - Ho rilasciato il codice buggy :(
-1 byte - spostato dallo stampaggio come numeri dispari al partizionamento agli indici quadrati

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

Un collegamento monadico che accetta un elenco di personaggi e che restituisce 1(Verità) o 0(Falsey).
Nota: utilizza la parte della specifica che limita l'input a una lunghezza quadrata.

Provalo online! o vedi la suite di test .

Questo può essere semplificato a 17 byte notando che se tutte le righe sono palindromi è necessario controllare solo un "lato" ( JƲ0;œṗ⁸ZḢ$ṭ$ŒḂ€Ạ), tuttavia Erik the Outgolfer ha già notato questo fatto e lo ha usato nella loro risposta quindi ho dato loro il metodo di costruzione del triangolo risparmiando un byte lì.

Inoltre, ciò a sua volta può essere migliorato a 16 byte osservando che il partizionamento su indici di verità non importa se c'è eccesso nell'argomento di sinistra (J²‘Ṭœṗ⁸ZḢ$ṭ$ŒḂ€Ạ ).

Come?

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
Accidenti, stavo per rispondere Jelly. Anche se tecnicamente il mio è sbagliato e il doppio del tempo ... bel lavoro :): P
HyperNeutrino

"notare che il partizionamento su indici veritieri non dispiace se c'è un eccesso nell'argomento di sinistra" notato anche prima di leggere.
Erik the Outgolfer,

1

Mathematica, 156 byte

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&


ingresso

[ "1101"]


Non puoi sostituirlo If[<stuff>, True, False]con solo <stuff>? E penso che And@@(...)sia più breve di Count[...,True]==s, il che significa anche che non è necessario definire scome variabile.
Non un albero il

Aspetta, questo effettivamente mette alla prova le diagonali? Ricevo falsi positivi per un paio di casi di test ( "1202"e "160625052").
Non un albero il

tutti i problemi risolti
J42161217


1

Java, 136 byte

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

Utilizza un MutableList<Character>dalle raccolte 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 byte

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

Provalo online!

Output undef(es. Vuoto, nullo) per true, qualsiasi numero per false


0

Excel VBA, 87 byte

Funzione di finestra immediata VBE anonima che accetta input dalla cella [A1]e output nella finestra immediata di 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

0

Python 2 , 128 118 115 byte

def f(s):
 w=1;l=r='';b=[]
 while s:l+=s[0];r+=s[w-1];b+=[s[:w]];s=s[w:];w+=2
 print all(d==d[::-1]for d in[l,r]+b)

Provalo online!

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.