Buat penjelasan kode ini lagi cantik

17

pengantar

Sebagian besar pegolf kode di sini menambahkan penjelasan pada kiriman mereka, jadi lebih mudah untuk memahami apa yang terjadi. Biasanya codelines pergi ke kiri dan penjelasan yang sesuai ke kanan dengan semacam pemisah. Agar terlihat cantik, pemisah semua berada di kolom yang sama. Juga teks penjelasan panjang biasanya dibungkus ke baris berikutnya, sehingga pembaca tidak harus menggulir secara horizontal untuk membaca semuanya.

Namun, ketika Anda ingin mengedit penjelasan ini karena Anda membuat beberapa golf gila, Anda sering menghabiskan waktu untuk membuat penjelasan Anda lagi. Karena ini adalah tugas yang sangat berulang, Anda ingin menulis sebuah program untuk ini.

Tantangan

Diberikan beberapa baris kode dengan penjelasan dan pemisah, menampilkan kode yang diformat dengan baik dengan penjelasan.

Contoh

Memasukkan

shM-crz1dc4. "ANDBYOROF # z = input

     rz1 # ubah input menjadi huruf besar
    masukan masukan cd # pada spasi
         c4. "ANDBYOROF # membuat daftar kata - kata dari string yang dikemas yang akan diabaikan
   - # saring kata-kata itu
 hM # hanya mengambil huruf pertama dari semua kata
s # gabungkan mereka menjadi satu string

Keluaran

shM-crz1dc4. "ANDBYOROF # z = input

     rz1 # ubah input menjadi huruf besar
    masukan masukan cd # pada spasi
         c4. "ANDBYOROF # membuat daftar kata - kata dari string yang dikemas
                           # diabaikan
   - # saring kata-kata itu
 hM # hanya mengambil huruf pertama dari semua kata
s # gabungkan mereka menjadi satu string

Satu cookie untuk yang pertama yang bisa mengetahui apa yang dilakukan kode ini.

Algoritma pemformatan

  • Temukan baris kode terpanjang (tidak termasuk penjelasan dan spasi antara kode dan pemisah).
  • Tambahkan 5 spasi setelah baris kode ini dan tambahkan pemisah yang sesuai dengan penjelasan. Sekarang ini adalah garis referensi.
  • Sesuaikan setiap baris lain ke baris referensi ini, sehingga pemisah semua berada di kolom yang sama.
  • Bungkus semua baris yang lebih panjang dari 93 karakter ke baris baru dengan cara berikut:
    • Temukan kata terakhir yang ujungnya ada di kolom 93 atau lebih rendah.
    • Ambil semua kata setelah ini dan bungkus ke baris baru dengan pemisah utama dan spasi yang benar. Ruang antara kedua kata tersebut harus dihapus, sehingga baris pertama diakhiri dengan karakter kata dan baris kedua dimulai dengan satu setelah pemisah.
    • Jika baris yang dihasilkan masih lebih dari 93 karakter, lakukan hal yang sama lagi sampai setiap baris di bawah 94 karakter.

Catatan

  • Sebuah kata terdiri dari karakter yang bukan spasi. Kata-kata dipisahkan oleh satu ruang.
  • Pembungkus kata selalu memungkinkan. Ini berarti bahwa tidak ada kata yang terlalu panjang sehingga tidak memungkinkan pembungkusnya.
  • Input hanya akan berisi ASCII yang dapat dicetak dan tidak akan memiliki spasi spasi tambahan
  • Pemisah hanya akan muncul sekali per baris.
  • Sementara penjelasan dapat memiliki panjang tidak terbatas, pemisah dan kode hanya dapat memiliki panjang 93 - 5 = 87karakter maksimum gabungan . 5 karakter adalah spasi antara kode dan pemisah. Panjang kode dan pemisah akan selalu setidaknya satu karakter.
  • Input mungkin berisi baris kosong. Itu tidak akan mengandung karakter apa pun (kecuali baris baru jika Anda mengambil input sebagai string multiline). Baris-baris kosong itu juga harus ada di output.
  • Setiap baris akan memiliki beberapa kode, pemisah, dan penjelasan. Pengecualian adalah baris kosong.
  • Anda dapat mengambil input dalam format apa pun yang wajar, asalkan tidak diproses terlebih dahulu. Jelaskan dalam jawaban Anda mana yang Anda gunakan.
  • Output dapat berupa string multiline atau daftar string.

Aturan

  • Fungsi atau program lengkap diizinkan.
  • Aturan default untuk input / output.
  • Celah standar berlaku.
  • Ini adalah , sehingga byte-count terendah akan menang. Tiebreak adalah pengiriman sebelumnya.

