Luruskan teks


27

Tugas Anda adalah mengambil input string dan angka serta menyelaraskan string ke kanan, menjadikan lebar teks sebagai nomor. Ketika garis terlalu panjang, pecahkan dan letakkan sisanya di baris berikutnya, ulangi sampai tidak perlu. Jika garis lebih pendek dari lebarnya, maka balut dengan spasi. Beberapa baris baru dapat muncul, dan harus diperlakukan seperti karakter tunggal lainnya.

Misalnya, string

Programming
Puzzles
&
Code
Golf

dan jumlahnya 5akan menghasilkan:

Progr
ammin
    g
Puzzl
   es
    &
 Code
 Golf

Sedangkan string dan nomor yang sama 10akan menghasilkan:

Programmin
         g
   Puzzles
         &
      Code
      Golf

String

a

b

dan angka 5 akan menghasilkan:

    a
      <-- note the 5 spaces
    b

Kode terpendek menang!


1
Teks mengatakan "Hancurkan garis bila perlu [...]", tetapi contoh Anda menyarankan agar Anda mengingkari setiap kata, bahkan ketika itu cocok. Harap jelaskan: apakah kita menempatkan setiap kata pada baris baru, atau apakah kita menerapkan algoritma pembungkusan kata yang sebenarnya?
Timwi

Bisakah ada spasi di tengah-tengah jalur input, misalnya Programming Puzzles\n&\nCode Golf?
Sp3000

@ sp3000 Bisa ada karakter apa pun, termasuk spasi.
Trebuchette

@Timwi: Contohnya memiliki satu kata per baris. Akan lebih baik untuk memasukkan beberapa baris multi-kata untuk memperjelas bahwa ruang di dalam sebuah baris tidak spesial. (yaitu hanya ada baris baru, dan non-baris baru.)
Peter Cordes

Jawaban:



10

Python 2, 84

s,n=input()
for w in s.split('\n'):
 w=w or' '
 while w:print w[:n].rjust(n);w=w[n:]

Dibawa sebagai input string dengan baris baru dan angka, dan mencetak hasilnya. Untuk setiap baris dalam input, ambil dan cetak nkarakter sekaligus, menggunakan built-in rjustuntuk melapisi bagian kiri dengan spasi sebelum mencetak.

Saya memperbaiki kasing kosong dengan retas w=w or' '. Mungkin ada metode yang lebih baik, tetapi saya tidak akan terlalu memikirkannya.


8

CJam, 21 byte

