Bu kod açıklamasını tekrar yapın


17

Giriş

Buradaki çoğu kod golfçüsü gönderimlerine açıklama eklediğinden neler olup bittiğini anlamak daha kolay. Genellikle kod dizileri sola gider ve ilgili açıklama bir tür ayırıcıyla sağa gider. Güzel görünmesi için ayırıcıların hepsi aynı sütundadır. Ayrıca uzun açıklama metni genellikle bir sonraki satıra sarılır, bu nedenle okuyucuların her şeyi okumak için yatay olarak kaydırmaları gerekmez.

Ancak, çılgın golfler yaptığınız için bu açıklamayı düzenlemek istediğinizde, genellikle açıklamanızı tekrar yapmak için zaman harcarsınız. Bu çok tekrarlayan bir görev olduğundan, bunun için bir program yazmak istiyorsunuz.

Meydan okuma

Açıklama ve ayırıcı içeren birkaç kod satırı verildiğinde, güzel biçimlendirilmiş kodu açıklama ile çıktılayın.

Misal

Giriş

shM-crz1dc4. "ANDBYOROF # z = giriş

     rz1 # girişi büyük harfe dönüştür
    boşluklarda cd # split girişi
         c4. "ANDBYOROF #, paketlenmiş bir dizeden yok sayılacak sözcüklerin bir listesini oluşturur
   - # bu kelimeleri filtrele
 hM # tüm kelimelerin sadece ilk harfini al
s # bunları tek bir dizede birleştir

Çıktı

shM-crz1dc4. "ANDBYOROF # z = giriş

     rz1 # girişi büyük harfe dönüştür
    boşluklarda cd # split girişi
         c4. "ANDBYOROF #, paketlenmiş bir dizeden gelen ve
                           # önemsenmedi
   - # bu kelimeleri filtrele
 hM # tüm kelimelerin sadece ilk harfini al
s # bunları tek bir dizede birleştir

Bu kodun ne yaptığını bulan ilk çerez için bir çerez.

Biçimlendirme algoritması

  • En uzun kod satırını bulun (açıklama ve kod ile ayırıcı arasındaki boşluklar hariç).
  • Bu kod satırından sonra 5 boşluk ekleyin ve ilgili ayırıcıyı açıklama ile ekleyin. Bu şimdi referans çizgisi.
  • Ayırıcıların tümü aynı sütunda olacak şekilde diğer her satırı bu referans çizgisine ayarlayın.
  • 93 karakterden uzun olan tüm satırları yeni bir satıra aşağıdaki şekilde kaydırın:
    • Sütun 93 veya altında olan son kelimeyi bulun.
    • Bundan sonra tüm kelimeleri alın ve onları önde gelen ayırıcı ve doğru boşluk ile yeni bir satıra sarın. Bu iki sözcük arasındaki boşluk silinmelidir, bu nedenle ilk satır bir sözcük karakteriyle biter ve ikinci satır ayırıcıdan sonra bir satırla başlar.
    • Ortaya çıkan satır hala 93 karakterden uzunsa, her satır 94 karakterin altına düşene kadar aynı işlemi tekrarlayın.

notlar

  • Bir kelime boşluk olmayan karakterlerden oluşur. Kelimeler tek bir boşlukla ayrılır.
  • Sözcük kaydırma her zaman mümkündür. Bu, hiçbir sözcüğün bu kadar uzun olmadığı, sargıyı imkansız kılacağı anlamına gelir.
  • Giriş yalnızca yazdırılabilir ASCII içerecek ve arka boşlukları olmayacak
  • Ayırıcı, her satırda yalnızca bir kez görünür.
  • Açıklama sınırsız uzunluğa sahip olsa da, ayırıcı ve kod yalnızca birleşik maksimum 93 - 5 = 87karakter uzunluğuna sahip olabilir . 5 karakter, kod ve ayırıcı arasındaki boşluklardır. Kod ve ayırıcı her zaman en az bir karakter uzunluğunda olacaktır.
  • Giriş boş satırlar içerebilir. Bunlar hiçbir zaman karakter içermeyecektir (girdiyi çok satırlı dize olarak alırsanız yeni satır hariç). Bu boş çizgiler çıktıda da bulunmalıdır.
  • Her satırın bir kodu, bir ayırıcısı ve bir açıklaması olacaktır. İstisnalar boş satırlardır.
  • Önceden işlenmediği sürece girdiyi makul bir biçimde alabilirsiniz. Cevabınızda hangisini kullandığınızı netleştirin.
  • Çıktı çok satırlı bir dize veya bir dize listesi olabilir.

kurallar

Test senaryoları

Buradaki girdi biçimi satırları temsil eden bir dize listesi ve ayırıcı için tek bir dize listesidir. Her ikisi de virgülle ayrılır. Çıktı dizelerin listesidir.

