Wyraźnie nawiasuj ciągi APL

19

W APL możesz pisać funkcje ukryte, zwane pociągami . Ich działanie nie ma znaczenia dla tego wyzwania. Oto różne sposoby ich grupowania za pomocą funkcji:

⍴      -> ⍴
⍴⍴     -> ⍴⍴
⍴⍴⍴    -> ⍴⍴⍴
⍴⍴⍴⍴   -> ⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴  -> ⍴⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴⍴ -> ⍴(⍴⍴(⍴⍴⍴))
...

Kolejność pozostaje taka sama. Procedura jest taka, że ​​dopóki są ściśle więcej niż 3 funkcje, ostatnie 3 funkcje są zgrupowane w jedną funkcję. Jeśli spotkamy zagnieżdżony pociąg, najpierw nawiasujemy go, zanim przejdziemy dalej. Oto procedura zastosowana do ⍴⍴⍴⍴⍴⍴:

Step 0: ⍴⍴⍴⍴⍴⍴
There are strictly more than 3 functions, repeat.
Step 1: ⍴⍴⍴(⍴⍴⍴)
There are strictly more than 3 functions, repeat.
Step 2: ⍴(⍴⍴(⍴⍴⍴))
There are 3 or less functions, we're done.

Oto ta sama procedura stosowana do ⍴⍴⍴(⍴⍴)⍴(⍴⍴⍴⍴(⍴⍴⍴))⍴⍴:

Step 0: ⍴⍴⍴(⍴⍴)⍴(⍴⍴⍴⍴(⍴⍴⍴))⍴⍴
There are strictly more than 3 functions, repeat.
We have met a nested train, applying procedure to that first:
  Step 0: ⍴⍴⍴⍴(⍴⍴⍴)
  There are strictly more than 3 functions, repeat.
  We have met a nested train, applying procedure to that first:
    Step 0: ⍴⍴⍴
    There are 3 or less functions, we're done.
  Step 1: ⍴⍴(⍴⍴(⍴⍴⍴))
  There are 3 or less functions, we're done.
Step 1: ⍴⍴⍴(⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴)
There are strictly more than 3 functions, repeat.
We have met a nested train, applying procedure to that first:
  Step 0: ⍴⍴
  There are 3 or less functions, we're done.
Step 2: ⍴⍴⍴((⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴))
There are strictly more than 3 functions, repeat.
Step 3: ⍴(⍴⍴((⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴)))
There are 3 functions or less, we're done.

Wejście

W przypadku tego wyzwania dane wejściowe zostaną uproszczone. Oznacza to, że możesz wybrać 2 różne znaki dla nawiasów otwierających i zamykających oraz 1 znak dla funkcji, różne od tych wybranych dla nawiasów. Wybrane znaki muszą być spójne. Dane wejściowe nie będą puste i nie będą zawierać nawiasów bez zawartości (tj ().).

Wynik

Ponownie możesz wybrać 3 różne znaki, 2 dla nawiasów i 1 dla funkcji. Zauważ, że nie muszą być one takie same jak te wybrane do wprowadzania, ale muszą być spójne.

Zasady

  • Jeśli istnieją nawiasy, które zawierają tylko jedną funkcję w danych wejściowych, musisz je usunąć w danych wyjściowych. Twoje dane wyjściowe nie mogą zawierać niepotrzebnych nawiasów (tj. Obejmujących tylko jedną funkcję lub obejmujących całe dane wyjściowe).
  • Nie musisz implementować zastosowanego tutaj algorytmu, o ile twoje rozwiązanie jest odpowiednie dla tego wyzwania.
  • Dane wejściowe i wyjściowe są łańcuchami w formacie objaśnionym w sekcjach Wejście i Wyjście. Dane wejściowe będą miały co najmniej jeden znak.
  • Korzystanie ze standardowych luk jest surowo zabronione.
  • To jest , więc wygrywa najkrótsza odpowiedź. Jednak nie będzie akceptowanej odpowiedzi, ponieważ jest to konkurs dla poszczególnych języków i zachęca do odpowiadania w językach, w których zadanie to spowodowałoby dłuższy kod w porównaniu do kodu napisanego w innych językach.

Przypadki testowe

Używane tutaj znaki to ()⍴powinieneś zastąpić je wybranymi znakami.

