Formatta un elenco di parole


16

La tua sfida è quella di formattare un elenco di parole su più righe che non siano più lunghe di un determinato numero di caratteri, in modo che ogni riga contenga quante più parole possibili e nessuna parola venga inutilmente tagliata.

Ingresso

L'input sarà un elenco di parole separato da spazi e quindi un numero che è almeno 4.

Produzione

L'output dovrebbe essere le parole di input raggruppate in righe in modo che nessuna delle righe contenga più caratteri del numero di input. Le parole dovrebbero essere emesse nell'ordine in cui sono state inserite. Le parole devono essere separate da una virgola e quindi da uno spazio, tranne alla fine di ogni riga, dove lo spazio non è necessario. Se una parola è troppo lunga per adattarsi a una linea, dovrebbe essere tagliata il meno possibile seguendo le altre regole e "..." dovrebbe essere aggiunto alla fine.

Casi test

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...


Risposte:


10

Illeggibile , 2559 byte

Questa sfida è stranamente adatta per illeggibile.

La prima versione di questo è stata di 3379 byte, solo per darti un'idea di quanto ho giocato a golf.

Il programma accetta l'input esattamente come descritto nella sfida: un elenco di parole separato da spazi (che può contenere anche cifre e segni di punteggiatura), seguito da uno spazio e un numero intero che è almeno 4 (i numeri più bassi generano cicli infiniti) .

' '' '' ''' "" "" "" "" ' '' ' ' '''' ' ' '''' ' ' '''' "' '' "' '' ''"'" " ' '' '' '''" "' '' ' ' '' '' '' '' '''' '' '' ' ' '' '' '''' '' '' ''"' "" " ' '''" "" "" "" ' '' '' '' ''' "" " ' '' '' '' '''" "" "" "" "'""" "" "" " ' '' '' '' '''" "" "" "" " ' '' '' '' '''" "" "" "" " ' '' '' '' "" ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" "" ' ''""" "" " ' '' '' '' '''" "" "" "" " ' '' '' '' '''" "" "" "" " ' '' '' '' '' ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" "" ' '' '' '' ' ' '''' ''' "" "" " ' ''"" "" " ' '' '' '''" "" "" "" " ' '' ' ' '' '' '' '''' '' '' '''" "" "" "" "' ''" ' '' "' '' '' "' '' '' '' ' ' '' '' '''' '' '' ''" ' '' ' ' '''' '' "" "" ' '' '' '' ''' "" " ' '' '''" "" " ' '' '' '''" "' ''"' '' '' """ " ' '' '' '' '''" "" "" "" " ' '' '' '' '''" "" "" "" " ' '' '' '' '''" "" "" "" " ' '' '' '' '''" "" "" "" " ' '' '' '' '''" "" "" "" " ' '' '' '' "" ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" "" ' '' "' ''""" ' ''' "" "" "" ' ''' "" ' '' ' ' '' '' '' '''' '' '' ''' "" ' ''' "" "' "" "" "" ' ''' "" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '' '' '' " ' '''" "" ' '' '' ''' "" ' ''' "" " ' '' '' ' ' '' '' '''' '' '' '''"""" "" "" ' '' ' ' '' '' '' '''' '' '' ''' "" "" "" " ' '' '' '' '''" "" '" "" "" " ' '''" "" ' ''' "" "" "" " ' '''" "" ' '' '' ' ' '' '' '''' "' ''" ' '' '' '' ''' "" "" "" " ' '''" "" ' '' '' ''' "" "" "" ' '' "' '' ''"" "" ' '' '' '' "' '' ' ' '' ' ' '' '' '''' ' ' '''' ' ' '''' ''''" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" "" "" ' ''' "" ' ''' "" '" "' '' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' ''''"' ''' ''' "" ' ''' "" ' ''' "" ' ''' "" "" "" ' ''' "" ' '' ' ' '''' ' ' ''''" "" "" ' '' '' '' ''' "" " ' '''" " ' '''" " ' '''" " ' '' '' '''" "" ' ''" ' '' '' ' ' '' '' '' ' ' '''' '' '' '''' '' '' '' "' '' ' ' '' '''' ''" '"" "" ' '' '' "' '' '' '' ' ' '' '' '''' '' '' ''" ' '' ' ' '''' '' '' ''' "" "" "" "" ' '' ' ' '' '' '''' ''' "" "" "" "" ' '' '' '' "' '' "' '' ''" "" "" ' '' '' ''' "" ' '' ' ' '' '' '' ' ' '''' '' '' '''' '' '' '' "'"" " ' '' '' '''" "" ' '' '' '' ''' "" "" "" "' ''" ' '' "' '' ''"' '' '' "" " ' '' '' '''" "" "" "" " ' '' ' ' '' '' '' '''' '' '' '''" "" "" "" "' "" "' '' ' ' '' '' '''' ' ' ''''" ' '' "' '' '' '' '' "' '' '' ''" '""" "" "" "" ' '' '' '' ' ' '''' ' ' '''' ''' "" "" "" ' '' " ' '' '' '' ''' "" "" "" "' ''" ' '' '' '' "' '' ' ' '' '''' '' "' '' '' '' ''" ' '' '' '' " ' '''" " ' '''" "" ' ' ' '' '' '' ' ' '''' ' ' '''' ' ' '''' '''' '''"" "" " ' '' '' '' ' ' '' '' '''' '' '' '' ' ' '' ' ' '''' '' '' '''' '' '' "" "' ''"' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" "'"" ' ''' "" "" "" " ' '' '' '' ' ' '' '' '' '''' '''" "" "" "" "" ' '' ''" "" ' ''' "" "'" ' '' '' '' ' ' '''' ' ' '''' "' '' "' '' ' ' '' '''' ''" ' "" "" "" "" " ' '' '' '' ' ' '''' ' ' '''' '''" "" ' '' ''' "" "" ' ''"" ' '' '''" "" "" ' '' '' '' ''' "" "" "" " ' '' '' '''" "" ' ''' "" "" "" "' ''" ' '' "' '' '' '' '' ' ' '' '' '' ' ' '''' '''' '' ''"' '' ' ' '''' "" "" "" ' '' "' ''" ' '' '' ' ' '''' '' '' ' ' '' ' ' '''' '' '' ''''"" ' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' " ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' '' '' '' ' ' '' '' '''' '' '' '' ' ' '' ' ' '''' '' '' '''' '' '' '' "'""" '"' "'" ' '' ''"' '' '' '' ' ' '' '' '''' '' '' '' "' '' ' ' '''' ''" "" " ' '' '' '' '''" "" ' ''' "" ' '' '' '' ' ' '''' ' ' '''' "' '' "' ''" "" "" "" ' '' '' '' ' ' '''' ''' "' '' '' '' ' ' '''' ' ' ''''" ' '' "'"" "'" ' '' '' '' ' ' '''' "' '' ' ' '' '' '' '''' '' '' "' ''" ' ''"