Uji kasus

Format input di sini adalah daftar string yang mewakili garis dan string tunggal untuk pemisah. Keduanya dipisahkan oleh koma. Output adalah daftar string.

['shM-crz1dc4. "ANDBYOROF # z = input', '', 'rz1 # konversikan input ke huruf besar', 'cd # split input pada spasi', 'c4." ANDBYOROF # buat daftar kata dari paket. string yang harus diabaikan ',' - # saring kata-kata itu ',' hM # hanya mengambil huruf pertama dari semua kata ',' s # gabung menjadi satu string '], "#" -> [' shM-crz1dc4 . "ANDBYOROF # z = input ',' ',' rz1 # konversikan input ke huruf besar ',' cd # pisahkan input pada spasi ',' c4." ANDBYOROF # buat daftar kata dari string yang dikemas yang harus ' , '# diabaikan', '- # filter kata-kata itu ',' hM # hanya ambil huruf pertama dari semua kata ',' s # gabung menjadi satu string ']
['codecodecode e # Penjelasan', 'sdf dsf sdf e # A Sangat sangat sangat sangat sangat sangat sangat sangat sangat sangat lama sangat lama sangat lama sangat panjang sangat lama sangat lama penjelasan panjang dan itu terus semakin lama', '', 'beberapa lebih banyak codee # dan lebih banyak penjelasan '], "e #" -> [' codecodecode e # Penjelasan ',' sdf dsf sdf e # A Sangat sangat sangat sangat sangat sangat sangat sangat sangat sangat sangat sangat lama sangat lama sangat lama ',' e # panjang panjang penjelasan panjang dan panjang terus bertambah ',' e # dan lebih lama ',' ',' beberapa kode lagi e # dan beberapa penjelasan lainnya ']

Selamat Coding!

Denker
sumber
1
@ Mat Semua pemisah selalu ada di kolom length of the longest code-line + 5. Ini juga berlaku untuk garis yang hanya berisi penjelasan, karena dibungkus.
Denker
Ya Tuhan, saya telah melakukan kesalahan ini selama 3 jam terakhir. Saya mencoba untuk membungkus kode panjang dan meninggalkan penjelasan panjang ..... Yah memulai kembali. Setidaknya sekarang lebih mudah. Terima kasih. Anda mengatakannya baik-baik saja .... Saya hanya konyol.
Matt
Bungkus semua baris yang lebih panjang dari 93 karakter. Apakah itu berarti kode, termasuk spasi, tidak akan pernah lebih dari 87 karakter?
Matt
@Matt Kode dan pemisah bersama tidak akan pernah lebih dari 87 karakter karena kita membutuhkan 5 spasi antara kode dan pemisah dan satu karakter untuk penjelasan.
Denker
1
Kode Pyth menemukan singkatan dari string yang diberikan. Saya akan tahu karena itu adalah jawaban untuk pertanyaan saya.
Aplet123

Jawaban:

3

Ruby, 245 237 220 216 212 209 205 byte

Fungsi anonim. Pendekatan yang cukup mendasar (temukan panjang maks, tambah 5, lalu lakukan pemrosesan pada setiap baris, dengan rekursi untuk menangani pembungkus) dan mungkin ada pendekatan lain yang menyimpan lebih banyak byte.

Saya menghapus jawaban sebelumnya yang tidak memenuhi semua persyaratan; Saya tidak ingin memiliki kode setengah-dijawab sebagai jawaban (sudah mendapatkan downvotes karena tidak lengkap juga) tetapi harus melakukan semua pertanyaan yang ditanyakan, sekarang.