⍴                          -> ⍴
⍴                          -> ⍴
⍴⍴                         -> ⍴⍴
⍴⍴⍴                        -> ⍴⍴⍴
⍴⍴⍴⍴                       -> ⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴            -> ⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴⍴))))))
⍴⍴⍴⍴⍴(⍴⍴⍴)⍴⍴(⍴(⍴⍴⍴)⍴⍴⍴)⍴⍴⍴ -> ⍴(⍴⍴(⍴⍴((⍴⍴⍴)⍴(⍴(⍴(⍴⍴⍴)(⍴⍴⍴))(⍴⍴⍴)))))
(⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)            -> (⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)
(⍴⍴⍴)(⍴⍴⍴)⍴⍴⍴              -> (⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)
⍴⍴(⍴)⍴⍴                    -> ⍴⍴(⍴⍴⍴)
((⍴⍴))                     -> ⍴⍴
⍴⍴((⍴⍴))⍴⍴                 -> ⍴⍴((⍴⍴)⍴⍴)

To wyzwanie zostało opublikowane w piaskownicy. Jeśli masz wymagane uprawnienia, możesz wyświetlić post w piaskownicy tutaj .

Erik the Outgolfer
źródło
2
Myślę, że Fully to lepszy tytuł niż Clearly .
Adám
@ Adám Spodziewałem się tej odpowiedzi referencyjnej, ale nie otrzyma wielu pozytywnych opinii;)
Erik the Outgolfer
@ Adám Najwyraźniej część tytułu odnosi się do faktu, że musisz usunąć niepotrzebne nawiasy. W pełni powinieneś zrobić, kiedy odpowiesz na wyzwanie; p
Erik the Outgolfer
Czy to prawda, że ​​ta funkcja zawsze będzie idempotentna?
Esolanging Fruit,

Odpowiedzi:

7

APL (Dyalog Classic) , 71 68 65 63 bajtów

0{⍵≡⍕⍵:⍵⋄⍬≡⍵:'⍬'1=≢⍵:⍺∇⊃⍵⋄3≥≢⍵:⍺⌽')(',⍣⍺∊1∇¨⍵⋄⍺∇¯3(↓,∘⊂1∇↑)⍵}⍎

Wypróbuj online!

Znaki I wybrał dla I / O są '(', ')'i '⍬'.

To rozwiązanie jest pociągiem APL.

analizuje dane wejściowe tak, jakby to była zagnieżdżona tablica - drzewo z pustymi wektorami liczbowymi ( ) jak liście.

Dfn (tj. Lambda - { }) przegląda drzewo rekurencyjnie i konwertuje je na odpowiednio nawiasowany ciąg. Lewy argument kontroluje, czy w razie potrzeby należy dodać nawiasy do bieżącego poziomu.

Dfn obsługuje następujące przypadki w oparciu o właściwy argument:

  • jeśli to jest już string ( ⍵≡⍕⍵), zwróć go

  • jeśli tak , zwróć znak'⍬'

  • jeśli jest to singleton, po prostu kop głębiej ( jest to symbol rekurencyjnego połączenia)

  • jeśli jego długość wynosi ≤3, powtórz dla każdego z elementów i w ()razie potrzeby otaczaj

  • w przeciwnym razie użyj 3-ogona, przygotuj wszystko oprócz 3-ogona i powtórz ponownie

ngn
źródło
Wygląda na 63 znaki, większość z nich Unicode. Jakie kodowanie znaków generuje 63 bajty? Robię 141 bajtów w UTF8.
Corey,
@Corey Relevant meta post .
Adám
@ Adám Dzięki za to. Spojrzałem, ale nie wiedziałem, czego szukać, aby uzyskać tę odpowiedź.
Corey,
3

Python 2 , 224 208 204 bajtów

-16 bajtów dzięki Mr. Xcoder -4 bajtów dzięki ovs

r=str.replace
p='p'
def c(l):
 while len(l)>3:l=l[:-3]+(l[-3:],)
 return l and map(c,l)or l
print r(r(r(r(r(`c(eval(r(r(r(input(),'(p)',p),p,'[],'),')','),')))`,'[]',p),*'[('),*'])'),' ',''),',','')[1:-1]

Wypróbuj online! lub Wypróbuj wszystkie przypadki testowe

Kod można podzielić na 3 główne kroki:
Konwersja danych wejściowych na zagnieżdżoną listę i zamiana (p)->p. Pojedyncza funkcja pzostanie zastąpiona pustą listą.

eval(r(r(r(input(),'(p)',p),p,'[],'),')','),'))

Funkcja rekurencyjna do stosowania reguły „3 lub mniej” na bieżącej liście i wywoływania się na wszystkich podlistach.

def c(l):
 while len(l)>3:l=l[:-3]+(l[-3:],)
 return l and map(c,l)or l

Wiele zamienników do formatu do żądanego formatu wyjściowego

r(r(r(r(r(`c(...)`,'[]',p),*'[('),*'])'),' ',''),',','')[1:-1]
Pręt
źródło
204 bajty
ovs
1
To nie upraszcza ((pp))(lub p((pp))p).
Martin Ender,
2

