Klammern Sie die APL-Züge deutlich ein

19

In APL können Sie implizite Funktionen schreiben, die als Züge bezeichnet werden . Wie sie funktionieren, spielt für diese Herausforderung keine Rolle. Hier sind die verschiedenen Arten, wie sie unter Verwendung der Funktion gruppiert werden können:

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

Die Reihenfolge bleibt gleich. Die Prozedur ist, dass die letzten 3 Funktionen in einer Funktion zusammengefasst werden, solange es streng genommen mehr als 3 Funktionen gibt. Wenn wir auf einen verschachtelten Zug treffen, setzen wir diesen zuerst in Klammern, bevor wir fortfahren. Hier ist das Verfahren angewendet auf ⍴⍴⍴⍴⍴⍴:

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.

Hier gilt das gleiche Verfahren für ⍴⍴⍴(⍴⍴)⍴(⍴⍴⍴⍴(⍴⍴⍴))⍴⍴:

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.

Eingang

Für diese Herausforderung wird die Eingabe vereinfacht. Dies bedeutet, dass Sie 2 verschiedene Zeichen zum Öffnen und Schließen von Klammern und 1 Zeichen für Funktionen auswählen können, die sich von den für Klammern ausgewählten unterscheiden. Die Zeichen, die Sie auswählen, müssen konsistent sein. Die Eingabe ist nicht leer und enthält keine Klammern ohne Inhalt (dh ()).

Ausgabe

Auch hier können Sie 3 verschiedene Zeichen wählen, 2 für Klammern und 1 für Funktionen. Beachten Sie, dass sie nicht mit den für die Eingabe ausgewählten identisch sein müssen, aber konsistent sein müssen.

Regeln

  • Wenn Klammern in der Eingabe nur eine Funktion enthalten, müssen Sie diese in der Ausgabe entfernen. Ihre Ausgabe darf keine nicht benötigten Klammern enthalten (dh nur eine Funktion oder die gesamte Ausgabe einschließen).
  • Sie müssen den hier verwendeten Algorithmus nicht implementieren, solange Ihre Lösung für diese Herausforderung gültig ist.
  • Eingabe und Ausgabe sind Zeichenfolgen in dem Format, das in den Abschnitten Eingabe und Ausgabe erläutert wird. Die Eingabe hat mindestens ein Zeichen.
  • Die Verwendung der Standardlücken ist strengstens untersagt.
  • Das ist , also gewinnt die kürzeste Antwort. Es wird jedoch keine akzeptierte Antwort geben, da dies ein sprachspezifischer Wettbewerb ist, und die Beantwortung in Sprachen zu fördern, in denen diese Aufgabe im Vergleich zu in anderen Sprachen geschriebenem Code zu längerem Code führen würde.

Testfälle

Die Zeichen, die hier verwendet werden ()⍴, sollten durch die von Ihnen gewählten Zeichen ersetzt werden.

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

Diese Herausforderung wurde in der Sandbox veröffentlicht. Wenn Sie über die erforderlichen Berechtigungen verfügen, können Sie den Sandbox-Beitrag hier anzeigen .

Erik der Outgolfer
quelle
2
Ich denke, Fully ist ein besserer Titel als Clearly .
Adám
@ Adám Ich habe diese Referenzantwort erwartet, es wird aber nicht viele positive Stimmen bekommen;)
Erik the Outgolfer
@ Adám Der Teil Klar im Titel bezieht sich auf die Tatsache, dass Sie nicht benötigte Klammern entfernen müssen. Vollständig ist etwas, was Sie tun müssen, wenn Sie eine Herausforderung beantworten: p
Erik the Outgolfer
Stimmt es, dass diese Funktion immer idempotent sein wird?
Esolanging Fruit

Antworten:

7

APL (Dyalog Classic) , 71 68 65 63 Bytes

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

Probieren Sie es online!

Die Charaktere , die ich für I / O gewählt sind '(', ')'und '⍬'.

Diese Lösung ist selbst ein APL-Zug.

analysiert die Eingabe wie ein verschachteltes Array - ein Baum mit leeren numerischen Vektoren ( ) als Blättern.

Das dfn (dh Lambda - { }) durchläuft den Baum rekursiv und konvertiert ihn in eine ordnungsgemäß in Klammern gesetzte Zeichenfolge. Das linke Argument steuert, ob bei Bedarf Klammern zur aktuellen Ebene hinzugefügt werden sollen.

Das DFN behandelt die folgenden Fälle basierend auf dem richtigen Argument:

  • Wenn es sich bereits um eine Zeichenfolge ( ⍵≡⍕⍵) handelt, geben Sie diese zurück

  • Wenn ja , gib das Zeichen zurück'⍬'

  • Wenn es sich um einen Singleton handelt, gehen Sie einfach tiefer ( ist das Symbol für einen rekursiven Aufruf).

  • Wenn die Länge ≤3 ist, verwenden Sie für jedes Element einen Rekurs und umgeben Sie es ()gegebenenfalls mit

  • Andernfalls rekursieren Sie für den 3-Schwanz, stellen Sie alle bis auf den 3-Schwanz voran und rekursieren Sie erneut