Spiegazione

Ti guiderò attraverso il modo in cui il programma elabora l'input thyme horseradish peppermint 10. L'output previsto è thyme,\nhorser...,\npeppermint.

Iniziamo dalla cella 7 e leggiamo l'intero input, ma sottraiamo 32 da ogni carattere in modo che gli spazi diventino zeri.

Per ovvi motivi, questo lascia il puntatore in esecuzione (chiamato p qui, memorizzato nella cella # 0) alla fine. Usiamo un ciclo while per trovare l'ultimo gap, che è l'inizio del numero che definisce la larghezza dell'output (cella # 36 in questo esempio).

Vogliamo ora decodificare il numero (ovvero convertire da decimale). Il risultato finale sarà sia in cellule t ed r . Facciamo affidamento sul fatto che iniziano da zero.

Per ogni cifra nel numero, procedi come segue:

  • Impostare t su −15.
  • In un ciclo while, decremento r (che contiene il risultato finora) a -1 (perché abbiamo bisogno esattamente r iterazioni, ma poiché il decremento avviene prima viene verificato come il tempo condizione del loop, decrementando a 0 darebbe uno iterazioni meno) e per ogni iterazione, aggiungi da 10 a t . Ora t contiene 10 volte il risultato precedente meno 15.
  • Sempre in un ciclo while, decrementa * p su 0 e per ogni iterazione, aggiungi 1 a t . Dopo questo t contiene finora il risultato intermedio corretto: i caratteri '0'devono '9'avere i codici ASCII 48–57, quindi dopo la sottrazione precedente di 32 sono 16–25, quindi in realtà aggiungiamo 15-24 a t , che si annulla con il −15 lo abbiamo impostato prima. È anche importante che questo azzeri le celle che contengono i caratteri delle cifre in modo che il codice successivo possa riconoscere la fine dell'elenco di parole.
  • Impostare r sul nuovo risultato intermedio in modo che la successiva iterazione lo trovi in r . (Nota che non abbiamo bisogno di leggere di nuovo da t , possiamo semplicemente usare l'ultimo valore del precedente ciclo while perché sappiamo che * p non può essere zero, quindi è stato eseguito almeno una volta.)

Infine, usiamo un altro ciclo while semplice (decrementando t come contatore) per convertire il numero che abbiamo appena calcolato in unario. Memorizziamo una stringa di 1 andando a sinistra dalla cella # 0. Ciò si basa sul fatto che la cella n. 1, il nostro puntatore in esecuzione per questo ( q ), inizia da 0. Otteniamo 1 in meno perché perché i loop in Illeggibile sono così:

Dopo questo, non abbiamo più bisogno del valore in r , quindi riutilizziamo quella cella per qualcos'altro. Abbiamo Azzera i puntatori p e q e inizializzare alcune cellule con i codici ASCII dei personaggi di cui abbiamo bisogno in seguito. Ho anche etichettato c e s che useremo in seguito, e faremo affidamento sul fatto che s inizia da zero:

Ehi, aspetta un minuto. Perché la cella # 0 è colorata di rosso? ... Bene, questo è per evidenziare un trucco subdolo. Ricorda che ne abbiamo prodotto uno in meno? Il trucco è che usiamo la cella # 0 come "estensione" per correggere. Funziona perché sappiamo che p non sarà mai 0. In questo modo, il blocco rosso è ora largo 10 celle, esattamente il numero che vogliamo. Inoltre salva 9 caratteri per poter inizializzare q su 1 invece di 0.

Ora entriamo nel ciclo while che passa attraverso le parole e le emette tutte.

Passaggio 1: scopri se la parola successiva si adatta alla riga corrente. Facciamo questo semplicemente spostando p verso destra e q verso sinistra con un ciclo while fino a quando p raggiunge il gap successivo:

Ora che p è sulla destra della parola, possiamo verificare se questa è l'ultima parola nell'elenco controllando se * (p + 1) è zero. Conserviamo anche quel valore (che nel nostro esempio è 72 perché è la "h" da "rafano" meno 32) in c perché ne avremo più bisogno in seguito. In questo caso, non è zero, quindi dovremo generare una virgola insieme alla parola, quindi la parola è più lunga di un carattere. Tenerne conto diminuendo q ancora una volta. Infine, usa un altro ciclo while per spostare p indietro all'inizio della parola.

Ora sappiamo che la parola si adatterà alla riga corrente perché q indica un valore diverso da zero, quindi tutto ciò che dobbiamo fare è:

  • Spostare di nuovo p in avanti attraverso la parola, stampando ciascun carattere (più 32, poiché tutti i codici ASCII sono disattivati ​​di 32).
  • Se c è diverso da zero, stampare una virgola (utilizzando il valore nella cella # 5).
  • Impostare s su un valore diverso da zero per indicare alla successiva iterazione che non siamo più all'inizio di una riga e quindi è necessario emettere uno spazio prima della parola successiva. (Per questo riutilizziamo il valore restituito dell'istruzione di stampa sopra, che è 44 per la virgola.)

Uscita finora: thyme,

Quindi inizia la successiva iterazione del ciclo grande. Come prima, controlliamo se la parola successiva si adatta al resto della riga diminuendo q mentre attraversiamo la parola da sinistra a destra. Si noti che q è ancora −5 dalla precedente iterazione, tenendo traccia di quanti caratteri abbiamo già stampato nella riga corrente. Dopo aver contato i caratteri in "rafano", più uno per la virgola, più uno perché s è diverso da zero indicando che è necessario generare anche uno spazio, q avrà superato la fine del blocco di 1s:

Ora q punta a una cella zero, il che significa che "rafano" non si adatterà alla linea corrente. Ciò che facciamo ora dipende dal fatto che s sia diverso da zero. Nel nostro caso lo è, il che significa che dobbiamo passare alla riga successiva. Tutto quello che dobbiamo fare per questo è:

  • Stampa una nuova riga (utilizzando la cella n. 3)
  • Riportare q su 1
  • Impostare s su 0

Uscita finora: thyme,\n

Per la prossima iterazione, p è nello stesso posto di prima, quindi vedremo di nuovo la stessa parola. Come in precedenza, contiamo i caratteri in "rafano", impostiamo di nuovo c su 80 quando notiamo che c'è un'altra parola dopo questa, diminuiamo q per la virgola e riavvolgiamo p all'inizio della parola:

Come nella precedente iterazione, troviamo che il "rafano" non si adatta ancora perché q finisce su una cella che è zero. Tuttavia, questa volta s è zero, il che significa che facciamo qualcosa di diverso dall'ultima volta. Abbiamo bisogno di produrre una parte della parola, tre punti e una virgola. La nostra larghezza è 10, quindi abbiamo bisogno di produrre 6 caratteri della parola. Vediamo dove finiamo se:

  • Trova l'inizio del blocco rosso di 1s. Possiamo farlo andando a destra perché sappiamo che q deve esserne lasciato.
  • Incrementa q ancora una volta se dobbiamo anche emettere una virgola ( c ≠ 0).

Il nastro ora appare così:

Ho segnato un arco di 6 celle qui. Come puoi vedere, dobbiamo emettere caratteri fino a q = −1. Questo è molto efficiente dal punto di vista del codice da controllare (in pratica, while ((++q)+1) { ... }). Così:

  • Stampa quei caratteri (più 32, perché tutti i codici ASCII sono disattivati ​​di 32) fino a quando q raggiunge −1. p sarà quindi nella cella 19, nel mezzo della parola "rafano".
  • Stampa tre punti. Poiché il comando print restituisce il proprio argomento, possiamo nidificarlo in modo efficiente (essenzialmente, print(print(print('.')))). Prendiamo il valore ASCII dalla cella # 5 e ne aggiungiamo 2 per ottenere il codice ASCII del punto.
  • Sposta p alla fine della parola. Poiché sappiamo di non aver già raggiunto la fine della parola (perché la parola era troppo lunga e abbiamo dovuto rimuovere almeno 3 caratteri per adattarla ai punti), questo ciclo ha sicuramente almeno un'iterazione, quindi è più breve nel codice fare in modo che il corpo del ciclo while calcoli il valore ASCII per il punto e quindi passi il valore di ritorno del ciclo while alle funzioni di stampa.
  • Stampa una virgola se c è diverso da zero.

Dopo tutto questo, stampiamo anche una nuova riga (usando la cella # 3) e riportiamo q su 1. Possiamo anche impostare s su 0 anche se è già 0, il che rende lo stesso che abbiamo fatto in precedenza quando abbiamo spostato il riga successiva (quando s era diverso da zero), quindi per evitare di ripetere il codice, lo facciamo dopo il condizionale che controlla s .

Uscita finora: thyme,\nhorser...,\n

È rimasta una sola iterazione. Questa volta, dopo aver contato le lettere della parola, otteniamo questo:

Questa volta, non c'è nulla dopo p , quindi impostiamo c su 0 per indicare "nessuna virgola", e di conseguenza non diminuiamo q un'altra volta. Poiché q ora punta a una cella diversa da zero, sappiamo che la parola si adatterà, quindi lo stesso codice viene eseguito come nella prima iterazione, tranne che questa volta c è zero, quindi semplicemente non stampa la virgola.

Produzione: thyme,\nhorser...,\npeppermint

In questa procedura dettagliata non ho incluso un caso in cui il codice stampasse effettivamente uno spazio, ma penso che dovrebbe essere abbastanza chiaro ora. Se il codice rileva che la parola si adatta ( * q ≠ 0) e s è diversa da zero, genererà semplicemente uno spazio prima della parola.


3

JavaScript (ES6), 171

Come una funzione anonima che restituisce l'output come un array

(in quanto ciò è generalmente consentito a meno che non sia esplicitamente vietato: 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 byte

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.