li_qN/Sfe|f/ff{\Se[N}

Terima kasih kepada @ Sp3000 untuk bermain golf 1 byte dan membuka jalan untuk 3 lebih.

Cobalah online di juru bahasa CJam .

Bagaimana itu bekerja

li                     Read an integer L from the first line of input.
  _                    Push a copy.
   qN/                 Split the remaining input at linefeeds.
      Sfe|             Map `OR " "'; the replaces empty lines with a space.
          f/           Split each line into chunks of length L.
            ff{     }  For each chunk, push L and the chunk; then:
               \         Swap L with the chunk.
                Se[      Left-pad the chunk to length L by prepending " ".
                   N     Push a linefeed.

5

Pyth, 16

jm>Q+*\ QdscRQ.z

Cobalah online di sini

Penjelasan

jm>Q+*\ QdscRQ.z             : Q is the number on the first line, .z takes the rest
           cRQ.z             : chop each line of .z into chunks of Q characters
 m        s                  : remove nested lists and map over the result
    +*\ Qd                   : add Q spaces to each line d
  >Q                         : take the last Q characters of that result
j                            : join results on newlines

4

Perl, 39 byte

perl -ni5 -e 's!^$|.{1,$^I}!printf"%${^I}s
",$&!ge'

36 byte + 3 byte untuk -ni. Lebar bungkus dilewatkan sebagai argumen untuk -i.

Tangani garis kosong dengan benar dengan melapisinya dengan spasi:

$ echo -e "Programming\nPuzzles\n\n&\n\nCode\nGolf" | perl -ni5 -e 's!^$|.{1,$^I}!printf"%${^I}s
",$&!ge'
Progr
ammin
    g
Puzzl
   es

    &

 Code
 Golf

Bagaimana itu bekerja

Solusi ini menggunakan operator substitusi untuk mengulang melalui input, menghemat satu byte di atas forloop yang setara . Trik sebenarnya, bagaimanapun, adalah di regex pada LHS substitusi:

^$|.{1,$^I}

Dengan pengubah global, ini akan cocok dengan $^Ikarakter sekaligus; ketika ada kurang dari $^Ikarakter yang tersisa di string, itu akan cocok dengan semuanya hingga akhir. Pergantian dengan ^$diperlukan untuk menangani garis kosong. Sebagai contoh:

$ echo -e "foo\n\nbar" | perl -ni2 -E 'say "<$_>" for /^$|.{1,$^I}/g'
<fo>
<o>
<>
<ba>
<r>

RHS dari substitusi hanya digunakan printfuntuk pad kiri-chunk yang cocok dengan spasi.


Saya selalu lupa $^I!
Dom Hastings

@HomHastings Saya belajar trik itu dari chilemagic, yang menyebutkannya dalam komentar tentang tantangan lain .
ThisSuitIsBlackNot

3

Javascript (ES6), 107

Saya berharap JS memiliki fungsi pad built-in. Baiklah.

(a,b)=>a.replace(eval(`/(.{${b}})(?!\\n)/g`),`$1
`).split`
`.map(c=>(Array(b).join` `+c).slice(-b)).join`
`

Penjelasan:

(a, b)=>

  // searches for sequences of characters longer than b without a newline after them and
  // adds a newline after every b characters of the sequence
  a.replace(eval(`/(.{${b}})(?!\\n)/g`), '$1\n')
    .split('\n')
    .map(c=>

      // prepends b spaces to each string then slices it from the right down to length b
      ( Array(b).join(' ') + c ).slice(-b)

    ).join('\n')

3

Julia, 126 byte

f(s,n)=for i=split(s,"\n") while length(i)>0 println(lpad(i[1:min(n,end)],n));length(i)<n?break:(i=i[min(n+1,end):end])end;end

Tidak Disatukan:

function f(s::String, n::Int)
    for i in split(s, "\n")
        while length(i) > 0
            println(lpad(i[1:min(n,end)], n))
            length(i) < n ? break : (i = i[min(n+1,end):end])
        end
    end
end

2

Fitur Bash, 62 , 61+ , 59

Lebih pendek jika Ndapat diatur oleh pemanggil, daripada harus membacanya sebagai baris input pertama.

# width as a function arg: 59 chars
f()while read -rn$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done
# width on stdin: 64 chars  (not updated with later suggestions&ideas)
read N;while read -rn$N r;do [[ $r ]]&&printf %$N's\n' "$r";done

Ini gagal menangani garis kosong di input. Jika tidak, ini tidak akan memasukkan data input ke pemisahan kata, perluasan nama path, atau memperlakukannya lebih dari sekadar data mentah.

read -n$Nmenyimpan satu karakter, tetapi memungkinkan readmunge \.

Ini [[ $r ]]&&diperlukan karena read -n4tidak dapat melihat ke depan untuk melihat bahwa arang berikutnya adalah baris baru. Jadi set rke string 4-char, dan pembacaan berikutnya menghasilkan string kosong-char. Memfilter baris baru palsu ini tanpa memfilter baris baru nyata akan memerlukan status pelacakan: apakah baris sebelumnya maks-panjang atau tidak. Diperlukan lebih banyak kode atau pendekatan yang sama sekali berbeda.

[[ $r ]]lebih pendek dari [ -n "$r" ]yang diperlukan untuk menghindari kesalahan jika garis dimulai dengan -z foo, atau apakah *atau sesuatu, jika Anda digunakan [ $r ].

Pembenaran terjadi dengan string format printf "% 4s" standar printf.

Tes dengan

f()(while read -rn$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done); (echo 4; echo -e "*\n\\"; cat /tmp/lines) | f 4

1. Saya akan memasukkan -rdalam hitungan byte. 2. f()(while ... done)sedikit lebih pendek.
Dennis

@ Dennis: Tanpa [[ $r ]]&&, jika N = 4, garis input dengan panjang 4 akan menghasilkan garis output kosong di mana sebelumnya tidak ada. Karena readmengembalikan string 4 karakter, kemudian melihat baris baru pada panggilan berikutnya dan segera kembali. Juga, terima kasih atas ()tipnya. Saya tidak tahu Anda bisa mendefinisikan fns seperti itu.
Peter Cordes

Saya sarankan membaca Tips untuk bermain golf di Bash . Ini sumber yang bagus.
Dennis

Sebenarnya, karena whilesudah majemuk, Anda bahkan tidak perlu tanda kurung:f()while ... done
Dennis

@Dennis: wow, haxx. Terima kasih untuk tautannya. Beberapa hal baru bagi saya, dan saya memperbaiki beberapa hal di jawaban lain :) Saya biasanya tidak bermain golf, tetapi> 15 tahun menjadi pecandu baris perintah telah mengajarkan saya satu atau dua hal :)
Peter Cordes

2

Haskell, 108 byte

import Data.List.Split
k[]=[""]
k x=x
f n=unlines.(map(\l->([1..n-length l]>>" ")++l).k.chunksOf n=<<).lines

Contoh penggunaan:

*Main> putStr $ f 5 "a\n\nb\ncd\nMatamorphosis"
    a

    b
   cd
Matam
orpho
  sis

Bagaimana itu bekerja

                              .lines   -- split input string at newlines
                           =<<         -- for every line
                  chunksOf n           --    split into chunks of length n
                k                      --    fix empty lines
    map                                --    for every chunk
        \l->([1..n-length l]>>" "      --      make a string of missing spaces
                        ++l            --      and append the chunk
unlines                                -- join padded chunks with newlines in-between

1

GNU awk + bash, 70

f()(awk -vFPAT=.\{,$1} '{for(i=0;i++<NF;){printf "%'$1's\n",$i}}/^$/')

Menggunakan bash untuk memasukkan hitungan ke program awk adalah prob. lebih kecil dari membacanya dengan NR==1{N=$0}blok.

Baca satu baris pada satu waktu. Dibagi menjadi potongan karakter paling banyak, menggunakan FPAT. (cocok dengan bidang, bukan pemisah. Ekstensi GNU.) printf masing-masing bidang secara terpisah. (ORS Default = \ n).

The /^$/Aturan yang ada untuk mencetak baris kosong, yang memiliki NF = 0 dan dengan demikian tidak mencetak sama sekali di blok lain. Jadi tidak seperti solusi murni-bash saya, ini benar-benar berfungsi dalam kasus umum.

Semi-tidak terkait, tapi ide saya sejauh ini untuk perl adalah 112 karakter untuk kode perl:

(echo 4; echo -e 'foo\nbar'; echo -e "*\n\\"; echo '~$(true)'; cat /tmp/lines) |  # test input
perl -e '$N=<>;$/=\1;print "$N\n"; while(<>){if(/\n/ or length($l)>=$N){printf("%$4s\n",$l);$l=/\n/?"":$_;}else{$l.=$_;}}'

Ini memakan salah satu baris baru, dan terlalu lama. $/=\1membaca satu byte pada satu waktu. Kami menambahkan ke $ l. Mungkin garis-pada-saat-dengan pendekatan split-lebar tetap akan lebih pendek.


1

Utilitas Bash + GNU, 41

fold -$1|sed ":;s/^.\{,$[$1-1]\}\$/ &/;t"

String adalah input melalui STDIN, lebar adalah input oleh baris perintah arg:

ubuntu@ubuntu:~$ echo 'Programming
Puzzles
&
Code
Golf'|./ralign.sh 10
Programmin
         g
   Puzzles
         &
      Code
      Golf
ubuntu@ubuntu:~$

1

Python 2, 151 byte

s,n=input();N='\n'
for w in[i.lstrip()if i.replace(' ','').isalpha()else i for i in s.replace(N,'\n ').split(N)]:
 while w:print w[:n].rjust(n);w=w[n:]

Ini adalah adaptasi dari jawaban xnor di atas, karena ia tidak menangani baris baru dengan benar.


The forLoop diubah dari:

for w in s.split('\n'):

untuk:

for w in[i.lstrip()if i.replace(' ','').isalpha()else i for i in s.replace(N,'\n ').split(N)]:

Contoh

$ python main.py
"Programming\n\n\nPuzzles\n\n&\n\nCode\nGolf", 5
Progr
ammin
    g


Puzzl
   es

    &

 Code
 Golf

1

C #, 143 byte

(s,n)=>Join("\n",s.Split('\n').SelectMany(l=>(l.Any()?l:" ").Select((c,i)=>new{c,i}).GroupBy(o=>o.i/n,o=>o.c).Select(g=>Concat(g).PadLeft(n))))

Linq memungkinkan Anda membuat ekspresi yang cukup rumit. GroupByberguna di sini, tapi sayang sekali mereka tidak bisa membuat fungsi kelebihan mengambil indeks.

Tetapkan lambda ke a Func<string, int, string>untuk menjalankannya

Kurang bermain golf:

Func<string, int, string> Align = (s, n) => Join("\n", 
    s.Split('\n')
     .SelectMany(l => (l.Any() ? l : " ")
         .Select((c, i) => new { c, i })
         .GroupBy(o => o.i / n, o => o.c)
         .Select(g => Concat(g).PadLeft(n))));

1

Groovy, 63 byte

Mengembalikan string yang disesuaikan dengan benar. Tidak tahu ada fungsi padLeft (dan padRight, padCenter) sampai sekarang.

f={s,n->s.split("(?<=\\G.{$n})|\n")*.padLeft(n," ").join("\n")}

1

JavaScript 174 136

function R(s,x){return s.replace(new RegExp(".{"+x+"}","g"),"$&\n").replace(/[^\n]*/g,function(m){
while(m.length<x)m=" "+m;return m;})}

1

Ceylon, 107

String w(String s,Integer n)=>"\n".join{for(l in s.lines)for(p in l.partition(n))String(p).padLeading(n)};

1

Matlab, 99 byte

Terima kasih kepada @beaker karena menghapus 6 byte!

Menggunakan dan fungsi anonim:

@(s,k)fliplr(char(cellfun(@fliplr,strsplit(regexprep(s,sprintf('\\S{%i}',k),'$0\n'),'\n'),'un',0))) 

Tentukan fungsi dan gunakan ansuntuk menyebutnya:

>> @(s,k)fliplr(char(cellfun(@fliplr,strsplit(regexprep(s,sprintf('\\S{%i}',k),'$0\n'),'\n'),'un',0)))

ans =

@(s,k)fliplr(char(cellfun(@fliplr,strsplit(regexprep(s,sprintf('\\S{%i}',k),'$0\n'),'\n'),'un',0)))

>> ans(['Programming' 10 'Puzzles' 10 '&' 10 'Code' 10 'Golf'], 5) %% 10 is line feed

ans =

Progr
ammin
    g
Puzzl
   es
    &
 Code
 Golf

1

Burlesque, 28 Bytes

Sama seperti versi di bawah ini, tetapi memperlakukan baris 1 sebagai angka dan garis lainnya sebagai string.

lng_riPpun{pPco{pP' lp}mu}Wl

Penggunaan seperti pada:

$ cat input.txt | blsq --stdin "lng_riPpun{pPco{pP' lp}mu}Wl"
Progr
ammin
    g
Puzzl
   es
    &
 Code
 Golf

Versi Lama (16 byte):

{5co{5' lp}mu}Wl

Contoh:

blsq ) "Programming\nPuzzles\n&\nCode\nGolf"{5co{5' lp}mu}Wl
Progr
ammin
    g
Puzzl
   es
    &
 Code
 Golf
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.