** Brainfuck Interpreter Contest ** [abgeschlossen]
-
µ, das vierfache =0 bei dir tut mir richtig weh. Als Membervariablen wären das auf einen Schlag 7 Zeichen weniger. Ansonsten: Das Muster
(j -= XXX) * j == 1
gefällt mir. Da wär ich wohl auch nicht drauf gekommen.
-
Bashar ich beiße mir gerade selbst in den Arsch dafür. 221 wären es sonst.
-
@Bashar:
Wobei ich das "Deaktivieren" von Opcodes das unsere beiden Codes gemeinsam haben (zum Sparen des 2. "if" das in 1-Schleifen-Lösungen sonst nötig wäre) auch sehr kuhl finde
-
Naja, 221 geht ja noch.
Blöd wäre wenn du auf 219 oder gar 217 gekommen wärst damit
-
Interessant: Niemand konnte 65536 bzw 1<<16 oder eine größere Zahl mit weniger als 5 Zeichen darstellen. Ich vermute irgendeine geschickte Lösung mit Überlauf.... habe sie aber nicht gefunden.
-
Bashar schrieb:
Ansonsten: Das Muster
(j -= XXX) * j == 1
gefällt mir. Da wär ich wohl auch nicht drauf gekommen.Spielt ein kleines wenig "Glück" eine Rolle. Bei hohen char-Werten kommt es zum Überlauf. Aber es gibt keine Zahl in UTF-16 die in diesen Fällen ebenfalls j*j==1 ergeben würde. Sonst hätte ich auf long umsteigen müssen. Bei einer Variante dieses Schemas hatte ich nämlich ein solches Problem.
-
hustbaer schrieb:
Wobei ich das "Deaktivieren" von Opcodes das unsere beiden Codes gemeinsam haben (zum Sparen des 2. "if" das in 1-Schleifen-Lösungen sonst nötig wäre) auch sehr kuhl finde
Ich hätte mir einen (sinnlosen) Rückgabewert bei der S.W() Funktion gewünscht. Dieses Monster war sonst nirgends unterzubringen. Imho ist nur der Upadate-Teil der For-Schleife in der Lage, Ausdrücke ohne Rückgabewert zu verarbeiten.
-
Übrigens ist mir bei diesem Contest aufgefallen, dass C# keine oktalen Literale kennt. Es war eine sehr frühe chancenlose Version mit >400 Zeichen, aber da hätte ich das erste mal seit ... weiß ich nicht ... überhaupt Oktalzahlen gebraucht, und C# hat die einfach nicht.
010 == 10 in C#.
Keine Warnung.
-
Mit long hättest du aber Probleme, da C# keine implizite Konvertierung long -> int erlaubt.
D.h. beim Aufruf der Write Funktion wäre dann ein "(int)" Cast fällig gewesen = +5 Zeichen.Ich hatte mir das mit long nämlich auch schon überlegt, da ich eben erst "i * i < 2" stehen hatte. Dummerweise geht sich das aber nicht mit allen möglichen UTF-16 Zeichen aus, bei 46xxx (sqrt(1 << 31)) ist Schluss - da wird die Zahl nämlich auf einmal negativ.
-
µ schrieb:
Ich hätte mir einen (sinnlosen) Rückgabewert bei der S.W() Funktion gewünscht. Dieses Monster war sonst nirgends unterzubringen.
Ach, was ich mir nicht alles gewünscht habe während des Contest
Die Regel dass sämtliche Kommentare ignoriert werden müssen war z.B auch halbwegs "lästig" - ASCII 0-127 hätte da einiges erleichtert.
-
@Bashar
Zu meiner Schande muss ich gestehen, dass ich bisher ebenfalls Oktal-Literale wie in C++ vermutet habe. Noch nie benötigt bisher.@hustbaer
Stimmt. Den Cast habe ich nicht bedacht.Die Kommentare habe ich nicht als lästig empfunden. Spontan weiß ich nicht, was ASCII 0-127 für erhebliche vorteile bringen würde. Habe nie darüber nachgedacht.
EDIT: Und ja, wie gesagt. Deinen Code zerpflücke ich morgen. Ist mir heute Abend zu viel
-
Dieser Thread ist bei Google auf Position 7 bei dem Suchbegriff "Brainfuck Interpreter".
Wir hinterlassen der Welt nichts Gutes
-
Bei mir is der auf Platz 30 (google.com) bzw. Platz 40 (google.de)...
(Liegt vielleicht daran dass ich als "Hauptsprache" in meinem Browser Englisch eingestellt hab...)
-
µ schrieb:
Interessant: Niemand konnte 65536 bzw 1<<16 oder eine größere Zahl mit weniger als 5 Zeichen darstellen. Ich vermute irgendeine geschickte Lösung mit Überlauf.... habe sie aber nicht gefunden.
~0u ist mir eingefallen, aber das ist dann wieder zuviel.
-
~0u !
ich sollte mir mal eine Tabelle mit Literalen einprägen.
(google liefert regional sehr unterschiedliche Suchergebnisse. Kein Wunder bei einer Million Servern)
-
class I_Nice { int[] m = new int[1 << 16]; int n = 0, z, c; public void R(S s, int p = -1, int r = 2) { while ((z = ++p) < s.P.Length && (c = s.P[p] - 40) != 53) { if (c == 51) if (m[n] != 0) R(s, p--); else { R(s, p, 0); p = z; } if (r > 0) { m[c == 20 || c == 22 ? n -= 21 - c : n] += c == 3 || c == 5 ? 4 - c : 0; if (c == 6) s.W(m[n]); if (c == 4) m[n] = s.R(); } } } }
m = Speicher
n = Position im Speicher m
z = "Rückgabewert" bei rekursiven Aufruf
p = Stelle des aktuellen Zeichen
c = Aktuelles Zeichen
r [Funktionsparameter] = Code ausführen oder "Suchlauf" (Flag)Zunächst werden alle Zeichen als Zahlen abgebildet, da 'x' länger ist als eine zweistellige Zahl. Um einige Zeichen noch kürzer darstellen zu können, wird 40 subtrahiert.
So ist das Zeichen [ nun 6 und ] ist 4.Da diese Zeichen fast nebeneinander liegen kann man durch Subtraktion der Paare herausfinden, ob man addieren oder subtrahieren muss.
Dieser Trick wird hier gleich 2x angewendet:
m[c == 20 || c == 22 ? n -= 21 - c : n] += c == 3 || c == 5 ? 4 - c : 0;
Ansonsten ist das Programm nichts besonderes, aber das hatte ich ja bereits am Anfang erwähnt
-
Wie ihr die []-Behandlung so kurz hinbekommen habt ist genial. Ich hatte da verschachtelte Schleifen, auch wenns sowieso nicht funktioniert hat.
-
Ich möchte mich an der Stelle noch mal bei hustbaer bedanken, der sich hier wirklich reingehängt hat, ein tolles Testsystem hochgezogen hat und die ganze Geschichte betreute!
-
GPC schrieb:
Ich möchte mich an der Stelle noch mal bei hustbaer bedanken, der sich hier wirklich reingehängt hat, ein tolles Testsystem hochgezogen hat und die ganze Geschichte betreute!
Dem schließe ich mich an. Vielen Dank dafür.
-
µ schrieb:
Interessant: Niemand konnte 65536 bzw 1<<16 oder eine größere Zahl mit weniger als 5 Zeichen darstellen. Ich vermute irgendeine geschickte Lösung mit Überlauf.... habe sie aber nicht gefunden.
»
~0u
«?