Ihre Herausforderung besteht darin, eine Liste von Wörtern über mehrere Zeilen zu formatieren, die nicht länger als eine bestimmte Anzahl von Zeichen sind, sodass jede Zeile so viele Wörter wie möglich enthält und keine Wörter unnötig abgeschnitten werden.
Eingang
Die Eingabe besteht aus einer durch Leerzeichen getrennten Liste von Wörtern und einer Zahl von mindestens 4.
Ausgabe
Die Ausgabe sollte aus den in Zeilen gruppierten Eingabewörtern bestehen, sodass keine der Zeilen mehr Zeichen als die Eingabenummer enthält. Die Wörter sollten in der Reihenfolge ausgegeben werden, in der sie eingegeben wurden. Die Wörter sollten durch ein Komma und dann ein Leerzeichen getrennt werden, außer am Ende jeder Zeile, wo das Leerzeichen nicht benötigt wird. Wenn ein Wort zu lang ist, um in eine Zeile zu passen, sollte es so wenig wie möglich abgeschnitten werden, während die anderen Regeln befolgt werden. Am Ende sollte ein "..." eingefügt werden.
Testfälle
Input:
foo bar baz qux 12
Output:
foo, bar,
baz, qux
Input:
foo bar baz qux 5
Output:
foo,
bar,
baz,
qux
Input:
strength dexterity constitution intelligence wisdom charisma 10
Output:
strength,
dexterity,
consti...,
intell...,
wisdom,
charisma
Input:
quas wex exort 4
Output:
...,
wex,
e...
Antworten:
Nicht lesbar , 2559 Bytes
Diese Herausforderung eignet sich unheimlich für Unreadable.
Die erste Version davon war 3379 Bytes, nur um Ihnen eine Vorstellung davon zu geben, wie viel ich das gespielt habe.
Das Programm akzeptiert die Eingabe genau wie in der Challenge beschrieben: Eine durch Leerzeichen getrennte Liste von Wörtern (die auch Ziffern und Satzzeichen enthalten kann), gefolgt von einem Leerzeichen und einer Ganzzahl von mindestens 4 (niedrigere Zahlen erzeugen Endlosschleifen). .
Erläuterung
Ich werde Ihnen zeigen, wie das Programm die Eingaben verarbeitet
thyme horseradish peppermint 10
. Die erwartete Ausgabe istthyme,\nhorser...,\npeppermint
.Zuerst beginnen wir in Zelle 7 und lesen die gesamte Eingabe, subtrahieren jedoch 32 von jedem Zeichen, sodass Leerzeichen zu Nullen werden.
Aus offensichtlichen Gründen bleibt der laufende Zeiger (benannt) erhalten p bezeichnet , in Zelle # 0 gespeichert) am Ende. Wir verwenden eine while-Schleife, um die letzte Lücke zu finden, die der Anfang der Zahl ist, die die Breite der Ausgabe definiert (Zelle 36 in diesem Beispiel).
Wir wollen nun die Zahl dekodieren (dh von dezimal konvertieren). Das Endergebnis wird in beiden Zellen t sein und r sein . Wir verlassen uns darauf, dass sie bei Null beginnen.
Führen Sie für jede Ziffer in der Nummer die folgenden Schritte aus:
'0'
, die'9'
die ASCII-Codes 48–57 haben, sind nach der vorherigen Subtraktion von 32 16–25, also addieren wir 15–24 zu t , was mit −15 abbricht wir setzen es auf früher. Es ist auch wichtig, dass die Zellen, in denen sich die Ziffern befanden, auf Null gesetzt werden, damit der nachfolgende Code das Ende der Wortliste erkennen kann.Schließlich verwenden wir eine andere einfache while-Schleife (die t als Zähler dekrementiert ), um die gerade berechnete Zahl in eine unäre Zahl umzuwandeln. Wir speichern einen String von 1s, der von Zelle # 0 nach links geht. Dies beruht auf der Tatsache, dass Zelle 1, unser laufender Zeiger für dieses ( q ), bei 0 beginnt. Wir erhalten eine 1 weniger, weil while-Schleifen in Unreadable wie folgt lauten:
Danach brauchen wir den Wert in r nicht mehr , also verwenden wir diese Zelle für etwas anderes. Wir setzen die Zeiger p und q zurück und initialisieren einige Zellen mit ASCII-Zeichencodes, die wir später benötigen. Ich habe auch c und s beschriftet, die wir später verwenden werden, und wir werden uns auf die Tatsache verlassen, dass s bei Null beginnt:
Hey, warte eine Minute. Warum ist Zelle 0 rot gefärbt? Erinnerst du dich, dass wir eine 1 zu wenig ausgegeben haben? Der Trick ist, dass wir die Zelle # 0 als „Erweiterung“ verwenden, um dies zu korrigieren. Dies funktioniert, weil wir wissen, dass p niemals 0 sein wird. Auf diese Weise ist der rote Block jetzt 10 Zellen breit, genau die Zahl, die wir wollen. Außerdem werden 9 Zeichen gespeichert, um q anstelle von 0 mit 1 zu initialisieren .
Jetzt geben wir die while-Schleife ein, die die Wörter durchläuft und sie alle ausgibt.
Schritt 1: Finden Sie heraus, ob das nächste Wort in die aktuelle Zeile passt. Wir tun dies, indem wir p einfach mit einer while-Schleife nach rechts und q nach links bewegen , bis p die nächste Lücke erreicht:
Nun das p auf dem ist rechts des Wortes, können wir prüfen , ob dies das letzte Wort in der Liste ist durch Prüfen , ob * (p + 1) gleich Null ist. Wir speichern diesen Wert (der in unserem Beispiel 72 ist, weil es das "h" von "Meerrettich" minus 32 ist) auch in c, weil wir ihn später wieder brauchen werden. In diesem Fall ist es nicht Null, daher müssen wir ein Komma zusammen mit dem Wort ausgeben, damit das Wort ein Zeichen länger ist. Berücksichtigen Sie dies, indem Sie q noch einmal verringern . Verwenden Sie abschließend eine andere while-Schleife, um p an den Wortanfang zurückzusetzen.
Wir wissen jetzt, dass das Wort in die aktuelle Zeile passt, weil q auf einen Wert ungleich Null zeigt. Wir müssen also nur Folgendes tun:
Bisherige Ausgabe:
thyme,
Dann beginnt die nächste Iteration der großen Schleife. Wie zuvor prüfen wir, ob das nächste Wort in den Rest der Zeile passt, indem wir q dekrementieren, während wir das Wort von links nach rechts durchlaufen. Beachten Sie, dass q der vorherigen Iteration immer noch −5 ist und protokolliert, wie viele Zeichen in der aktuellen Zeile bereits gedruckt wurden. Nach dem Zählen der Zeichen in „Meerrettich“ plus eins für das Komma plus eins, da s nicht Null ist, was darauf hinweist, dass wir auch ein Leerzeichen ausgeben müssen, hat q das Ende des Blocks von 1s überschritten:
Jetzt zeigt q auf eine Null-Zelle, was bedeutet, dass „Meerrettich“ nicht in die aktuelle Zeile passt. Was wir jetzt tun, hängt davon ab, ob s nicht Null ist. In unserem Fall bedeutet dies, dass wir in die nächste Zeile springen müssen. Alles was wir dafür tun müssen ist:
Bisherige Ausgabe:
thyme,\n
Bei der nächsten Iteration befindet sich p an derselben Stelle wie zuvor, sodass wir uns das gleiche Wort noch einmal ansehen werden. Wie zuvor zählen wir die Zeichen in „Meerrettich“ und setzen c erneut auf 80, wenn wir feststellen, dass ein anderes Wort nach diesem steht. Verringern Sie q um das Komma und spulen Sie p zum Wortanfang zurück:
Wie in der vorherigen Iteration finden wir, dass „Meerrettich“ immer noch nicht passt, weil q in einer Zelle endet, die Null ist. Diesmal jedoch s jedoch Null, was bedeutet, dass wir etwas anderes als beim letzten Mal tun. Wir müssen einen Teil des Wortes, drei Punkte und ein Komma ausgeben. Unsere Breite ist 10, also müssen wir 6 Zeichen des Wortes ausgeben. Mal sehen, wo wir landen, wenn wir:
Das Band sieht jetzt so aus:
Ich habe hier eine Spanne von 6 Zellen markiert. Wie Sie sehen, müssen wir Zeichen ausgeben, bis q = −1 ist. Dies ist sehr Code-effizient zu überprüfen (im Grunde genommen
while ((++q)+1) { ... }
). So:print(print(print('.')))
) . Wir nehmen den ASCII-Wert aus Zelle 5 und addieren 2 dazu, um den ASCII-Code des Punkts zu erhalten.Danach drucken wir auch eine neue Zeile (unter Verwendung von Zelle 3) und setzen q wieder auf 1. Wir können s auch auf 0 setzen, obwohl es bereits 0 ist nächste Zeile (wenn s ungleich Null war), damit der Code nicht wiederholt wird, tun wir dies nach der Bedingung, die s prüft .
Bisherige Ausgabe:
thyme,\nhorser...,\n
Es ist nur noch eine Iteration übrig. Dieses Mal erhalten wir, nachdem wir die Buchstaben des Wortes gezählt haben, Folgendes:
Dieses Mal gibt es nach p nichts mehr , also setzen wir c auf 0, um „kein Komma“ anzuzeigen, und dementsprechend dekrementieren wir q kein weiteres Mal. Da q jetzt auf eine Nicht-Null-Zelle zeigt, wissen wir, dass das Wort passt, sodass derselbe Code wie in der ersten Iteration ausgeführt wird, mit der Ausnahme, dass diesmal c Null ist, sodass das Komma einfach nicht gedruckt wird.
Ausgabe:
thyme,\nhorser...,\npeppermint
In dieser exemplarischen Vorgehensweise habe ich keinen Fall aufgenommen, in dem der Code tatsächlich ein Leerzeichen drucken würde, aber ich denke, dass es jetzt ziemlich klar sein sollte. Wenn der Code feststellt, dass das Wort passt ( * q ≠ 0) und s ungleich Null ist, wird einfach ein Leerzeichen vor dem Wort ausgegeben.
quelle
JavaScript (ES6), 171
Als anonyme Funktion, die die Ausgabe als Array zurückgibt
(da dies generell erlaubt ist, sofern nicht ausdrücklich verboten: meta meta )
quelle
Python 2, 206 Bytes
quelle