Dowiedz się, czy jest to prawidłowy program Stack Cats w stylu Stack Cats!

16

tło

Stack Cats to odwracalny ezoteryczny język stworzony przez Martina Endera. Każde polecenie w stosie kotów jest albo odwrotnością samego siebie (reprezentowaną jako znak symetryczny, np. -_:T|), Albo ma swoje polecenie odwrotne (reprezentowane jako odbicie lustrzane, takie jak () {} [] <>). Stack Cats ma silne wymagania składniowe, aby cały program był lustrzanym odbiciem samego siebie. Zauważ, że oznacza to, że każdy poprawny program Stack Cats jest naturalnym ambigramem obrazu lustrzanego .

Oto cały zestaw poleceń Stack Cats:

  • Samosymetryczny: !*+-:=ITX^_|
  • Pary symetryczne: () {} [] <> \/

Wszelkie inne znaki są nieprawidłowe; każde wejście zawierające znak spoza powyższego zestawu znaków powinno dawać wartość false.

Język ma dodatkowe ograniczenie ()i {}pary muszą być zawsze zrównoważone, ale dla uproszczenia nie musisz sprawdzać tego warunku.

Oto kilka przykładów prawidłowego programu Stack Cats (ponownie, pamiętaj, że nie sprawdzasz zrównoważonych elementów):

{[+]==[+]}
[)>^<(]
({T)}|{(T})
<(*]{[:!-_:>}<[<)*(>]>{<:_-!:]}[*)>

Te nie są:

b<+>d
())(
({[<++<]})

Wyzwanie

Napisz program lub funkcję, która określa, czy podany ciąg jest poprawnym programem Stack Cats. Twój kod powinien być także naturalnym ambigramem obrazu lustrzanego , co oznacza:

  • Twój kod powinien być lustrzanym odbiciem samego siebie.
    • Twój kod może mieć jedną lub więcej nowych linii, o ile cały kod, wyświetlany w sposób naturalny, jest lustrzanym odbiciem samego siebie.
    • Możesz pominąć lub dodać końcowe białe spacje w każdej linii, ponieważ nie zmienia to wyświetlania.
    • Znaki tabulacji są niedozwolone, ponieważ wyświetlają się niejasności.

Uwaga: Twój kod nie musi być prawidłowym programem Stack Cats; może zawierać pewne dodatkowe znaki, które nie są dozwolone w Stack Cats. (Pełna lista znajduje się poniżej).

Na przykład następujące dwa programy są symetryczne (a zatem prawidłowe przesłanie ), podczas gdy trzeci nie jest:

({bTd})
[<q|p>]
({bTd})
  IXI
({bTd})
IXI
  • Jeśli chodzi o „symetrię lustrzaną”, brana jest pod uwagę tylko symetria w stylu Stack Cats (np. ({IH})Nie jest poprawnym przesłaniem, mimo że ma symetrię lustrzaną).
  • Twój kod może zawierać tylko te zestawy znaków oraz znak nowej linii:
    • Samosymetryczny: spacja ( 0x20) +!"'*+-.8:=AHIMOTUVWXY^_ovwx|
    • Pary symetryczne: () /\ <> [] bd pq {}

Zestaw znaków jest wybierany tak, aby był ściśle symetryczny lub samosymetryczny, gdy jest wyświetlany jako kod w SE.

Wejście i wyjście

Zakres wejściowy jest dowolnym ciągiem jednej linii drukowalnych znaków ASCII .

Możesz wybrać wejście jako ciąg znaków, listę znaków lub listę wartości ASCII.

Możesz wybrać wyjście:

  • Dowolna z wartości prawdy / fałszu określona przez wybrany język
    • Rzeczywiste wartości wyników mogą się różnić między danymi wejściowymi (np. Wyjście 1 dla prawdziwego wejścia i 2 dla innego prawdziwego).
    • Zamiana wartości prawdy i fałszu jest niedozwolona.
  • Dowolne dwie stałe wartości odpowiednio dla wartości prawda / fałsz
    • W takim przypadku wartości wynikowe powinny być dokładnie jedną z dwóch stałych wartości.

W formularzu należy podać metodę wprowadzania i wartości wyjściowe.

Warunki wygranej

To jest , więc wygrywa najmniej bajtów w każdym języku.

Notatki

  • Standardowe luki są jak zwykle zabronione.
  • Oczywiście możesz to rozwiązać w Stack Cats, ale jest szansa, że ​​nie możesz użyć flagi, która pozwala zmniejszyć rozmiar kodu o połowę. I jest to bardzo trudny do opanowania język: P
Bubbler
źródło
1
Dlaczego ostro #zabronione?
tsh
1
@tsh Jest lekko wypaczony w wielu czcionkach, w tym w kodzie czcionki w SE (przynajmniej tak widzę w Chrome).
Bubbler
@DLosc Próbowałem wyjaśnić kilka punktów wokół tego. Ale jeśli uważasz, że opis jest nadal niejasny, możesz go edytować.
Bubbler

Odpowiedzi:

16

JavaScript (ES6), 487 467 378 298 292 280 266 264 bajtów

Zaoszczędź 14 bajtów dzięki @Bubbler

I=>(V=v=>!I[v]||((T=o=>[[]][+!!A[o]]||[(I[v]!=A[o]||A)[o^o<88/8]]+T(++o))(8-8)==I.pop())*V(++v))(V|(A='(){}[]<>\\/ !*+-:=ITX^_|'))//\\(('|_^XTI=:-+*! \//<>[]{}()'=A)|V)((v++)V*(()qoq.I==(8-8)((o++)T+[[8\88>o^o](A||[o]A=![v]I)]||[[o]A!!+][[]]<=o=T))||[v]I!<=v=V)<=I

Definiuje anonimową funkcję, która pobiera tablicę znaków i zwraca żądane dane wyjściowe. Dane wyjściowe są zgodne z prawdą / fałszem; zwykle 1/ 0, ale pusty ciąg daje true.

W jaki sposób?

Najbardziej oczywistą sztuczką jest użycie //\\jako punktu centralnego do skomentowania lustrzanej wersji kodu. Następnie staje się grą polegającą na znalezieniu najkrótszego sposobu rozwiązania problemu za pomocą tylko podanego zestawu znaków.

Pierwszym problemem, na jaki napotykamy, jest brak słów kluczowych i wbudowanych funkcji. Cud wciąż mamy.pop() , ale wszystko inne trzeba będzie zrobić za pomocą dozwolonych operatorów (w tym a[b]i f(c)) z rekurencją w celu emulacji pętli.

Druga kwestia to brak operatorów logicznych. Ani &i nie ?są dozwolone, co oznacza jedynym operatorem, z którego możemy skorzystać, jest ||. Dlatego musimy dokładnie ustrukturyzować naszą logikę, aby to uwzględnić.

Pierwszą rzeczą, którą zrobiłem, było zdefiniowanie funkcji T która odzwierciedla indywidualny charakter. Podstawową ideą jest zapętlanie każdej postaci w szeregu znaków, które można wykonać w lustrze, testując każdą z nich pod kątem równości z danym char. Jeśli jest on równy, wracamy swoje lustrzane char co index^1za (){}[]<>\/lub char sama do końca.

Pierwszym problemem, na który natknąłem się tutaj, było uzyskanie albo lustrzanego char albo wartości falsy przy każdej iteracji. Rozwiązaniem, które ostatecznie wymyśliłem, było (x!=A[o]||A)[o^o<88/8], gdzie xjest znak wejściowy, Ajest lustrzanym alfabetem i ojest bieżącym indeksem. Jeśli xnie jest taki sam jak A[o], daje to true, a wyrażenie indeksu ocenia na undefined; w przeciwnym razie||A zostanie aktywowany, a my skończymy A[o^(o<11)].

Drugim problemem jest zakończenie rekursji. Odkryłem, że najlepszym sposobem na to jest po prostu konkatenacja wyników każdej iteracji, zwracanie pustego ciągu po osiągnięciu końca A. Stwarza to nam dwa kolejne problemy: konwersję undefineds na puste łańcuchy i zwrócenie ||czegoś pustego łańcucha . Można je rozwiązać za pomocą nadużywania tablic: [a]+""daje ciąg znaków alub ciąg pusty, jeśli nie ajest zdefiniowany. Jako bonus, []jest zgodny z prawdą, ale łączy się z pustym ciągiem, dzięki czemu możemy wygodnie użyć go jako „prawdziwego pustego ciągu”.

Teraz możemy użyć Tfunkcji do odzwierciedlenia dowolnego pojedynczego znaku. Robimy to rekurencyjnie, porównując lustro I[v++]do, I.pop()aż do osiągnięcia końca tablicy znaków. Nie możemy użyć &&lub &sprawdzić, czy wszystkie porównania są zgodne z prawdą, ale skorzystaj *zamiast tego. Pomnożenie wszystkich tych wyników razem daje1 jeśli każda postać jest zwierciadłem przeciwnej lub 0jeśli jakiekolwiek porównanie się nie powiedzie.

I tak w zasadzie działa ta odpowiedź. Prawdopodobnie nie wyjaśniłem tego bardzo jasno, więc zadawaj pytania i wskaż błędy, które popełniłem.

ETHprodukcje
źródło
U=([A,...H])=>!(V=H.pop())||!(W=([x,...X]=(T="!*+-:=ITX^_|")+"(){}[]<>\\/",[o,...O]=T+")(}{][></\\")=>!x||((o!=A)+(x!=V))*(W(X,O)))()*U(H)//...280 bajtów
tsh
@tsh przecinki nie są dozwolone w kodzie źródłowym, ponieważ nie są symetryczne (w kodzie czcionki SE) i nie mają lustra (w ASCII, tak)
ETHproductions
przepraszam, tęskniłem za tą częścią.
tsh
@tsh Na początku też za nim tęskniłem i spędziłem 20 minut na rozwiązaniu tylko po to, aby zdać sobie sprawę, że to nie może być ważne: P
ETHproductions
W każdym razie, skoro już opublikowałeś rozwiązanie JavaScript. Nie potrzebujemy teraz innego rozwiązania JSF * k ... // Gdybym był tobą, naprawiłbym to po prostu kompilując to do JSF * k ...
tsh
1

Stax , 76 70 bajtów

:Wx^^MH_=_"{([</!*+-:=ITX^_|":W-!*pq*!-W:"|_^XTI=:-+*!\>])}"_=_HM^^xW:

Uruchom i debuguj

Stax jest przyjacielem Stack Cats i ma elementy wewnętrzne do generowania późniejszej połowy programu Stack Cats z pierwszej połowy. Jeśli nie obchodzi nas ograniczenie źródła i nie musimy sprawdzać zestawu znaków, oto 4-bajtowe rozwiązanie:

4 bajty

:R_=

Uruchom i debuguj

Wyjaśnienie

:Wx^^MH_=_"{([</!*+-:=ITX^_|":W-!*pq...
:W                                         "Mirror" the string
                                           Equivalent to appending the reverse of the string to itself
                                           And map `{([</\>])}` to its mirror in the appended string
  x^^                                      2, but we can't just use `2` here ...
     MH                                    Partition the "mirror"ed string to two parts, take the later part.
       _=                                  The string is the same as the original one (*)
                                           `:Wx^^MH_=` is just `:R_=`, but we can't use `R` here ...
         _                                 Input string
          "{([</!*+-:=ITX^_|":W-           Remove valid characters from input
                                !          The final string is empty (**)
                                 *         (*) and (**)
                                  p        Pop and print result
                                   q       Peek stack and print
                                           Since the stack is now empty, this causes the program to terminate
                                    ...    Not executed
Weijun Zhou
źródło
Istnienie Ri Wjest naprawdę interesujące. pqImponujące jest również zakończenie programu przez połączenie.
Bubbler
Dziękuję Ci. Instrukcje mają w rzeczywistości dwa bajty: :Ri :W. Wydaje mi się, że nie mogę nic poradzić, by powiedzieć wszystkim, że w Stax są takie elementy wewnętrzne.
Weijun Zhou