Duodyadische Kacheln sind Arten von quadratischen Funktionsblöcken , die zwei Eingänge (einen von oben und einen von links) und zwei Ausgänge (einen von rechts und einen von unten) haben. Jeder ihrer Ausgänge ist eine separate Funktion für beide Eingänge.
Wenn beispielsweise #
eine generische Kachel dargestellt wird, ist die rechte Ausgabe R
eine Funktion f
der Eingaben T
und L
und die untere Ausgabe B
eine weitere Funktion g
von T
und L
:
T
L#R R = f(T, L)
B B = g(T, L)
(Die Kacheln werden als "Duo" bezeichnet, da es zwei Funktionen gibt, und als "dyadisch", da beide Funktionen zwei Argumente haben .)
Kacheln können dann in einem Raster zusammengesetzt werden, wobei die Ausgaben einer Kachel direkt in die Eingaben der benachbarten Kacheln fließen. Hier geht zum Beispiel die rechte Ausgabe der linken #
in die linke Eingabe der rechten #
:
AB D = f(f(A, C), B)
C##D E = g(A, C)
EF F = g(f(A, C), B)
Sie können sich vorstellen, dass mit einer Reihe von duodyadischen Kacheln mit jeweils spezifischen Funktionen komplexe (und möglicherweise nützliche) Kompositionen erstellt werden könnten.
In dieser Herausforderung werden wir uns nur mit dem traditionellen Satz von zehn logikbasierten duodyadischen Kacheln befassen, bei denen alle Ein- und Ausgänge Einzelbit-Binärzahlen (Nullen oder Einsen) sind. Wir verwenden ein separates ASCII-Zeichen, um jeden Kacheltyp zu kennzeichnen.
Die Kachelzeichen und ihre Eingabe-Ausgabe-Beziehungen lauten wie folgt:
( T
gilt für die obere Eingabe, L
für die linke Eingabe, R
für die rechte Ausgabe, B
für die untere Ausgabe.)
- Null:
0
oder(Leerzeichen) →
R = 0
,B = 0
- Eins:
1
→R = 1
,B = 1
- Kreuz:
+
→R = L
,B = T
- Spiegel:
\
→R = T
,B = L
- Nur oben:
U
→R = T
,B = T
- Nur links:
)
→R = L
,B = L
- Nicht:
!
→R = not L
,B = not T
- Und:
&
→R = L and T
,B = L and T
- Oder:
|
→R = L or T
,B = L or T
- Xor:
^
→R = L xor T
,B = L xor T
Herausforderung
Schreiben Sie ein Programm oder eine Funktion, die ein rechteckiges Raster der Zeichen enthält 0 1+\U)!&|^
, das eine "Schaltung" darstellt, die mit den zehn duodyadischen Kacheln auf Logikbasis erstellt wurde. Sie müssen auch zwei Folgen von 0
's und 1
' s aufnehmen; Eine wird die linke Eingabespalte sein und eine wird die obere Eingabezeile sein. Ihr Programm / Ihre Funktion muss die unterste Ausgabezeile und die rechte Ausgabespalte (auch in 0
's und 1
' s) drucken / zurückgeben .
Zum Beispiel in diesem Raster
+++
+++
Alle Eingänge fließen direkt über das Netz zu den Ausgängen
ABC
D+++D
E+++E
ABC
Ein Eingang von 010
/ 01
hätte also einen Ausgang von 010
/ 01
:
010
0+++0
1+++1
010
Die genaue Ausgabe Ihres Programms wäre [bottom output row]\n[right output column]
oder [bottom output row]/[right output column]
:
010
01
oder
010/01
Wenn Sie eine Funktion geschrieben haben, können Sie die beiden Zeichenfolgen in einem Tupel oder einer Liste zurückgeben (oder sie trotzdem drucken).
Einzelheiten
- Nehmen Sie die drei Eingaben in einer angemessenen Weise als Zeichenfolge (vorzugsweise in der Reihenfolge Tabelle, obere Zeile, linke Spalte): Befehlszeile, Textdatei, SDTIN, Funktion arg.
- Sie können davon ausgehen, dass die Länge der Eingabezeilen und -spalten mit den Rastermaßen übereinstimmt und nur
0
's und1
' s enthält. - Ihr Raster muss die richtigen Zeichen enthalten (
0 1+\U)!&|^
). Denken Sie daran0
undmeinen Sie dasselbe.
Testfälle
(Lese I / O als top
/ left
→ bottom
/ right
.)
Nand:
&!
00
/ 0
→ 01
/ 1
00
/ 1
→ 01
/ 1
10
/ 0
→ 01
/ 1
10
/ 1
→ 11
/0
Alle:
1111
1\+\
1+\+
1\+\
Jede Eingabe sollte zu 1111
/ führen 1111
.
Xor from Nand: (Beachten Sie die Spalte mit den nachgestellten Leerzeichen)
\)+\
U&!&
+! !
\&!&
!
00000
/ 00000
→ 00000
/ 00000
00000
/ 10000
→ 00010
/ 00000
10000
/ 00000
→ 00010
/ 00000
10000
/ 10000
→ 00000
/00000
Zick-Zack:
+++\00000000
000\!!!!\000
00000000\+++
Das erste Bit des linken Eingangs wird zum letzten Bit des rechten Ausgangs. Alles andere ist 0
.
000000000000
/ 000
→ 000000000000
/ 000
000000000000
/ 100
→ 000000000000
/001
Vermehrung:
)))
UUU
U+U
U+U
UUU
Das erste Bit des linken Eingangs geht an alle Ausgänge.
000
/ 00000
→ 000
/ 00000
000
/ 10000
→ 111
/11111
Hier ist ein Pastebin aller 1 × 1-Rastertestfälle.
Wertung
Die kürzeste Übermittlung in Bytes gewinnt.
Bonus: Welche coolen "Circuits" kannst du machen?
PS: Googeln Sie nicht mit "duodyadischen Kacheln". Ich habe sie gestern erfunden. D
Wenn Sie darüber diskutieren möchten, wie Sie diese Idee zu einer vollwertigen Programmiersprache erweitern können, besuchen Sie diesen Chatroom .
quelle
Antworten:
Pyth, 122
Ein bisschen wie ein Monster. Verwendet einfach Rekursion, nichts Besonderes wie dynamisches Programmieren.
Online-Demonstration .
Die Eingabe erfolgt folgendermaßen: Zuerst das Raster (kein Escapezeichen, keine zusätzlichen Symbole) und dann die beiden Eingabezeilen, z. B. (Zick-Zack)
quelle
Mathematica,
331276270267264262252250 BytesDas
ist ein privat genutztes Unicode-Zeichen, das Mathematica als hochgestelltes Zeichen verwendetT
, dh es ist der Transpositionsoperator.Hier ist eine besser lesbare Version:
Dies ist eine unbenannte Funktion, die die drei Zeichenfolgen für die Raster-, oberen und linken Eingaben verwendet und die unteren und rechten Ausgaben druckt.
Erläuterung
Lassen Sie uns dies Schritt für Schritt durchgehen (ich werde versuchen, keine Mathematica-Kenntnisse anzunehmen). Sie müssen den Code von vorne nach hinten lesen. Der grundlegende Algorithmus durchläuft nur die Zeilen, in denen jede Funktion berechnet und die Ergebnisse gespeichert werden, auf die
f
nachfolgende Kacheln zugreifen sollen.Eingabeverarbeitung
Das ist das bisschen:
Dies teilt das Raster lediglich in eine verschachtelte Liste von Zeichen auf (beachten Sie, dass ich
h
einen Alias fürCharacter
irgendwo im Code definiert habe) und stellt dann eine Zeile und eine Spalte mit den Eingaben voran. Dies funktioniert, da1
und0
auch die Namen der Konstantenfunktionskacheln sind. Wenn Sie diese also auf die Kacheln setzen, hat dies den gleichen Effekt wie das manuelle Einspeisen der Eingaben. Da dies Funktionen sind, beziehen sie ihre Eingaben technisch von außerhalb des Gitters, aber da es sich um konstante Funktionen handelt, spielt dies keine Rolle. Die obere linke Ecke erhält ein,0
aber dies ist ziemlich willkürlich, da die Ergebnisse dieser Kachel niemals verwendet werden.Beachten Sie auch die Umsetzung. Das Hinzufügen von Spalten erfordert mehr Zeichen als das Hinzufügen von Zeilen. Deshalb transponiere ich das Raster, nachdem ich die oberste Zeile hinzugefügt habe. Dies bedeutet, dass oben / unten und links / rechts für den Hauptteil des Programms vertauscht werden, aber sie sind vollständig austauschbar, so dass es keine Rolle spielt. Ich muss nur sicherstellen, dass die Ergebnisse in der richtigen Reihenfolge zurückgegeben werden.
Das Gitter lösen
(Dieser Abschnitt ist etwas veraltet. Wird behoben, sobald ich wirklich sicher bin, dass ich mit dem Golfen fertig bin.)
Als nächstes durchlaufen wir
MapIndexed
die innere Ebene dieser verschachtelten Liste. Dies ruft die anonyme Funktion auf, die als erstes Argument für jedes Zeichen im Raster bereitgestellt wird, und gibt ihr auch eine Liste mit den aktuellen zwei Koordinaten. Das Gitter wird der Reihe nach durchlaufen, sodass wir jede Zelle auf der Grundlage der vorherigen Zellen sicher berechnen können.Wir verwenden die Variablen
r
(ight) undb
(ottom) als Nachschlagetabellen für die Ergebnisse jeder Zelle. Unsere anonyme Funktion enthält die aktuellen Koordinaten#2
, sodass wir die Eingaben für jede Zelle mit erhaltenBeachten Sie, dass in der ersten Zeile und Spalte auf undefinierte Werte von
r
und zugegriffen wirdb
. Mathematica hat damit kein wirkliches Problem und gibt Ihnen stattdessen nur Ihre Koordinaten zurück, aber wir verwerfen dieses Ergebnis trotzdem, da alle Kacheln in dieser Zeile / Spalte konstante Funktionen sind.Nun dieses Ding:
Ist eine Golf Form von
Dies ist wiederum eine Funktion, die angesichts der beiden Kacheleingaben eine Zuordnung zurückgibt (Sie würden es eine Hashmap oder eine Tabelle in anderen Sprachen nennen), die alle möglichen Kachelergebnisse für diese beiden Eingaben enthält. Um zu verstehen, wie alle Funktionen implementiert sind, müssen Sie wissen, dass auf das erste Argument einer solchen Funktion mit
#
und auf das zweite mit zugegriffen werden kann#2
. Außerdem erhalten##
Sie eine Folge beider Argumente, mit denen Sie die Argumente "splattern" können.0
: ist unkompliziert, wir geben nur eine Konstante zurück{0, 0}
und weisen diese auchz
für die zukünftige Verwendung zu (z. B. in der Raumkachel).1
: ist im Wesentlichen gerecht{1,1}
, aber mitz
diesem wird verkürzt1+z
. Wir speichern dies auch ino
, da es für alle Kacheln nützlich ist, bei denen beide Ausgaben identisch sind.+
: Hier nutzen wir die Sequenz.{##}
ist dasselbe wie{#,#2}
und leitet beide Eingänge unverändert weiter.\
: Wir tauschen die beiden Argumente aus{#2,#}
.U
: Jetzt können wir nutzeno
.o#2
Das heißt{1,1}*#2
, wir setzen einfach das oberste Argument in beide Ausgaben.)
In analoger Weise für das linke Argument:o#
.!
: Bitwise ist ärgerlich in Mathematica nicht, aber da wir immer nur haben0
und1
beide Eingänge aus, können wir einfach abziehen1
( und dadurch invertiert sie) und geben sie an:1-{##}
.&
: Dieser ist ziemlich geschickt. Zuerst bemerken wir, dass bitweise und für0
und1
mit der Multiplikation identisch ist. Darüber hinauso##
ist das gleiche wieo*#*#2
.|
: Auch hier verwenden wir eine äquivalente Funktion. Bitweise oder ist dasselbe wieMax
in diesem Fall, daher wenden wirMax
auf die Eingabeargumente an und multiplizieren das Ergebnis mit{1,1}
.^
: Das kürzeste, was ich für xor gefunden habe, ist, den Unterschied zu nehmen und ihn zu quadrieren (um die Positivität sicherzustellen), also haben wir eso(#-#2)^2
.Nachdem diese Funktion abgeschlossen ist und gibt den vollständigen Verband wir die aktuelle Zelle Zeichen verwenden , um das Element herausziehen wir daran interessiert sind , und speichern Sie es in
r
undb
. Beachten Sie, dass dies auch der Rückgabewert der in verwendeten anonymen Funktion istMapIndexed
, sodass mir die Zuordnung tatsächlich ein Raster aller Ergebnisse gibt.Ausgabeverarbeitung
MapIndexed
gibt ein 3D-Gitter zurück, wobei die erste Dimension der horizontalen Gitterkoordinate entspricht (die frühere Transposition beachten), die zweite Dimension der vertikalen Gitterkoordinate entspricht und die dritte angibt, ob wir eine untere oder eine linke Ausgabe haben. Beachten Sie, dass dies auch die Eingabezeile und -spalte enthält, die wir entfernen müssen. Also greifen wir mit auf die unterste Ausgabe der untersten Zeile zuund die rechte Ausgabe der letzten Spalte mit
Beachten Sie, dass dies
2;;
ein Bereich vom zweiten bis zum letzten Element ist.Zuletzt wenden wir
Print
beide an (wobei@@@
als syntaktischer Zucker für die zweite Ebene verwendet wirdApply
), wobei nur alle Argumente hintereinander ausgegeben werden (und da dies auf zwei separate Ausdrücke angewendet wird, wird zwischen bottom und eine neue Zeile eingefügt rechte Ausgabe).quelle
C
332309272270266259247225 BytesHier können Sie die Ergebnisse online anzeigen!
Dies definiert eine Funktion
void f(char*, char*, char*)
, die die Karte als erste Eingabe, dann die obere Eingabezeile und dann die linke Eingabezeile verwenden soll.Folgendes habe ich zum Testen verwendet:
Durch Eingabe des 2-Bit-Multiplikators von Sp3000:
Wir bekommen:
Mit dem halben Addierer von Sp3000 möchte ich einen Volladdierer sehen ...Einer von euch hat es geschafft! Ich denke nicht, dass das System als Programmiersprache für sich allein steht, aber es war sehr interessant. Dies scheint jedoch ein hervorragendes Ziel für Metagolf zu sein!Eine kurze Erklärung:
Hier ist der entschlüsselte, kommentierte Code:
Wir iterieren von
c
links nach rechts (dann von oben nach unten), schreiben diet
Eingaben jedes Mal neu und geben eine Ausgabe ganz rechts aus, die in diel
Zeichenfolge eingefügt wird . Wir können uns das so vorstellen, dass wir die obere Reihe von iterativc
durch1
's und0
' s ersetzen und die Bits verfolgen, die rechts herausgedrückt werden.Hier ist eine visuellere Sequenz, Zeile für Zeile:
Dies wird offensichtlich mit unterschiedlichen Symbolen und Größen komplizierter, aber die zentrale Idee gilt. Dies funktioniert nur, weil die Daten niemals auf- oder abfließen.
quelle
f
auf ändernf(c,t,l)char*c,*t,*l
(machen Sie sich keine Gedanken über den Rückgabetyp).f(c,t,l)char*c,*t,*l;
. Kompilieren Sie nicht im C11-Modus, da die implizite int-Regel, die das Löschen des Rückgabetyps ermöglicht, in dieser Revision gelöscht wurde.*l
? Es wird auf meinem Computer im C99-Modus kompiliert.Python 2, 316 Bytes
Diese Funktion erstellt 10 Kachel-Lambda-Funktionen, durchläuft dann das Raster und aktualisiert die Logikzustände. Die endgültigen vertikalen und horizontalen Logikzustände werden dann gedruckt.
Der ungolfed Code inklusive Tests:
Die
test.txt
Datei (einschließlich 2 anderer Tests von Sp3000):Die Testausgabe:
quelle
Python 2,
384338325 BytesErnsthaft CH, wenn dies noch kein Spielzeug ist, solltest du anfangen, einige Spielzeugfabriken anzurufen.
Golfer und viel weniger effizient, aber CarpetPython noch nicht eingeholt. Input wie
f("1111\n1\\+\\\n1+\\+\n1\\+\\","0101","1010")
Output ist ein Tupel von zwei Strings. Stellen Sie jedoch sicher, dass auf dem Board kein Zeilenumbruch vorhanden ist, der zu Problemen führen kann.Testprogramm
Sie können auch alle möglichen Fälle mit testen
test_all()
.Zusätzliche Testfälle
Halbaddierer
Hier ist ein Halbaddierer, der die oberen linken Bits addiert und Folgendes ausgibt
<input bit> <carry> <sum>
:Tests:
Die Ausgabe sollte identisch sein, auch wenn das zweite / dritte Bit der Eingänge geändert wird.
Rechte Shifttaste
Vorausgesetzt
abc / def
, dies gibt Folgendes ausfab / cde
:Tests:
3-Bit-Sortierer
Sortiert die ersten drei Bits von oben in die letzten drei Bits von unten. Richtige Ausgabe ist Junk.
Tests:
2 Bit mal 2 Bit Multiplikator
Nimmt das 1./2. Bit von oben als erste Zahl und das 3./4. Bit von oben als zweite Zahl. Ausgabe bis zu den letzten vier Bits von unten. Richtige Ausgabe ist Junk.
Bearbeiten: Golfed aus einer Spalte und zwei Zeilen.
Tests:
quelle
R
524517Wahrscheinlich viel Platz, um dies im Moment zu reduzieren, aber das war wirklich interessant zu tun. Es gibt zwei Funktionen. Funktion d ist der Arbeiter und f ist der Vergleicher.
Die Funktion d wird mit 3 Strings aufgerufen, Gates, Top und Left. Die Gates werden in eine durch die Breite bestimmte Matrix gelegt.
Ein bisschen formatiert
Einige Tests
quelle