W pełni palindromowe trójkąty

18

Rozważ ciąg 160615051. Może być „triangulowany” jako taki:

  1
 606
15051

Następnie każdy rząd jest palindromem. Pamiętaj również, że każda strona na obwodzie jest również palindromem:

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

Dlatego ciąg ten można uznać za w pełni palindromiczny trójkąt. 100W tym przypadku nie martw się wysokością , nie musi to być palindromic.

Dane wejściowe: ciąg znaków ASCII do wydruku od 0x20 do 0x7E. Może to być tablica znaków, pojedynczy ciąg znaków lub tablica punktów kodowych ASCII. Twój wkład zawsze będzie mógł być triangulowany (to znaczy, jego długość zawsze będzie idealnym kwadratem).

Dane wyjściowe : prawdziwa wartość, jeśli ciąg jest w pełni palindromowym trójkątem lub w przeciwnym razie wartość falsey.

Przypadki testowe

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
Conor O'Brien
źródło

Odpowiedzi:

10

Galaretka , 14 12 bajtów

J’ƲœṗZ⁻¦µU⁼

Wypróbuj online!

tło

Zaczynamy od spojrzenia na indeksy ciągu wejściowego oparte na 0.

 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

Aby uzyskać rzędy trójkąta, możemy podzielić ciąg przed wskaźnikami 1 , 1 + 3 = 4 , 1 + 3 + 5 = 9 i 1 + 3 + 5 + 7 = 16 . Ponieważ (n + 1) ² = n² + (2n + 1) , sumy te są dokładnie dodatnimi, idealnymi kwadratami na liście indeksów. Jeśli podzielimy również ciąg przed 0 , jest to tak proste, jak podzielenie przed wszystkimi indeksami opartymi na 0, które są idealnymi kwadratami.

Po podzieleniu otrzymujemy następujące ciągi.

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

Następnie zastępujemy pusty ciąg na początku wszystkimi znakami w pierwszej kolumnie.

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

Zadanie sprowadza się teraz do sprawdzenia, czy odwrócenie wszystkich łańcuchów daje tę samą tablicę łańcuchów.

Jak to działa

Najpierw Jgeneruje wszystkie indeksy 1 ciągu wejściowego J, a następnie zmniejsza je, aby uzyskać wszystkie indeksy 0. Ʋtestuje wszystkie indeksy oparte na 0 na kwadratowość. W naszym przykładzie z góry daje to następującą tablicę boolowską.

 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

Następnie wywołujemy œṗpartycję ciągu wejściowego, np.

 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

przed wszystkimi 1 (właściwie wszystkie prawdziwe elementy). W naszym przykładzie daje to następującą tablicę ciągów.

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

Z⁻¦jest prawdopodobnie najciekawszą częścią tej odpowiedzi. Przeanalizujmy Z1¦najpierw bardziej proste .

¦jest rzadki szybki. Zużywa dwa łącza ze stosu, konkretnie 1iw Ztym przypadku. Pierwszy Zjest stosowany do jego argumentu: tablicy ciągów z wcześniej. Zjest atomem zip i odczytuje tablicę ciągów / tablicę znaków 2D według kolumn, dając

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

To, co kiedyś było lewą stroną ciągu wejściowego i pierwszą kolumną tablicy ciągów, staje się teraz pierwszym ciągiem .

Teraz ¦zagląda 1i znajduje pojedynczy indeks: 1 . Zatem pierwszy ciąg w oryginalnej tablicy ciągów jest zastępowany pierwszym ciągiem w wartości zwracanej przez Z; ciągi przy innych indeksach pozostają niezmienione.

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

Nazwijmy to tablica .

