Memformat daftar kata

16

Tantangan Anda adalah memformat daftar kata di beberapa baris yang tidak lebih dari jumlah karakter tertentu, sehingga setiap baris berisi sebanyak mungkin kata dan tidak ada kata yang terpotong tidak perlu.

Memasukkan

Input akan berupa daftar kata-kata yang dipisahkan oleh spasi dan kemudian angka yang setidaknya 4.

Keluaran

Outputnya harus berupa kata-kata input yang dikelompokkan ke dalam baris sehingga tidak ada baris yang mengandung lebih banyak karakter daripada jumlah input. Kata-kata harus berupa output sesuai dengan urutan inputnya. Kata-kata harus dipisahkan dengan koma dan kemudian spasi, kecuali pada akhir setiap baris, di mana spasi tidak diperlukan. Jika sebuah kata terlalu panjang untuk ditampung pada sebuah baris, kata itu harus dipotong sesedikit mungkin saat mengikuti aturan lain, dan "..." harus ditambahkan pada bagian akhir.

Uji kasus

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...
KSFT
sumber
1
Doa yang Mulia!
Fatalkan
Terkait
Peter Taylor

Jawaban:

10

Tidak dapat dibaca , 2559 byte

Tantangan ini sangat cocok untuk Unreadable.

Versi pertama ini adalah 3379 byte, hanya untuk memberi Anda gambaran tentang seberapa banyak saya bermain golf ini.

Program menerima input persis seperti yang dijelaskan dalam tantangan: daftar kata-kata yang dipisahkan oleh ruang (yang mungkin mengandung digit dan tanda baca juga), diikuti oleh spasi dan integer yang setidaknya 4 (angka yang lebih rendah menghasilkan loop tak terbatas) .

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

Penjelasan

Saya akan memandu Anda melalui bagaimana program memproses input thyme horseradish peppermint 10. Output yang diharapkan adalahthyme,\nhorser...,\npeppermint .

Pertama kita mulai dari sel # 7 dan membaca seluruh input, tetapi kurangi 32 dari setiap karakter sehingga spasi menjadi nol.

