Formatieren Sie eine Liste von Wörtern


16

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:


10

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 ist thyme,\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:

  • einstellen t auf −15.
  • In einer while-Schleife wird r (das das Ergebnis enthält) auf −1 dekrementiert (da wir genau r- Iterationen benötigen , aber da die Dekrementierung erfolgt, bevor sie als Bedingung für die while-Schleife geprüft wird, würde eine Dekrementierung auf 0 eine Iteration weniger ergeben). und füge für jede Iteration 10 zu t hinzu . Jetzt enthält t das 10-fache des vorherigen Ergebnisses minus 15.
  • In einer while-Schleife dekrementieren Sie * p erneut auf 0 und addieren Sie für jede Iteration 1 zu t . Danach enthält t das korrekte Zwischenergebnis: Die Zeichen '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.
  • Setze r auf das neue Zwischenergebnis, so dass die nächste Iteration es in r findet . (Beachten Sie, dass wir nicht noch einmal von t lesen müssen, sondern nur den letzten Wert der vorherigen while-Schleife verwenden können, da wir wissen, dass * p nicht Null sein kann und daher mindestens einmal ausgeführt wurde.)

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:

  • Bewegen Sie p erneut vorwärts durch das Wort und drucken Sie jedes Zeichen (plus 32, da alle ASCII-Codes um 32 deaktiviert sind).
  • Wenn c nicht Null ist, geben Sie ein Komma aus (unter Verwendung des Werts in Zelle 5).
  • Setzen Sie s auf einen Wert ungleich Null, um bei der nächsten Iteration anzuzeigen, dass wir nicht mehr am Anfang einer Zeile stehen und daher ein Leerzeichen vor dem nächsten Wort ausgeben müssen. (Wir verwenden dafür den Rückgabewert der obigen print-Anweisung, also 44 für das Komma.)

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:

  • Neue Zeile drucken (mit Zelle 3)
  • Stellen Sie q wieder auf 1
  • einstellen s auf 0

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:

  • Finden Sie den Anfang des roten Blocks von 1s. Wir können dies tun, indem wir nach rechts gehen, weil wir wissen, dass q davon übrig bleiben muss.
  • Erhöhen Sie q erneut, wenn Sie auch ein Komma ausgeben müssen ( c ≠ 0).

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:

  • Drucken Sie diese Zeichen (plus 32, da alle ASCII-Codes um 32 versetzt sind), bis q −1 erreicht.p befindet sich dann in Zelle 19, in der Mitte des Wortes "Meerrettich".
  • Drucken Sie drei Punkte. Da der Druckbefehl ein eigenes Argument zurückgibt, können wir es Code-effizient verschachteln (im Wesentlichenprint(print(print('.'))) ) . Wir nehmen den ASCII-Wert aus Zelle 5 und addieren 2 dazu, um den ASCII-Code des Punkts zu erhalten.
  • Bewegung p an das Ende des Wortes. Da wir wissen, dass wir das Ende des Wortes noch nicht erreicht haben können (weil das Wort zu lang war und wir mindestens 3 Zeichen entfernen mussten, um die Punkte einzufügen), hat diese Schleife definitiv mindestens eine Iteration Im Code ist es kürzer, wenn der Rumpf der while-Schleife den ASCII-Wert für den Punkt berechnet und dann den Rückgabewert der while-Schleife an die Druckfunktionen übergibt.
  • Gib ein Komma aus, wenn c nicht Null ist.

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.


3

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 )

s=>(s=s.split` `,n=s.pop()-1,t='',o=[],s.map((w,i)=>(w=w[n+=!s[i+1]]?w.slice(0,n-3)+'...':w,(t+w)[n-2]&&(t&&o.push(t.slice(1)),t=''),t+=` ${w},`)),o.push(t.slice(1,-1)),o)

f=s=>(s=s.split` `,n=s.pop()-1,t='',o=[],s.map((w,i)=>(w=w[n+=!s[i+1]]?w.slice(0,n-3)+'...':w,(t+w)[n-2]&&(t&&o.push(t.slice(1)),t=''),t+=` ${w},`)),o.push(t.slice(1,-1)),o)

// Less golfed
U=s=>(
  s=s.split` `,
  n=s.pop()-1,
  t='', // current line
  o=[], // output
  s.map( (w,i)=>(
    w=w[
      n+=!s[i+1] // space for 1 more char on the last line
    ]?w.slice(0,n-3)+'...':w, // change w if it is too long
    (t+w)[n-2]&& ( // if current line + w is too long, ouput t and reset current line
      t&&o.push(t.slice(1)),t=''
    ),
    t+=` ${w},`
  )),
  o.push(t.slice(1,-1)), // remove tailing comma on last line
  o
)

console.log=x=>O.textContent+=x+'\n\n';
  
console.log(f("foo bar baz qux 12").join`\n`)
console.log(f("foo bar baz qux 5").join`\n`)
console.log(f("strength dexterity constitution intelligence wisdom charisma 10").join`\n`)
console.log(f("quas wex exort 4").join`\n`)
<pre id=O></pre>


1

Python 2, 206 Bytes

i=input().split()
l=int(i.pop())
i=[[w[:l-4]+'...',w][len(w)<l]+','for w in i][:-1]+[[w,w[:l-3]+'...'][len(w)>l]]
r=[i.pop(0)]
for w in i:
 if len(r[-1])+len(w)<l:r[-1]+=' '+w
 else:r+=[w]
print'\n'.join(r)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.