Użyliśmy Z⁻¦zamiast Z1¦, ale to nie robi różnicy: porównuje tablicę ciągów z wejściowym ciągiem pod kątem nierówności, dając 1, ponieważ nie są one równe. Różnica między nimi polega na tym, że Z⁻¦jest diademowa, ponieważ pozwala nam pisać œṗZ⁻¦zamiast œṗ¹Z1¦. Wynika to z tego, że dyad ( œṗ), po której następuje monada ( œṗ¹Z1¦), jest rozwidleniem (monada jest stosowana do argumentu łańcucha / ciągu wejściowego, a zwracana wartość jest przekazywana jako właściwy argument œṗ), podczas gdy za nią znajduje się inna diada (lub na końcu łańcucha) jest hakiem , tzn. jego prawy argument jest argumentem łańcucha.

Pozostało tylko sprawdzić palindromiczność. µrozpoczyna nowy łańcuch (jednowartościowy) kto jest argumentem jest . Odwracania atom cofa wszystkie ciągi w A (lecz nie sobie), a następnie porównuje wynik z A do równości. Zwrócony Boolean 1 wskazuje na w pełni palindromiczny trójkąt; inne ciągi zwracałyby 0 .U

Dennis
źródło
Naprawdę powinienem nauczyć się czytać Galaretkę. (Wyjaśnienie, proszę?)
97
1
Zredagowałem swoją odpowiedź.
Dennis
6

Japt , 25 21 17 bajtów

Zaoszczędzono 2 bajty dzięki @obarakon

ò@°T ¬v1
pUmg)eêP

Przetestuj online!

Jak to działa

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

Pamiętaj, że nie musimy sprawdzać obu stron; jeśli boki nie są takie same, co najmniej jeden z rzędów nie jest palindromem.

ETHprodukcje
źródło
Czy to multilinium to nowa funkcja Japt?
Luke
@Luke Tak, właśnie dodałem to we wtorek. To moja pierwsza szansa, aby się tym pochwalić :-)
ETHproductions
Nieważne moja wskazówka golfowa. Po prostu sprawdza, czy każda linia była palindromiczna, co również dało prawidłowe wyniki ...
Luke
4

05AB1E , 18 bajtów

gÅÉ£õÜÐíQs€¬āÈÏÂQ*

Wykorzystuje kodowanie 05AB1E . Wypróbuj online!

Adnan
źródło
Możesz zaoszczędzić jeden bajt, modyfikując go niecogÅÉ£ÐíQs€¬āÈÏJÂQ*
kalsowerus
gÅÉ£ty chytry lisa ... Nie doceniam tychlist-commands.py
Magic Octopus Urn
4

Galaretka , 18 lat 16 bajtów

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

Wypróbuj online!

Podziękowania dla Jonathana Allana za trywialne, ale nie tak oczywiste oszczędności w postaci 2 bajtów.

Erik the Outgolfer
źródło
Użyj mojej trójkątnej konstrukcji i zapisz bajt:JƲ0;œṗ⁸ZḢ$ṭ$ŒḂ€Ạ
Jonathan Allan
... w rzeczywistości połączyć ten pomysł z nieprawdą i zaoszczędzić kolejny bajt, ponieważ partycjonowanie „zip najkrótszy”:J²‘Ṭœṗ⁸ZḢ$ṭ$ŒḂ€Ạ
Jonathan Allan
@JonathanAllan Umm ... dlaczego w ogóle muszę ½? Teraz Jma to większy sens ...
Erik the Outgolfer,
3

JavaScript (ES6), 112 bajtów

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)

ti uzbierz boki, aby można je było przetestować na końcu.

Neil
źródło
2

C #, 184 bajty

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

Myślałem, że rozwiązanie wygląda dobrze, dopóki nie dotarłem do części palindromowej

Wersja bez golfa:

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);
        };