['shM-crz1dc4. "ANDBYOROF # z = girdi', '', 'rz1 # girdiyi büyük harfe dönüştür', 'boşluklarda cd # bölünmüş girdi', 'c4." ANDBYOROF # paketlenmiş kelimelerin bir listesini oluşturur ihmal edilecek dize ',' - # bu kelimeleri filtrele ',' hM # sadece tüm kelimelerin ilk harfini al ',' s # bunları tek bir dizeye birleştir '', "#" -> ['shM-crz1dc4 "ANDBYOROF # z = input ',' ',' rz1 # girdiyi büyük harfe dönüştür ',' cd # boşluklarda split girdi ',' c4." ANDBYOROF # paketlenmiş bir dizeden ' , '# önemsenmedi', '- # bu kelimeleri filtrele ',' hM # yalnızca tüm kelimelerin ilk harfini al ',' s # bir dizeye katıl ']
['codecodecode e # Explanation', 'sdf dsf sdf e # A Çok çok çok çok çok çok çok uzun uzun uzun uzun uzun uzun uzun uzun uzun uzun açıklama ve gittikçe uzamaya devam ediyor' ',' ', more codee # ve biraz daha açıklama '], "e #" -> [' codecodecode e # Explanation ',' sdf dsf sdf e # A Çok çok çok çok çok çok çok çok uzun uzun uzun uzun ',' e # uzun uzun uzun uzun uzun uzun açıklama devam ediyor 've' e # ve daha uzun ',' ',' biraz daha kod e # ve biraz daha açıklama ']

Mutlu Kodlama!


1
@Matt Tüm ayırıcılar daima sütundadır length of the longest code-line + 5. Bu, yalnızca açıklama içeren satırlara da uygulanmıştır, çünkü bunlar sarılmıştır.
Denker

Aman tanrım bunu son 3 saattir yanlış yapıyorum. Ben uzun kod sarmaya çalışıyordu ve açıklamaları uzun bırakarak ..... Peki baştan başlamak. En azından şimdi daha kolay. Teşekkürler. İyi ifade ettin .... Ben sadece aptalım.
Matt

93 karakterden uzun tüm satırları sarma Bu, önde gelen boşluklar da dahil olmak üzere kodun hiçbir zaman 87 karakterden uzun olmayacağı anlamına mı geliyor?
Mat

@Matt Kod ve ayırıcı birlikte 87 karakterden daha uzun olmayacaktır, çünkü kod ve ayırıcı arasında 5 boşluk ve açıklama için bir karakter gerekir.
Denker

1
Pyth kodu herhangi bir dizenin kısaltmasını bulur. Biliyordum çünkü bu sorumun cevabıydı.
Aplet123

Yanıtlar:


3

Yakut, 245 237 220 216 212 209 205 bayt

Anonim işlev. Oldukça basit bir yaklaşım (maksimum uzunluğu bulun, 5 ekleyin, ardından her satırda, sarma ile başa çıkmak için özyineleme ile işleme yapın) ve daha fazla bayt tasarrufu sağlayan başka bir yaklaşım olabilir.

Daha önce tüm gereksinimleri karşılamayan cevabı sildim; Ben bir cevap olarak yarı cevaplanmış bir kod var istemiyordu (o da eksik olduğu için downvotes alıyordum) ama sorunun şimdi sorduğu her şeyi yapmalı.

->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}*"
"}

Değişiklikler:

  • Girdideki bazı vaatlerden, özellikle de tüm boş olmayan satırların ayırıcı karaktere ve bir açıklamaya sahip olduğu vaadinden yararlanarak bazı baytlar kurtardı.
  • Bölünmüş dizeleri ilkinden kaydederek biraz daha golf oynamayı başardı map çağrıdanstrip ve açıklamadaki kelimelerin aralarında her zaman tam olarak bir boşluk olduğu vaadine dayanarak bazı gereksiz işlevler alarak golfü biraz daha yönetti . Ayrıca, " "çok kullandığımdan beri artık bir sabite atanmış durumda.
  • Her ikisini de zincirleme mapÜst düzey işlevlerin gücünden yararlanarak çağrıyı birlikte , yani ilk harita çağrısı uzunluk değişkenini ayarlayacaktırl , yardımcı işlev bildirildikten sonra çağrılsa bile doğrus . -4 bayt.
  • \nGerçek satırlarla değiştirmek için kötüye kullanılan çok satırlı dizeler , ayrıca küçük bir numaraif üçlü operatörler üzerinde ( değerlere joinsahip bir dizide çağrıldığında nilboş dizeler haline gelir)
  • .joingörünüşe göre a ile değiştirilebilir *.

Şimdi düzeltilmesi gerektiğini düşünüyorum?
Değer Mürekkebi

bu 94'te nasıl sarılır?
Ven

Tamam, şimdi kod üzerinde çalışmak için daha fazla zamanım olduğu için, düzgün bir şekilde sarar.
Değer Mürekkebi

"Açıklama sınırsız uzunluğa sahip olsa da, ayırıcı ve kod yalnızca birleşik maksimum 93 - 5 = 87karakter uzunluğuna sahip olabilir . 5 karakter, kod ve ayırıcı arasındaki boşluklardır. Kod ve ayırıcı her zaman en az bir karakter uzunluğunda olacaktır." Kod bölümünüz, 97 karakterle sınırı aşmıştır, bu nedenle programın tanımlanmamış davranışı vardır.
Değer Mürekkebi