ngn
quelle
Sieht aus wie 63 Zeichen, die meisten davon Unicode. Welche Zeichenkodierung ergibt dafür 63 Bytes? Ich mache es 141 Bytes in UTF8.
Corey
@ Corey Relevanter Meta-Beitrag .
Adám
@Adam Danke dafür. Ich sah nach, wusste aber nicht, wonach ich suchen sollte, um diese Antwort zu erhalten.
Corey
3

Python 2 , 224 208 204 Bytes

-16 Bytes dank Mr. Xcoder -4 Bytes dank 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]

Probieren Sie es online! oder Probieren Sie alle Testfälle aus

Der Code kann in drei Hauptschritte unterteilt werden:
Konvertieren der Eingabe in eine verschachtelte Liste und Ersetzen (p)->p. Die einzelne Funktion pwird durch eine leere Liste ersetzt.

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

Eine rekursive Funktion, um die Regel "3 oder weniger" auf die aktuelle Liste anzuwenden und sich selbst auf alle Unterlisten aufzurufen.

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

Viele Ersetzungen zum Formatieren auf das gewünschte Ausgabeformat

r(r(r(r(r(`c(...)`,'[]',p),*'[('),*'])'),' ',''),',','')[1:-1]
Stange
quelle
204 Bytes
Ovs
1
Dies vereinfacht ((pp))(oder p((pp))p) nicht.
Martin Ender
2

CJam , 56 Bytes

Schlägt APL!

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

Probieren Sie es online!

Das funktioniert (glaube ich) und ich habe keine Ahnung warum ...

Eingabezeichen sind ][Tfür ()⍴und Ausgabezeichen sind ][0für ()⍴(ja, dies bedeutet, sie sind umgekehrt zu dem, was Sie erwarten würden; Sie könnten zum Beispiel übergeben TTT]TT[T]TTTT]TTT[[TT).

Übergeordneter Überblick

Das Programm arbeitet mit der Eingabe rückwärts, weil es bequemer ist. Um die Eingabe zu analysieren, verwenden wir den Parser von CJam. Durch Umkehren und Ausführen der Eingabe wird die (rückwärts) analysierte Form der Eingabe bereitgestellt.

Wir definieren dann eine Prozedur K. Kerledigt die meiste Arbeit für unsere Einreichung und es funktioniert wie folgt:

  • Das Eingabearray ist eine Mischung aus Nullen und nicht leeren Unterarrays. Identifizieren Sie die Sub-Arrays und wenden Sie Ksie rekursiv an. Das Ergebnis sollte ein anderes Array sein. Wenn dieses Array nur aus einem einzelnen Element besteht, entpacken Sie es (dadurch werden redundante Klammern entfernt).
  • Solange das Ergebnis mehr als drei Elemente enthält, gruppieren Sie die ersten drei (nicht die letzten drei) in einer einzigen Liste. Denken Sie daran, dass die Eingabe rückwärts verarbeitet wird.
  • Gib das Ergebnis zurück.

Durch Anwenden Kauf die Eingabe erhalten wir die ordnungsgemäß in Klammern gesetzte Form der Eingabe (das Einzige, was zu beachten ist, ist, dass wir die Eingabe tatsächlich in eine Singleton-Liste einschließen und anschließend wieder auspacken; der Grund dafür ist, dass wir das Snippet benötigen, das Singletons auspackt auf das Top-Level-Programm anzuwenden, und nicht nur auf seine Sub-Arrays). Anschließend wenden wir nur eine minimale Formatierung an, um das Ergebnis zu erhalten.

Einige Erklärungen für Golfbits

Der Golf, auf den ich am stolzesten bin, ist ,die Überprüfung zwischen ganzen Zahlen und Arrays.

  • Wenn die Stapelspitze eine ganze Zahl n ist , ,wird der Bereich [0..n] generiert . Da die einzige Ganzzahl, auf die wir stoßen werden 0, immer die leere Liste ist [], die falsch ist.
  • Wenn der oberste Stapel ein Array ist, ,nimmt er seine Länge an. Da alle Arrays, denen wir begegnen, nicht leer sind, erhalten wir immer eine positive ganze Zahl, was wahr ist.

Ein weiteres interessantes Golfspiel ist die Methode, mit der ich die ersten drei Elemente des Arrays gruppiere. Es ist ein bisschen ähnlich wie bei meinem Beitrag "Turing Complete Language Interpreter Code Golf" . CJam hat keine kurze Möglichkeit, ein Array in zwei Teile zu zerlegen (Sie können versuchen, den ersten Teil und dann den anderen Teil abzutrennen, während Sie das ursprüngliche Array und den Index auf dem Stapel behalten, aber das funktioniert nicht sehr gut). Ich verwende stattdessen 3/, um ein Array in 3er-Blöcke zu gruppieren. Ich kann dann das erste Element (entfernen, das Array zweimal aaumbrechen und dann wieder an den Anfang der Liste anhängen \+. Der Grund, warum wir das Array zweimal umbrechen, ist, dass wir eine Ebene mit entfernen müssen :~, da wir den Rest des Arrays ebenfalls in Abschnitte gruppiert haben.

Esolanging Fruit
quelle
Nitpick: das schlägt APL ohne eingebauten Code .
Erik der Outgolfer
@EriktheOutgolfer Fair genug.
Esolanging Fruit
0

JavaScript (ES6), 149 146 Byte

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>

Verwendet ()p, obwohl Sie einen anderen Buchstaben verwenden, können Sie nur die pgegen Ende ändern .

ETHproductions
quelle