LiefdeWen
źródło
Czy możesz przejść e=..do linii pętli for, aby zapisać bajt? Nie ma potrzeby liczenia nowych wierszy w liczbie bajtów, więc zakładam, że nie.
TheLethalCoder,
Nie, nie liczę nowych linii, nie mogę przenieść litery e do pętli, ponieważ potrzebuję jej w instrukcji return.
LiefdeWen
Miałem na myśli tak....; i < s;e = f.Substring(s - k)){c+=....
TheLethalCoder,
2

Java 8, 358 301 bajtów

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

Dane wejściowe to a String, dane wyjściowe to boolean.

Wyjaśnienie:

Wypróbuj tutaj.

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)
Kevin Cruijssen
źródło
1

Galaretka ,  20  21 bajtów

+2 bajty - wypuściłem błędny kod :(
-1 bajt - przeniesiono z formowania jak nieparzyste liczby całkowite do partycjonowania według kwadratowych indeksów

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

Monadyczny link akceptujący listę znaków i zwracający 1(Prawda) lub0 (Falsey).
Uwaga: wykorzystuje część specyfikacji, która ogranicza dane wejściowe do długości kwadratu.

Wypróbuj online!lub zobacz pakiet testowy .

Można to uprościć do 17 bajtów , zauważając, że jeśli wszystkie wiersze są palindromami, tylko jedna „strona” wymaga sprawdzenia (JƲ0;œṗ⁸ZḢ$ṭ$ŒḂ€Ạ ), jednak Erik Outgolfer już zauważył ten fakt i wykorzystał go w swojej odpowiedzi więc im metodę budowy trójkąta bajt tam.

Dodatkowo można to z kolei poprawić 16 bajtów , zauważając, że partycjonowanie według prawdziwych indeksów nie ma znaczenia, jeśli w lewym argumencie występuje nadmiar ( J²‘Ṭœṗ⁸ZḢ$ṭ$ŒḂ€Ạ).

W jaki sposób?

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
Jonathan Allan
źródło
1
Cholera, właśnie miałem odpowiedzieć na galaretkę. Chociaż technicznie moje jest złe i jak dwa razy dłużej ... dobra robota :): P
HyperNeutrino
„zauważając, że partycjonowanie według prawdziwych indeksów nie ma nic przeciwko, jeśli w lewym argumencie występuje nadmiar”, zauważyłem również przed czytaniem.
Erik the Outgolfer,
1

Mathematica, 156 bajtów

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&


Wejście

[„1101”]

J42161217
źródło
Czy nie możesz zastąpić If[<stuff>, True, False]tylko <stuff>? I myślę, że And@@(...)jest krótszy niż Count[...,True]==s, co oznacza również, że nie musisz definiować sjako zmiennej.
Nie drzewo,
Zaraz, czy to faktycznie sprawdza przekątne? Otrzymuję fałszywe wyniki pozytywne dla kilku przypadków testowych ( "1202"i "160625052").
Nie drzewo,
wszystkie problemy naprawione
J42161217,
1

PHP , 97 bajtów

for($t=1;~$s=substr($argn,$i**2,$i++*2+1);$d.=$s[0])$t&=strrev($s)==$s;$t&=strrev($d)==$d;echo$t;

Wypróbuj online!

Jörg Hülsermann
źródło
Zaraz, czy to faktycznie sprawdza przekątne? Otrzymuję fałszywe wyniki pozytywne dla kilku przypadków testowych („1202” i „160625052”).
J42161217,
@Jenny_mathy teraz działa
Jörg Hülsermann
1

Java, 136 bajtów

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

Korzysta MutableList<Character>z kolekcji 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;
};
Nathan Merrill
źródło
1

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

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

Wypróbuj online!

Dane wyjściowe undef(puste, puste) dla wartości true, dowolna liczba dla false

Xcali
źródło
0

Excel VBA, 87 bajtów

Anonimowa funkcja bezpośredniego okna VBE, która przenosi dane wejściowe z komórki [A1]i dane wyjściowe do bezpośredniego okna 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
Taylor Scott
źródło
0

Python 2 , 128 118 115 bajtów

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)

Wypróbuj online!

TFeld
źródło