Es war eine lustige Herausforderung, zwischen den Weihnachtsfeiern hin und her zu arbeiten. Vielen Dank für die Veröffentlichung! Das Golfen war interessant, da die Spezifikation viele Ausnahmen und Sonderfälle enthält, für die viele Bedingungen erforderlich waren. Auch wenn ich dieses Mal nicht in und von Dezimalstellen konvertieren musste, benötigte ich eine Art "Max" -Funktion, um die größte Anzahl von Ziffern in jeder Zahl und den größten Wert der Ziffern an jeder Stelle zu bestimmen.
Die erste Version davon war 4844 Bytes, nur um Ihnen eine Vorstellung davon zu geben, wie viel ich das gespielt habe.
Das Programm erwartet die Eingabe als durch Kommas getrennte Liste von Ganzzahlen. Keine Leerzeichen oder Zeilenumbrüche. Die Verwendung dieser führt zu undefiniertem Verhalten.
"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "
Erläuterung
Ich werde Sie durch die Funktionsweise des Programms führen, indem ich Ihnen zeige, wie es die spezifischen Eingaben verarbeitet 202,100,1
.
Zu Beginn konstruieren wir einige Werte, die wir später benötigen werden - hauptsächlich die ASCII-Codes der Zeichen, die wir ausgeben werden.
Wie Sie sehen können '8'
und '.'
bereits verfügbar sind. '|'
ist jedoch 124, nicht 14. Wir verwenden eine while-Schleife, um den doppelten temporären Wert in Slot # 1 zu addieren und 124 zu erhalten (das ist 14 + 55 × 2, da die while-Schleife für 56−1 = 55 läuft Iterationen). Dies spart einige Bytes, da große Integer-Literale wie 124 sehr lang sind. Im folgenden Diagramm zeige ich die Position jeder vom Programm verwendeten Variablen.
Als nächstes wollen wir alle Zeichen eingeben und sie ab Zelle 12 auf dem Band speichern ( p ist der laufende Zeiger dafür). Gleichzeitig möchten wir wissen, wie lang die längste Nummer ist (wie viele Ziffern). Um dies zu erreichen, führen wir eine laufende Summe in unary beginnend bei Zelle # −1 nach links (wir verwenden q als laufenden Zeiger). Nach der ersten eingegebenen Nummer ( 202
) sieht das Band nun so aus:
Sie werden bemerkt haben, dass die Zahlen um 4 abweichen. Nun, wenn wir sie zum ersten Mal eingeben, handelt es sich um ihre ASCII-Werte, also sind sie um 48 "ausgeschaltet" und das Komma ist 44. Für jedes Zeichen kopieren wir die 46 von '.'
in r und subtrahieren es dann mit einer while-Schleife (die 45 subtrahiert) und dann addieren wir 1. Wir machen das so, dass das Komma (unser Trennzeichen) 0 ist, so dass wir eine Bedingung verwenden können, um es zu erkennen.
Außerdem haben Sie bemerkt, dass wir die Zelle Nr. 11 auf 0 belassen. Dies ist erforderlich, um die Grenze der ersten Zahl zu erkennen.
Das nächste Zeichen ist ein Komma, also speichern wir eine 0 in # 15, aber dieses Mal rücken wir natürlich q nicht vor . Stattdessen setzen wir q auf 0 zurück und “überschreiben” die 1, die wir bereits platziert haben.
Nachdem alle verbleibenden Zeichen verarbeitet wurden, erhalten wir Folgendes:
Wie Sie sehen, geben die von q geschriebenen Einsen (in unary) die Länge der längsten Zahl an.
Wir verwenden jetzt eine while-Schleife, um q ganz nach links zu verschieben und platzieren dann einen anderen Zeiger, den ich r2 nennen werde . Der Zweck von r2 wird später klar.
Lassen Sie mich an dieser Stelle die Terminologie klarstellen, die ich in dieser gesamten Beschreibung verwenden werde.
- Mit Nummer meine ich eine der Eingabenummern, die durch Kommas getrennt sind. In unserem Beispiel sind das 202, 100 und 1.
- Mit Ziffer meine ich eine einzelne Ziffer in einer bestimmten der Zahlen. Die erste Nummer besteht aus 3 Ziffern.
- Mit Ort meine ich den einen Ort, den Zehnerort, den Hunderterort usw. Wenn ich also „die Ziffern am aktuellen Ort“ sage und der aktuelle Ort derjenige ist, sind diese Ziffern darin 2, 0 und 1 Bestellung.
Nun zurück zu unserer regulären Programmierung. Der gesamte Rest des Programms ist eine große Schleife, die q vorwärts bewegt , bis sie die Zelle # 0 erreicht. Jede der Zellen auf dem Weg stellt einen Ort dar, wobei sich der eine ganz rechts befindet und q am signifikantesten beginnt. In unserem Beispiel ist das die Hunderterstelle.
Wir fahren fort, indem wir die q- Punkte der Zelle inkrementieren (d. H. * Q ).
Wir sind jetzt auf "Stufe 2" für den Hundertplatz. In dieser Phase werden wir herausfinden, welche der hundert Stellen die größte unter allen Stellen ist. Wir verwenden dafür denselben unären Zähltrick, außer dass der Zeiger dieses Mal r heißt und der Zeiger r2 seine Startposition markiert, auf die wir ihn jedes Mal zurücksetzen müssen, wenn wir zur nächsten Zahl übergehen.
Beginnen wir mit der ersten Zahl. Wir beginnen mit der Einstellung von p auf 11 (die fest codierte Startposition aller Zahlen). Wir benutzen dann eine while-Schleife, um das Ende der Zahl zu finden und setzen dort p2 , um die Position zu markieren. Gleichzeitig setzen wir q2 auf 0:
Lassen Sie sich nicht von der Tatsache ablenken, dass q2 in die Vars zeigt. Wir haben dort kein Auffüllen einer leeren Zelle, weil wir die Zelle 0 erkennen können, nur weil sie die Nummer Null ist.
Als nächstes gehen wir die aktuelle Zahl durch, indem wir p und q2 zusammen dekrementieren, bis * p Null ist. An jeder Stelle gibt der Wert von * q2 an , was zu tun ist. 1 bedeutet „nichts tun“, also machen wir weiter. Schließlich begegnen wir der 2 in Zelle # -3. Jedes Mal, wenn * q2 ungleich 1 ist, ist q2 immer gleich q .
Wie ich bereits sagte, ist Stufe 2 "die größte Ziffer an dieser Stelle bestimmen". Also setzen wir r auf r2 , dekrementieren * p mit einer while-Schleife, bewegen r nach links und füllen das Band mit 1s und verwenden dann eine andere while-Schleife, um r zurück nach rechts zu bewegen und * p erneut zu erhöhen, um den Wert wiederherzustellen. Denken Sie daran, dass jede while-Schleife eine Iteration kürzer als der Wert ist, für den sie verwendet wird. Aus diesem Grund ist die Anzahl der geschriebenen Einsen um 3 höher (anstatt um 4 höher) als der Ziffernwert, und der in * p zurückgespeicherte Endwert ist um 2 höher. Dies hat also effektiv * p um 2 dekrementiert .
Danach setzen wir p auf den Wert von p2 und machen das alles noch einmal. Setzen Sie q2 zum zweiten Mal auf 0, suchen Sie das Ende der Zahl, indem Sie p nach rechts bewegen , und gehen Sie dann die Ziffern dieser Zahl durch, indem Sie p und q2 zusammen dekrementieren . Wieder werden wir in Zelle # −3 auf die 2 stoßen und so viele Einsen von * r schreiben, wie noch vorhanden sind .
Bei der dritten Zahl machen wir nichts, weil sie keine Hunderterstelle hat (also q2 nie q erreicht ), aber das ist in Ordnung, weil das die Berechnung des maximalen Ziffernwerts nicht beeinflusst.
Wir setzen auch die Zelle * (r - 4) , die ich hier mit einem unbeschrifteten Pfeil markiert habe, auf 1 (obwohl sie bereits auf 1 steht). Ich werde dir noch nicht sagen warum, aber vielleicht hast du es schon erraten?
Das nächste Inkrement von * q führt uns zu Stufe 3, in der „die maximale Ziffer von allen Ziffern an der aktuellen Stelle subtrahiert“ wird. Wie zuvor setzen wir p auf 11 und q2 auf 0 zurück und gehen dann alle Zahlen durch, wie wir es in der vorherigen Stufe getan haben; außer diesmal * q = 3 statt 2. Jedes Mal, wenn q2 auf q trifft und p an einer Hunderterstelle liegt, dekrementieren wir * p mit einer while-Schleife so oft, wie der Block von * r2 (5) noch Einsen enthält in unserem Beispiel) mit rals laufender Zeiger. Wir dekrementieren es tatsächlich noch einmal, damit die größte Ziffer bei -2 endet, aus einem Grund, der später noch klar wird:
Nachdem wir alle Zahlen verarbeitet haben, sind wir nun am Ende von Stufe 3. Hier führen wir zwei singuläre Dinge durch.
- Zuerst subtrahieren wir auch die Größe des r- Blocks (plus 1) von * q , verwenden aber den r2- Zeiger, der ihn links belässt. * q wird auf diese Weise negativ. In unserem Fall hat der r- Block fünf Einsen, also wird * q −3.
- Zweitens haben wir eine Variable out auf einen Wert ungleich Null , um anzuzeigen , dass man nun die Ausgangsstufe eintreten. (Technisch gesehen zeigt die Tatsache, dass * q negativ ist, bereits die Ausgangsstufe an, aber dies ist zu schwierig zu überprüfen, daher die zusätzliche Variable.)
Sie verstehen jetzt, dass wir die Zahlen durchgehen, die aktuelle Position (angegeben durch den Wert * q ungleich 1 ) in jeder Zahl finden und abhängig vom Wert * q etwas unternehmen . Wir sehen, dass * q zuerst auf 2 inkrementiert wird (= Maximalziffernwert berechnen), dann auf 3 (Maximalziffernwert von jeder Ziffer an dieser Stelle subtrahieren) und dann von dieser subtrahieren, um sie negativ zu machen. Von dort steigt es weiter an, bis es 1 erreicht, wodurch der Wert wiederhergestellt wird, der bedeutet, dass Sie nichts tun. An diesem Punkt gehen wir weiter zum nächsten Ort.
Wenn nun * q negativ ist, geben wir aus. * q hat genau den richtigen Wert, sodass die richtige Anzahl von Zeichenzeilen ausgegeben wird, bevor 1 erreicht wird. Wenn die größte Ziffer 2 ist, müssen 3 Zeilen ausgegeben werden. Mal sehen, was bei jedem Wert von * q passiert :
- * q = −2:
- Für die erste Zahl ist * p −2, was anzeigt, dass wir einen
'.'
(Punkt) oder einen ':'
(Doppelpunkt) ausgeben müssen . Wir entscheiden, was durch Betrachten von q : Wenn es −1 ist, sind wir an der richtigen Stelle, also geben Sie a aus ':'
(was wir als '8'
+2 berechnen ), andernfalls a '.'
.
- Für die zweite Zahl ist * p -3. Alles, was nicht −2 ist, bedeutet, dass wir eine
'|'
(Pipe) ausgeben und dann den Wert erhöhen . Auf diese Weise erreicht es −2 an der richtigen Stelle und wir geben '.'
s / ':'
s für den Rest dieser Ziffer aus.
- In jedem Fall setzen wir auch eine Variable pd auf 0, bevor wir die Zahl verarbeiten, und setzen pd (= "gedruckt") auf einen Wert ungleich Null, um anzuzeigen, dass wir ein Zeichen gedruckt haben.
- Bei der dritten Nummer findet keine Verarbeitung statt, da die dritte Nummer keinen Platz für Hunderte hat. In diesem Fall ist pd nach der Verarbeitung der Zahl immer noch 0, was darauf hinweist, dass wir immer noch a ausgeben müssen
'|'
(aber nur, wenn out nicht Null ist, da wir uns sonst immer noch in Stufe 2 oder 3 befinden).
- Wenn out nicht Null ist, geben Sie nach der Verarbeitung aller Zahlen eine neue Zeile aus. Beachten Sie, dass wir die Variable out benötigen , damit wir die Newline in Stufe 2 oder 3 nicht ausgeben.
- * q = −1: Wie zuvor, mit der Ausnahme, dass * p für beide ersten beiden Zahlen −2 ist, sodass beide a ausgeben
'.'
(und der dritte a'|'
wie zuvorausgeben).
- * q = 0: Wenn * q 0 ist, bedeutet dies, dass Sie nichts tun, wenn Sie an der richtigen Stelle sind, andernfalls eine Zeile mit
'|'
s unabhängig von * p ausgeben. Auf diese Weise erhalten wir den Abstand zwischen den Ziffern.
Jetzt erhöhen wir q , um zur nächsten Stelle, der Zehnerstelle, zu gelangen, und erhöhen dort * q . Zu Beginn von Stufe 2 sieht das Band folgendermaßen aus:
Dann führen wir Stufe 2 wie zuvor durch. Denken Sie daran, dass dies effektiv 2 von jeder Ziffer an dieser Stelle subtrahiert und außerdem eine unäre Zahl von * r2 übrig lässt , die die maximale Ziffer angibt. Wir lassen die vorherige unäre Nummer in Ruhe und verlängern das Band einfach weiter nach links. Es würde nur unnötigen zusätzlichen Code kosten, um "aufzuräumen". Wenn wir fertig sind und * q erhöhen, lautet das Band zu Beginn von Stufe 3 wie folgt:
Eigentlich ist das eine Lüge. Weißt du noch, wo ich sagte, wir hätten * (r - 4) auf 1 gesetzt, und ich habe dir nicht gesagt, warum? Jetzt sage ich dir warum. Dies gilt für Fälle wie diesen, in denen die größte Ziffer tatsächlich 0 ist, was bedeutet, dass alle Ziffern an dieser Stelle 0 sind. Wenn Sie * (r - 4) , angezeigt durch den nicht gekennzeichneten Pfeil oben, auf 1 setzen, wird die unäre Zahl um 1 erweitert. aber nur in diesem speziellen Fall. Auf diese Weise tun wir so, als ob die größte Ziffer 1 wäre, was bedeutet, dass wir eine zusätzliche Zeile ausgeben.
Nach Stufe 3 (maximale Stelle von allen Stellen an der aktuellen Stelle abziehen), einschließlich des zusätzlichen Schritts, der * q negativ macht, sieht das Band so aus. Beim letzten Mal wurde die größte Ziffer im * p- Block durch –2 dargestellt , aber diesmal sind sie alle –3, weil sie eigentlich alle Nullen sind, aber wir tun so, als wäre die maximale Ziffer eine 1.
Nun wollen wir sehen, was passiert, wenn * q auf 1 zugeht :
- Wenn * q = −1, sind die * p- Werte alle −3, was bedeutet, dass wir
'|'
s ausgeben und inkrementieren.
- Wenn * q = 0, geben wir aus,
'|'
weil wir dies immer tun, wenn * q = 0, unabhängig von * p .
So erhalten wir zwei Rohrreihen.
Schließlich bewegen wir uns * q an die eigene Stelle. Dies wird interessant, weil wir ':'
s ausgeben müssen, wenn die tatsächliche Ziffer nicht 1 ist, sondern '8'
1. Mal sehen, wie das Programm abläuft. Zuerst erhöhen wir * q , um Stufe 2 einzuleiten:
Nach Stufe 2 („Maximaler Ziffernwert berechnen“) bleibt Folgendes übrig:
Nach Stufe 3 ("Maximaler Stellenwert von allen Stellen an der aktuellen Stelle subtrahieren") sieht das Band folgendermaßen aus:
Gehen wir nun nacheinander jede Iteration von * q durch:
- * q = −2:
- Erste Zahl: bereits bei −2, also gib a aus
':'
(anstatt a, '.'
weil q = −1).
- Zweite Zahl: bei -4, also a ausgeben
'|'
und inkrementieren.
- Dritte Zahl: bei -3, also gib a aus
'|'
. Diesmal wird jedoch ein Sonderfall ausgelöst, anstatt ihn zu erhöhen. Nur wenn wir den letzten Platz ausgeben ( q = −1) und dafür in der vorletzten Zeile stehen ( * q = −2) und die Ziffer tatsächlich eine 1 ist ( * p = −3) , dann , anstatt sie auf -2 erhöht wird , setzen wir es auf -1. Mit anderen Worten, wir verwenden −1 als speziellen Wert, um anzuzeigen, dass wir in der nächsten Iteration '8'
statt ausgeben müssen ':'
.
- * q = −1:
- Erste Zahl: bereits bei −2, also gib a aus
':'
.
- Zweite Zahl: bei -3, also gib a aus
'|'
. Die Sonderbedingung wird nicht ausgelöst, weil * q nicht mehr −2 ist. Daher inkrementieren.
- Dritte Zahl: bei -1, also Ausgabe
'8'
.
- * q = 0: Normalerweise würden wir hier die Auffüllzeile von
'|'
sausgeben, aber in dem speziellen Fall, in dem wir uns an der einen Stelle befinden ( q = −1), überspringen wir diese.
Danach wird q auf 0 erhöht und die große while-Schleife endet.
Jetzt wissen Sie, wie eine Eingabe 202,100,1
funktioniert. Es gibt jedoch einen weiteren Sonderfall, den wir noch nicht behandelt haben. Sie erinnern sich vielleicht, dass wir während der Verarbeitung des letzten Platzes, als * p −3 war, diesen Wert auf −1 gesetzt haben 1
(anstatt ihn auf −2 zu erhöhen), damit bei der nächsten Iteration '8'
stattdessen ein ausgegeben wird. Dies funktioniert nur, weil wir eine Iteration haben, in der * p −3 ist, und wir entscheiden, ob wir es inkrementieren oder auf −1 setzen. Wir nicht haben eine solche Iteration , wenn alle der Ziffern in der Einerstelle 0 oder 1. In einem solchen Fall werden alle * p - Werte für die 1s würde beginnen bei -2; Es gibt keine Möglichkeit, sich zu entscheiden, es auf -1 zu setzenanstatt es von -3 zu erhöhen . Aus diesem Grund gibt es innerhalb von Stufe 3 eine weitere Sondergehäusebedingung ("maximale Ziffer von jeder Ziffer an der aktuellen Stelle subtrahieren"). Ich habe behauptet, dass wir nach dem Subtrahieren des maximalen Ziffernwerts von jeder Ziffer (an diesem Punkt liegt die maximale Ziffer bei -1) nur noch einmal dekrementieren, aber tatsächlich gibt es eine Bedingung dafür, die wie folgt lautet:
Wenn die Ziffer, die wir betrachten, gleich der maximalen Ziffer an dieser Stelle ist ( * p = −1) und diese Stelle die Einerstelle ist ( q = −1) und die maximale Ziffer ist 1 ( * (r +) 5) = 0, dh der unäre Block ganz links ist nur 5 Zellen lang), nur dann belassen wir * p bei -1, um anzuzeigen, dass die einzige Iteration der Ausgabe ein ausgeben muss '8'
. In allen anderen Fällen verringern wir es noch einmal.
Getan. Frohes neues Jahr!
Edit 1 (3183 → 3001): Frohes Neues Jahr beim Golfen! Ich habe es geschafft, die Variablen p2 und r2 komplett loszuwerden ! p rast nun hin und her, um den Anfang und das Ende von Zahlen zu finden, aber der Code scheint kürzer zu sein. Ich habe versucht, auch Q2 loszuwerden , aber ich konnte den Code auf diese Weise nicht kürzer machen.
Ich habe auch ein paar weitere Stellen gefunden, an denen ich typische Unreadable-Golftricks anwenden kann, beispielsweise den letzten Wert einer while-Schleife erneut verwenden. Um Ihnen ein Beispiel zu geben, anstatt
while *(++p) { 1 } // just increment p until *p is 0; the 1 is a noop
if (pd) { x } else { y } // where pd is a variable
Ich kann das '""""
(mache das erste, dann das zweite) und das '"""
(konstante 1) retten , indem ich es auf eine Art schreibe, die der gleichen ist
if (while *(++p) { pd }) { x } else { y }
Dies funktioniert natürlich nur, wenn ich weiß, dass die while-Schleife für mindestens eine Iteration ausgeführt wird, aber wenn dies der Fall ist, ist ihr Rückgabewert pd, sodass ich das als Bedingung für das if verwenden kann.