CJam , 56 bajtów

Beats APL!

lW%~]]]{{_,{K_,({~}|}&}%{_,3>}{3/(aa\+:~}w}:K~~`1>W<W%S/

Wypróbuj online!

To działa (myślę) i nie mam pojęcia, dlaczego ...

Znaki wejściowe są ][Tdla ()⍴, a znaki wyjściowe są ][0dla ()⍴(tak, oznacza to, że są odwrócone od tego, czego można oczekiwać; na przykład możesz przekazać TTT]TT[T]TTTT]TTT[[TT).

Omówienie wysokiego poziomu

Program działa z wejściem do tyłu, ponieważ jest to wygodniejsze. Aby przeanalizować dane wejściowe, korzystamy z parsera CJam - odwrócenie i wykonanie danych wejściowych zapewnia (odwrotnie) przeanalizowaną formę danych wejściowych.

Następnie określamy procedurę K. Kwykonuje większość pracy związanej z naszym przesłaniem i działa w następujący sposób:

  • Tablica wejściowa będzie mieszanką zer i niepustych tablic podrzędnych. Zidentyfikuj pod-tablice i zastosuj się Kdo nich rekurencyjnie . Wynikiem powinna być kolejna tablica, a jeśli tablica składa się tylko z jednego elementu, rozpakuj ją (spowoduje to usunięcie zbędnych nawiasów).
  • Tak długo, jak wynik zawiera więcej niż trzy elementy, zgrupuj pierwsze trzy (nie ostatnie trzy; pamiętaj, że dane wejściowe są przetwarzane wstecz) w jedną listę.
  • Zwróć wynik.

Stosując Kdo danych wejściowych, otrzymujemy odpowiednio nawiasowaną formę danych wejściowych (jedyną rzeczą do odnotowania jest to, że faktycznie zawijamy dane wejściowe na liście singletonów, a następnie rozpakowujemy je; powodem tego jest to, że chcemy fragmentu, który rozpakowuje singletony aby zastosować się do programu najwyższego poziomu, a nie tylko jego tablic podrzędnych). Następnie po prostu stosujemy minimalne formatowanie, aby uzyskać nasz wynik.

Kilka wyjaśnień dla golfowych bitów

Golf, z którego jestem najbardziej dumny, wykorzystuje ,do sprawdzania liczb całkowitych i tablic.

  • Jeśli wierzchołkiem stosu jest liczba całkowita n , ,generuje zakres [0..n) . Ponieważ jedyną liczbą całkowitą , na którą się natkniemy 0, jest zawsze pusta lista [], czyli falsey.
  • Jeśli wierzchołkiem stosu jest tablica, ,bierze swoją długość. Ponieważ wszystkie tablice, które napotykamy, będą niepuste, zawsze daje nam to dodatnią liczbę całkowitą, co jest prawdą.

Innym golfem, który może być interesujący, jest metoda, której używam do grupowania pierwszych trzech elementów tablicy; jest to trochę podobne do mojego przesłania „golfowy kod tłumacza Turinga w pełnym języku” . CJam nie ma krótkiego sposobu na podzielenie tablicy na dwie części (możesz spróbować odciąć pierwszą część, a następnie drugą część, zachowując oryginalną tablicę i indeks na stosie, ale to nie działa zbyt dobrze) , więc zamiast tego używam 3/, który grupuje tablicę w bloki po trzy. Następnie mogę oderwać pierwszy element (, owinąć tablicę dwa razy aa, a następnie dołączyć z powrotem na początku listy \+. Powodem, dla którego dwukrotnie zawijamy tablicę jest to, że musimy zdjąć warstwę :~, ponieważ zgrupowaliśmy resztę tablicy również w sekcje.

Esolanging Fruit
źródło
Nitpick: pokonuje APL bez wbudowanych funkcji .
Erik the Outgolfer,
@EriktheOutgolfer Do przyjęcia.
Esolanging Fruit 12.12.17
0

JavaScript (ES6), 149 146 bajtów

i='a';f=s=>s==(s=s[R='replace'](/\((\w+)\)/,(q,t)=>(f[q=i+=0]=f(t),q)))&&s==(s=s[R](/(?!^)((a0+|p){3})$/,"($1)"))?s[R](/a0+/g,t=>`(${f[t]})`):f(s)
<textarea cols=80 id=I>ppp(pp)p(pppp(ppp))pp</textarea><br>
<button onclick=O.innerText=f(I.value)>Run</button><br>
<pre id=O></pre>

Używa ()p, chociaż możesz użyć innej litery, możesz po prostu zmienić pkoniec.

ETHprodukcje
źródło