ah, iyi tespit, mantıklı!
Ven

9

LiveScript, 243 236 233 228 219 225 bayt

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

Nasıl çalışır: çoğunlukla Java kodu gibi. Uzunluk takma adı ile başlayın (LiveScript, parantez kullanarak işleçlerden bir işlev oluşturmanıza olanak tanır). .=olduğunu a = a.b- biz haritaya Burada kullandığımız hangi.

=> blabla ..Smalltalk-ish kaskad yapısıdır: sol tarafına bloğun geri kalanında =>olduğu gibi erişilebilir ..; ve iade edilecektir. Burada, k üzerine bölünmüş element. Not: Dize enterpolasyonu kullanıyorum, çünkü /sadece değişmez bir dize ile "bölünmüş" anlamına geliyor.

LS a-=/regexp/bu lambda'da da kullanmamıza izin veriyor (aynı zamanda string değişmezleriyle de çalışıyor): sadece bir .replacearama için şeker .

Son olarak, iki işlenenden daha fazlasını döndüren >?=kombinator >?-assin operatörüdür.

LS, Python / Haskell tarzına sahiptir. İçinde yeterince uzun bir süre tekrarlamak için "string * times" dışında hiçbir şey yoktur.

Anlama için bu konu olarak hizmet eder (kaskadlar ile ilgili bloğa bakınız).

Daha sonra dizinin her bir elementine (kavrama ile yeni oluşturduğumuz) döngüye gireriz ve herhangi bir çizgi 93 karakterden büyükse, son dizini bulur, oraya böleriz ve ayrılan çizgiyi bu mevcut yinelemeden hemen sonra ( ... Böylece satır çok büyükse bir sonraki yineleme tekrar bölünecektir).

Sadece son şey fantezi a[j to](j sonuna kadar) bir aralık, ama Dizi yöntemler kullanır beri biz aşırı kullanarak hangi, geri dizeye katılmak zorunda *: *''.

misal

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

çıktı:

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

1
kim indirilmişse ona: cevap sabittir.
Ven

2
Bir açıklama taştığında, ayırıcı karakterlerini diğer IIRC ile hizalamak için yeni satırlara ihtiyacınız vardır.
Değer Mürekkebi

@KevinLau iyi tespit, sabit!
Ven

Örnek çıktınızı da güncelleyebilir misiniz?
Değer Mürekkebi

@KevinLau bitti.
Ven

6

Java, 347 + 19 = 366 bayt

gerektirir

import java.util.*;

Böylece +19 bayt.

(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);}}

Biçiminde alır f.accept(List<String> code, String seperator). Yerinde biçimler. Yeni bir sürüm oluşturan ve döndüren bir sürümün List<String>uygulanması önemsizdir ancak bazı baytlara mal olur.

Girintili + örnek kullanım:

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);
}

... muhtemelen bunu kendi başıma yapmalıyım: P


Eğer kimse neden replace(" *"+s)çalışmadığını anlayabiliyorsa ama replaceAll(" *"+s)duymak ister miyim - anlayamıyorum .
CAD97

<badguess> replacedizeleri replaceAllkullanır , ancak normal ifadeleri kullanır. </badguess>
CalculatorFeline

@CatsAreFluffy iyi, haklısın ! Bunu nasıl fark etmediğimi bilmiyorum: P
CAD97

Yeni satırı kaldıramaz mısınız?
CalculatorFeline

Peki yeni satır gerekli yarı nedeniyle kaldırılabilir: s (.s ama ne olursa olsun olmalı)
CalculatorFeline

2

PowerShell, 224 217 235 bayt

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}

Maksimum kod dizesi uzunluğunu belirlemek için mantık güncellendi. Normal ifade meta karakterlerini içeren birden çok ayırıcıya izin verecek şekilde güncellendi.


Küçük Açıklama

Bu, girdi için tüm yeni satırla ayrılmış bir dizeyi alır.

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
}

Bazı Lorem Ipsum ile Örnek Çıktı

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

@nimi Umarım güncellemeler artık daha iyi bir çözüm sağlıyor.
Matt

@nimi Yanlış fark ettiğiniz başka bir şey var mı? Görünüşe göre son birkaç günü okurken sorun yaşıyorum.
Matt

Hayır. Şimdi +1.
nimi

1

MATLAB, 270 265 262 bayt

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, girdiyi I, hücre dizisinin her elemanının girişin ayrı bir satırı olduğu bir dizeler hücre dizisi biçiminde kabul eder . Ayrıca, yorum karakterinin (yani #) ne olduğunu gösteren ikinci bir girişi de kabul eder . İşlev, düzgün biçimlendirilmiş çok satırlı bir dize döndürür.

Kısa açıklama

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

Örnek Giriş

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,'#'));

Örnek Çıktı

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.