Untuk alasan yang jelas, ini meninggalkan pointer berjalan (bernama hal sini, disimpan di sel # 0) di akhir. Kami menggunakan satu loop sementara untuk menemukan celah terakhir, yang merupakan awal dari angka yang mendefinisikan lebar output (sel # 36 dalam contoh ini).

Kami sekarang ingin men-decode angka (yaitu konversi dari desimal). Hasil akhir akan berada di kedua sel t dan r . Kami mengandalkan fakta bahwa mereka mulai dari nol.

Untuk setiap digit angka, lakukan hal berikut:

  • Set t ke −15.
  • Dalam loop sementara, penurunan r (yang berisi hasil sejauh ini) ke −1 (karena kita membutuhkan r iterasi yang tepat , tetapi karena penurunan terjadi sebelum diperiksa sebagai kondisi loop sementara, penurunan ke 0 akan memberikan iterasi yang lebih sedikit) dan untuk setiap iterasi, tambahkan 10 ke t . Sekarang t berisi 10 kali hasil sebelumnya minus 15.
  • Sekali lagi dalam loop sementara, turunkan * p ke 0 dan untuk setiap iterasi, tambahkan 1 ke t . Setelah t ini berisi hasil antara yang benar sejauh ini: karakter '0'untuk '9'memiliki kode ASCII 48–57, jadi setelah pengurangan sebelumnya dari 32 mereka adalah 16-25, jadi kami benar-benar menambahkan 15-24 ke t , yang dibatalkan dengan −15 kita atur ke sebelumnya. Penting juga bahwa ini nol sel yang digunakan untuk berisi karakter digit sehingga kode selanjutnya dapat mengenali akhir daftar kata-kata.
  • Set r ke hasil tengah baru sehingga iterasi berikutnya menemukannya di r . (Perhatikan bahwa kita tidak perlu membaca dari t lagi, kita bisa menggunakan nilai terakhir dari loop sementara sebelumnya karena kita tahu bahwa * p tidak boleh nol, sehingga telah berjalan setidaknya sekali.)

Akhirnya, kami menggunakan loop sementara sederhana lainnya (decrementing t sebagai penghitung) untuk mengubah angka yang baru saja kita hitung menjadi unary. Kami menyimpan string 1s ke kiri dari sel # 0. Ini bergantung pada fakta bahwa sel # 1, pointer berjalan kami untuk ini ( q ), dimulai pada 0. Kami mendapatkan 1 yang lebih sedikit karena sementara loop di Unreadable seperti itu:

Setelah ini, kita tidak lagi membutuhkan nilai dalam r , jadi kami menggunakan kembali sel itu untuk hal lain. Kami mereset pointer p dan q dan menginisialisasi beberapa sel dengan kode karakter ASCII yang kami butuhkan nanti. Saya juga memberi label c dan s yang akan kami gunakan nanti, dan kami akan mengandalkan fakta bahwa s dimulai dari nol:

Hei, tunggu sebentar. Mengapa sel # 0 berwarna merah? ... Ya, ini untuk menyoroti trik licik. Ingat kami output satu 1 terlalu sedikit? Kuncinya adalah kita menggunakan sel # 0 sebagai "ekstensi" untuk memperbaikinya. Ini bekerja karena kita tahu bahwa p tidak akan pernah menjadi 0. Dengan cara ini, blok merah sekarang memiliki lebar 10 sel, persis jumlah yang kita inginkan. Ini juga menghemat 9 karakter untuk dapat menginisialisasi q ke 1, bukan 0.

Sekarang kita memasuki loop while yang melewati kata-kata dan mengeluarkan semuanya.

Langkah 1: Cari tahu apakah kata berikutnya akan cocok dengan baris saat ini. Kami melakukan ini hanya dengan memindahkan p ke kanan dan q ke kiri dengan loop sementara sampai p menyentuh celah berikutnya:

Sekarang p ada di sebelah kanan kata, kita dapat memeriksa apakah ini adalah kata terakhir dalam daftar dengan memeriksa apakah * (p + 1) adalah nol. Kami juga menyimpan nilai itu (yang dalam contoh kami adalah 72 karena itu adalah "h" dari "lobak" minus 32) di c karena kita akan membutuhkannya lagi nanti. Dalam hal ini, ini bukan nol, jadi kita perlu menampilkan koma bersama kata, jadi kata tersebut lebih panjang satu karakter. Pertimbangkan ini dengan mengurangi q sekali lagi. Akhirnya, gunakan loop sementara lainnya untuk memindahkan p kembali ke awal kata.

Kita sekarang tahu bahwa kata itu akan cocok dengan baris saat ini karena q menunjuk pada nilai yang tidak nol, jadi yang harus kita lakukan adalah:

  • Bergerak p maju melalui kata lagi, mencetak setiap karakter (ditambah 32, karena semua kode ASCII dimatikan oleh 32).
  • Jika c adalah nol, cetak koma (menggunakan nilai dalam sel # 5).
  • Tetapkan s ke nilai bukan nol untuk menunjukkan ke iterasi berikutnya bahwa kita tidak lagi di awal baris dan oleh karena itu perlu menampilkan karakter spasi sebelum kata berikutnya. (Kami menggunakan kembali nilai pernyataan cetak di atas untuk ini, yaitu 44 untuk koma.)

Output sejauh ini: thyme,

Kemudian iterasi loop besar berikutnya dimulai. Seperti sebelumnya, kita memeriksa apakah kata berikutnya cocok dengan sisa baris dengan mengurangi q saat kita menelusuri kata dari kiri ke kanan. Perhatikan bahwa q masih −5 dari iterasi sebelumnya, catat berapa banyak karakter yang telah kita cetak pada baris saat ini. Setelah menghitung karakter dalam "lobak", ditambah satu untuk koma, ditambah satu karena s adalah nol, yang menunjukkan bahwa kita perlu menampilkan spasi juga, q akan melampaui ujung blok 1s:

Sekarang q menunjuk pada sel nol, yang berarti “lobak” tidak akan cocok dengan garis saat ini. Apa yang kita lakukan sekarang tergantung pada apakah s adalah nol. Dalam kasus kami, itu artinya kita perlu membungkus ke baris berikutnya. Yang harus kita lakukan untuk itu adalah:

  • Cetak baris baru (menggunakan sel # 3)
  • Atur q kembali ke 1
  • Set s ke 0

Output sejauh ini: thyme,\n

Untuk iterasi berikutnya, p ada di tempat yang sama seperti sebelumnya, jadi kita akan melihat kata yang sama lagi. Seperti sebelumnya, kita menghitung karakter dalam “horseradish”, atur c ke 80 lagi ketika kita melihat ada kata lain setelah ini, mengurangi q untuk koma, dan mundur p kembali ke awal kata:

Seperti dalam iterasi sebelumnya, kami menemukan bahwa "lobak" masih tidak cocok karena q berakhir pada sel yang nol. Namun, kali ini s adalah nol, yang berarti kita melakukan sesuatu yang berbeda dari terakhir kali. Kita perlu menampilkan beberapa kata, tiga titik dan koma. Lebar kami adalah 10, jadi kami harus menampilkan 6 karakter kata. Mari kita lihat di mana kita berakhir jika kita:

  • Temukan awal blok merah 1s. Kita dapat melakukan ini dengan berbelok ke kanan karena kita tahu bahwa q harus dibiarkan begitu saja.
  • Kenaikan q sekali lagi jika kita juga perlu mengeluarkan koma ( c ≠ 0).

Rekaman itu sekarang terlihat seperti ini:

Saya telah menandai rentang 6 sel di sini. Seperti yang Anda lihat, kita perlu menampilkan karakter sampai q = −1. Ini sangat efisien untuk memeriksa kode (pada dasarnya, while ((++q)+1) { ... }). Begitu:

  • Cetak karakter tersebut (ditambah 32, karena semua kode ASCII dimatikan oleh 32) hingga q mencapai −1. p kemudian akan berada di sel 19, di tengah kata "lobak".
  • Cetak tiga titik. Karena perintah cetak mengembalikan argumennya sendiri, kita dapat menyarangkannya dengan efisien (pada dasarnya, print(print(print('.')))). Kami mengambil nilai ASCII dari sel # 5 dan menambahkan 2 untuk mendapatkan kode ASCII dari titik tersebut.
  • Pindahkan p ke akhir kata. Karena kita tahu kita tidak mungkin telah mencapai akhir kata (karena kata itu terlalu panjang, dan kita harus menghapus setidaknya 3 karakter agar sesuai dengan titik-titik), loop ini pasti memiliki setidaknya satu iterasi, jadi itu lebih pendek dalam kode untuk memiliki tubuh loop sementara menghitung nilai ASCII untuk titik dan kemudian meneruskan nilai kembali dari loop sementara ke fungsi cetak.
  • Cetak koma jika c adalah nol.

Setelah semua ini, kami juga mencetak baris baru (menggunakan sel # 3) dan mengatur q kembali ke 1. Kami juga dapat mengatur s ke 0 meskipun sudah 0, yang membuat ini sama dengan yang kami lakukan sebelumnya ketika kami membungkus ke baris berikutnya (ketika s adalah nol), jadi untuk menghindari pengulangan kode, kita melakukannya setelah syarat yang memeriksa s .

Output sejauh ini: thyme,\nhorser...,\n

Hanya ada satu iterasi yang tersisa. Kali ini, setelah menghitung huruf-huruf kata, kita mendapatkan ini:

Kali ini, tidak ada apa pun setelah p , jadi kami menetapkan c ke 0 untuk menunjukkan "tidak ada koma", dan karenanya kami tidak mengurangi q waktu lebih lanjut. Karena q sekarang menunjuk ke sel yang bukan nol, kita tahu kata itu akan cocok, sehingga kode yang sama dijalankan seperti pada iterasi pertama, kecuali kali ini c adalah nol, jadi ia tidak akan mencetak koma.

Keluaran: thyme,\nhorser...,\npeppermint

Dalam langkah-langkah ini saya tidak memasukkan kasus di mana kode akan benar-benar mencetak spasi, tapi saya pikir itu harus cukup jelas sekarang. Jika kode menemukan bahwa kata tersebut cocok ( * q ≠ 0) dan s adalah bukan nol, kode itu hanya akan menghasilkan spasi sebelum kata tersebut.

Timwi
sumber
3

JavaScript (ES6), 171

Sebagai fungsi anonim mengembalikan output sebagai array

(karena ini umumnya diperbolehkan kecuali dilarang secara eksplisit: 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>

edc65
sumber
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)
TFeld
sumber