->x,d{l,S=0," "
s=->n{m,q=n.size,94-l-d.size
m>q ?(i=n.rindex(S,q)
n[0,i]+"
"+S*l+d+s[n[i+1,m]]):n}
x.map{|n|c,t=n.split d
c=(c||S).rstrip
l=[l,5+c.size].max
[c,t]}.map{|c,t|c+S*(l-c.size)+d+s[t]if t}*"
"}

Changelog:

  • Menyimpan beberapa byte dengan memanfaatkan beberapa janji dalam input, terutama janji bahwa semua baris yang tidak kosong memiliki karakter pemisah dan penjelasan.
  • Berhasil bermain golf sedikit lebih banyak dengan menyimpan string yang terpisah dari mappanggilan pertama dan mengeluarkan beberapa stripfungsi yang tidak perlu berdasarkan janji bahwa kata-kata dalam penjelasan selalu memiliki satu ruang di antara mereka. Juga, " "ditugaskan ke konstanta sekarang karena saya banyak menggunakannya.
  • Dirantai keduanya map panggilan bersama dengan memanfaatkan kekuatan fungsi tingkat tinggi, yang berarti bahwa panggilan peta pertama akan mengatur variabel panjang ldengan benar bahkan jika itu dipanggil setelah deklarasi fungsi helper s. -4 byte.
  • String multiline yang disalahgunakan untuk menggantikan \ndengan baris baru yang sebenarnya, ditambah sedikit trik menggunakan iflebih dari operator ternary (kapanjoin dipanggil pada array dengan nilnilai, mereka menjadi string kosong)
  • .jointernyata bisa diganti dengan a *.
Nilai Tinta
sumber
Saya pikir itu harus diperbaiki sekarang?
Nilai Tinta
bagaimana bungkus ini di 94?
Ven
Baiklah, sekarang saya punya lebih banyak waktu untuk mengerjakan kode, ia membungkus dengan benar.
Nilai Tinta
"Walaupun penjelasannya dapat memiliki panjang yang tidak terbatas, pemisah dan kode hanya dapat memiliki panjang 93 - 5 = 87karakter maksimum gabungan . Lima karakter adalah spasi antara kode dan pemisah. Kode dan pemisah akan selalu setidaknya sepanjang satu karakter." Bagian kode Anda melewati batas, dengan 97 karakter, sehingga program memiliki perilaku yang tidak ditentukan.
Nilai Tinta
ah, terlihat dengan baik, masuk akal!
Ven
9

LiveScript, 243 236 233 228 219 225 byte

f = (x,k,m+5)->l=(.length);x.=map(->it/"#k"=>..0-=/ +$/;m>?=5+l ..0);i=0;[..0&&..0+' '*(m- l ..0)+k+..1 for x]=>while i<(l ..),++i=>j=(s=..[i])lastIndexOf ' ' 93;(..splice i+1 0 ' '*m+k+s[j to]*'';s.=substr 0 j) if 94<l s;..[i]=s

Cara kerjanya: kebanyakan seperti kode Java. Mulai dengan aliasing length (LiveScript memungkinkan untuk membuat fungsi dari operator dengan menggunakan tanda kurung). .=adalah a = a.b- yang kami gunakan di sini untuk memetakan.

=> blabla ..adalah konstruksi kaskade Smalltalk-ish: sisi kiri =>dapat diakses seperti ..untuk sisa blok; dan akan dikembalikan. Di sini, itu adalah elemen yang dibagi pada k. Catatan: Saya menggunakan interpolasi string, karena /hanya berarti "split" dengan string literal.

LS memungkinkan kita untuk menggunakan a-=/regexp/lambda ini (juga bekerja dengan string literal): itu hanya gula untuk .replacepanggilan.

Akhirnya, >?=adalah >?operator -assin kombinasi , yang mengembalikan lebih besar dari dua operan.

LS memiliki gaya Python / Haskell untuk pemahaman, dengan tidak ada yang mewah di dalamnya, kecuali "string * times" untuk mengulang ruang cukup lama.

Ini untuk pemahaman berfungsi sebagai topik (lihat blok tentang kaskade anove).

Kami kemudian loop ke setiap elemen array (yang kami baru saja membangun dengan pemahaman), dan jika ada garis yang lebih besar dari 93char, kami menemukan indeks terakhir, terbagi di sana, dan mendorong garis yang dipisahkan tepat setelah iterasi saat ini ( ... Sehingga iterasi berikutnya akan terpecah lagi jika garis terlalu besar).

Hanya hal terakhir yang disukai a[j to]adalah rentang (dari j hingga akhir), tetapi karena menggunakan metode Array kita harus menggabungkannya kembali ke string, yang kita lakukan menggunakan overloaded* : *''.

contoh

s = """this is kod # Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
d # y

efgh # z"""

f = (x,k,m=5)->l=(.length);x.=map(->it/"#k"=>..0-=/ +$/;m>?=5+l ..0);i=0;[..0&&..0+' '*(m- l ..0)+k+..1 for x]=>while i<(l ..),++i=>j=(s=..[i])lastIndexOf ' ' 93;(..splice i+1 0 ' '*m+k+s[j to]*'';s.=substr 0 j) if 94<l s;..[i]=s

console.log (f s / '\n', '#') * \\n

keluaran:

this is kod     # Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
                # tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
                # veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
                # commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
                # velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
                # cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
                # est laborum.
d               # y

efgh            # z
Yang Mulia
sumber
1
untuk siapa pun yang diturunkan: jawabannya sudah pasti.
Ven
2
Saat penjelasan meluap, Anda perlu baris baru untuk menyelaraskan karakter pemisahnya dengan yang lain, IIRC.
Nilai Tinta
@KevinLau terlihat dengan baik, diperbaiki!
Ven
Bisakah Anda memperbarui contoh output Anda juga?
Nilai Tinta
@KevinLau selesai.
Ven
6

Java, 347 + 19 = 366 byte

Membutuhkan

import java.util.*;

Demikianlah +19 byte.

(c,s)->{int p=0,i=0,t;String l;for(;i<c.size();i++){l=c.get(i);l=l.replaceAll(" *"+s,s);p=Math.max(l.indexOf(s),p);c.set(i,l);}p+=5;for(i=0;i<c.size();i++){l=c.get(i);t=l.indexOf(s);while(t>-1&t<p)l=l.substring(0,t)+" "+l.substring(t++);t=93;if(l.length()>t){while(l.charAt(t)!=' ')t--;c.add(i+1,s+l.substring(t));l=l.substring(0,t);}c.set(i,l);}}

Mengambil dalam format f.accept(List<String> code, String seperator). Format di tempat. Versi yang membuat dan mengembalikan yang baru List<String>mungkin sepele untuk diimplementasikan tetapi perlu biaya beberapa byte.

Indentasi + contoh penggunaan:

static BiConsumer<List<String>, String> prettify = (code, seperator) -> {
    int space = 0, i=0, t;
    String line;
    for (; i<code.size(); i++) { // for each line
        line = code.get(i); // get line
        line = line.replaceAll(" *" + seperator, seperator); // strip space before seperator
        space = Math.max(line.indexOf(seperator), space); // save biggest space until seperator
        code.set(i, line); // save line
    }
    space += 5;
    for (i=0; i<code.size(); i++) { // for each line
        line = code.get(i); // get line
        t = line.indexOf(seperator); // get index of seperator
        while (t>-1&t<space) // while the seperator exists and is further left than desired
            line = line.substring(0,t) + " " + line.substring(t++); // move it right by adding a space before it
        t = 93; // get desired line length
        if (line.length()>t) { // if the line is longer than that
            while (line.charAt(t)!=' ') t--; // scan backwards for a space
            code.add(i+1, seperator + line.substring(t)); // add a line after this one with seperator and the rest of the line
                                                          // the next pass will space it correctly
            line = line.substring(0,t); // cut off this line at that point
        }
        code.set(i, line); // save edited line back to List
    }
};

public static void main(String[] args) {
    List<String> code = new ArrayList<>();
    code.add("shM-crz1dc4.\"ANDBYOROF  # z = input");
    code.add("");
    code.add("     rz1      # convert input to uppercase");
    code.add("    c   d        # split input on spaces");
    code.add("         c4.\"ANDBYOROF        # create a list of the words from a packed string which shall be ignored");
    code.add("   -          # filter those words out");
    code.add(" hM                # only take the first letter of all words");
    code.add("s                   # join them into one string");
    prettify.accept(code, "#");
    code.stream().forEach(System.out::println);
}

... Saya mungkin harus menjalankan ini sendiri: P

CAD97
sumber
Jika ada yang tahu mengapa replace(" *"+s)tidak berhasil tapi replaceAll(" *"+s)apakah saya ingin mendengarnya - saya tidak bisa mengetahuinya.
CAD97
<badguess> replacemenggunakan string tetapi replaceAllmenggunakan regex. </badguess>
CalculatorFeline
@CatsAreFluffy, Anda benar ! Tidak tahu bagaimana saya tidak menyadarinya: P
CAD97
Tidak bisakah Anda menghapus baris baru?
CalculatorFeline
Nah baris baru dapat dihapus karena diperlukan semi: s (yang seharusnya .s tapi apa pun)
CalculatorFeline
2

PowerShell, 224 217 235 byte

param($d,$s)$d=$d-split"`r`n";$p="\s+\$([char[]]$s-join"\")\s";$m=($d|%{($_-split$p)[0].Length}|sort)[-1];$d|%{$l,$c=$_-split$p;$c=if($c){"$s "+(("$c "-split"(.{1,$(87-$m)})\s"|?{$_})-join"`n$(" "*($m+5))$s ")}$l.PadRight($m+5," ")+$c}

Memperbarui logika untuk menentukan panjang string kode maks. Diperbarui untuk memungkinkan beberapa pemisah yang menyertakan karakter meta regex.


Penjelasan Kecil

Ini membutuhkan keseluruhan string baris baru untuk input.

param($d,$s)
# $d is a newline delimited string. $s is the separator.
# Take the string and turn it into a string array. Stored as $d
$d=$d-split"`r`n"
# Save a regex pattern as it is used more than once
$p="\s+\$([char[]]$s-join"\")\s"
# Get the longest string of code's length
$m=($d|%{($_-split$p)[0].Length}|sort)[-1]
# Split each line again into code and comment. Write out each line with formatted explanations based on separator column position $m
$d|%{
# Split the line
$l,$c=$_-split$p
# Build the comment string assuming there is one.
$c=if($c){"$s "+(("$c "-split"(.{1,$(87-$m)})\s"|?{$_})-join"`n$(" "*($m+5))$s ")}
# Pad the right amount of space on the code and add the comment string.
$l.PadRight($m+5," ")+$c
}

Contoh Output dengan beberapa Lorem Ipsum

shM-crz1dc4."ANDBYOROF     # z = input

     rz1                   # convert input to uppercase
    c   d                  # split input on spaces
         c4."ANDBYOROF     # But I must explain to you how all this mistaken idea of
                           # denouncing pleasure and praising pain was born and I will give
                           # you a complete account of the system, and expound the actual
                           # teachings of the great explorer
   -                       # filter those words out
 hM                        # only take the first letter of all words
s                          # join them into one string
Mat
sumber
@nimi Semoga pembaruan sekarang menjadi solusi yang lebih baik.
Matt
@nimi Ada lagi yang salah? Tampaknya saya mengalami masalah membaca beberapa hari terakhir.
Matt
Tidak. Sekarang punya +1.
nimi
1

MATLAB, 270 265 262 byte

function d=f(I,s);S=@sprintf;R=@regexprep;m=regexp(I,['\s*\',s]);L=max([m{:}])+4;a=@(x)S('%-*s%s',L,x,s);b=@(x)R(R(x,S('(.{1,%d}(\\s+|$))',93-L),S('$1\n%*s ',L+1,s)),['\n\s*\',s,' $'],'');c=R(I,['(.*?)\s*\',s,'\s*(.*$)'],'${a($1)} ${b($2)}');d=S('%s\n',c{:});end

Program menerima input Idalam bentuk array sel string di mana setiap elemen array sel adalah baris input yang terpisah. Itu juga menerima input kedua yang menunjukkan apa karakter komentar (yaitu #). Fungsi mengembalikan string multi-line yang diformat dengan benar.

Penjelasan singkat

function d = f(I,s)
    %// Setup some shortcuts for commonly-used functions
    S = @sprintf;
    R = @regexprep;

    %// Find the location of the space AFTER each code block but before a comment
    m = regexp(I, ['\s*\',s]);

    %// Compute the maximum column location of the code and add 4 (5 - 1)
    L = max([m{:}]) + 4;

    %// This is a callback for when we detect code
    %// It left justifies and pads the string to L width
    a = @(x)S('%-*s%s', L, x, s);

    %// This is a callback for when we detect a comment.
    b = @(x)R(...
            R(x, ...
                S('(.{1,%d}(\\s|$))', 93 - L), ... Regex for wrapping text to desired width
                S('$1\n%*s ', L+1, s)), ... Append a newline and padding for next line 
            ['\n\s*\',s,' $'], ''); ... Remove the trailing newline (to be improved)

    %// Perform replacement of everything.
    c = R(I, ...
            ['(.*?)\s*\',s,'\s*(.*$)'], ... Match "code comment_char comment"
            '${a($1)} ${b($2)}');   ... Replace using the output of the callbacks

    %// Concatenate all of the strings together with a newline in between
    d=S('%s\n',c{:});
end

Contoh Input

I = {
    'shM-crz1dc4."ANDBYOROF  # z = input'
    ''
    '     rz1      # convert input to uppercase'
    '    c   d        # split input on spaces'
    '         c4."ANDBYOROF        # create a list of the words from a packed string which shall be ignored'
    '   -          # filter those words out'
    ' hM                # only take the first letter of all words'
    's                   # join them into one string'
};

disp(f(I,'#'));

Contoh Output

shM-crz1dc4."ANDBYOROF     # z = input

     rz1                   # convert input to uppercase
    c   d                  # split input on spaces
         c4."ANDBYOROF     # create a list of the words from a packed string which shall be
                           # ignored
   -                       # filter those words out
 hM                        # only take the first letter of all words
s                          # join them into one string
Suever
sumber