Làm cho mã này giải thích lại một lần nữa


17

Giới thiệu

Hầu hết những người chơi mã ở đây thêm giải thích cho bài nộp của họ, vì vậy sẽ dễ hiểu hơn những gì đang diễn ra. Thông thường các codelines đi bên trái và giải thích tương ứng bên phải với một số loại dấu phân cách. Để làm cho nó trông đẹp, các dấu phân cách đều nằm trên cùng một cột. Ngoài ra văn bản giải thích dài thường được gói sang dòng tiếp theo, vì vậy người đọc không phải cuộn theo chiều ngang để đọc mọi thứ.

Tuy nhiên, khi bạn muốn chỉnh sửa lời giải thích này vì bạn đã tạo ra một số golf điên, cuối cùng bạn thường dành thời gian để làm cho lời giải thích của bạn trở lại đẹp hơn. Vì đây là một nhiệm vụ rất lặp đi lặp lại, bạn muốn viết một chương trình cho việc này.

Các thách thức

Đưa ra một vài dòng mã với lời giải thích và một dấu phân cách, xuất mã được định dạng độc đáo với lời giải thích.

Thí dụ

Đầu vào

shM-crz1dc4. "ANDBYOROF # z = đầu vào

     rz1 # chuyển đổi đầu vào thành chữ hoa
    đầu vào phân chia cd # trên dấu cách
         c4. "ANDBYOROF # tạo danh sách các từ trong chuỗi được đóng gói sẽ bị bỏ qua
   - # lọc những từ đó ra
 hM # chỉ lấy chữ cái đầu tiên của tất cả các từ
s # nối chúng thành một chuỗi

Đầu ra

shM-crz1dc4. "ANDBYOROF # z = đầu vào

     rz1 # chuyển đổi đầu vào thành chữ hoa
    đầu vào phân chia cd # trên dấu cách
         c4. "ANDBYOROF # tạo danh sách các từ trong chuỗi được đóng gói sẽ là
                           # mặc kệ
   - # lọc những từ đó ra
 hM # chỉ lấy chữ cái đầu tiên của tất cả các từ
s # nối chúng thành một chuỗi

Một cookie cho người đầu tiên có thể tìm ra mã này làm gì.

Thuật toán định dạng

  • Tìm dòng mã dài nhất (không bao gồm phần giải thích và khoảng trắng giữa mã và dấu phân cách).
  • Thêm 5 khoảng trắng sau dòng mã này và nối thêm dấu phân cách tương ứng. Đây là dòng tham khảo.
  • Điều chỉnh mọi dòng khác cho dòng tham chiếu này, sao cho tất cả các bộ tách biệt đều nằm trong cùng một cột.
  • Bao bọc tất cả các dòng dài hơn 93 ký tự thành một dòng mới theo cách sau:
    • Tìm từ cuối cùng ở cuối cột 93 hoặc thấp hơn.
    • Lấy tất cả các từ sau cái này và bọc chúng vào một dòng mới với dấu phân cách hàng đầu và khoảng cách chính xác. Không gian giữa hai từ đó phải được xóa, vì vậy dòng đầu tiên kết thúc bằng một ký tự từ và dòng thứ hai bắt đầu bằng một từ sau dấu phân cách.
    • Nếu dòng kết quả vẫn dài hơn 93 ký tự thì thực hiện lại cho đến khi mỗi dòng dưới 94 ký tự.

Ghi chú

  • Một từ bao gồm các ký tự không phải khoảng trắng. Các từ được phân tách bằng một khoảng trắng.
  • Việc gói từ luôn luôn có thể. Điều này có nghĩa là không có từ nào dài đến mức nó sẽ làm cho việc gói không thể thực hiện được.
  • Đầu vào sẽ chỉ chứa ASCII có thể in và sẽ không có bất kỳ khoảng trắng nào
  • Dấu phân cách sẽ chỉ xuất hiện một lần trên mỗi dòng.
  • Trong khi lời giải thích có thể có độ dài không giới hạn, dấu phân cách và mã chỉ có thể có độ dài tối đa kết hợp của 93 - 5 = 87ký tự. 5 ký tự là khoảng cách giữa mã và dấu phân cách. Mã và dấu phân cách sẽ luôn dài ít nhất một ký tự.
  • Đầu vào có thể chứa các dòng trống. Chúng sẽ không bao giờ chứa bất kỳ ký tự nào (ngoại trừ một dòng mới nếu bạn lấy đầu vào dưới dạng chuỗi nhiều dòng). Những dòng trống đó cũng phải có mặt trong đầu ra.
  • Mỗi dòng sẽ có một số mã, một dấu phân tách và một lời giải thích. Ngoại lệ là các dòng trống.
  • Bạn có thể lấy đầu vào ở bất kỳ định dạng hợp lý nào, miễn là nó không được xử lý trước. Làm cho nó rõ ràng trong câu trả lời của bạn mà bạn sử dụng.
  • Đầu ra có thể là một chuỗi nhiều dòng hoặc một danh sách các chuỗi.

Quy tắc

Các trường hợp thử nghiệm

Định dạng đầu vào ở đây là danh sách các chuỗi biểu thị các dòng và một chuỗi đơn cho dấu phân cách. Cả hai được phân tách bằng dấu phẩy. Đầu ra là một danh sách các chuỗi.

['shM-crz1dc4. "ANDBYOROF # z = input', '', 'rz1 # chuyển đổi đầu vào thành chữ hoa', 'cd # split input on space', 'c4." ANDBYOROF # tạo danh sách các từ từ được đóng gói chuỗi sẽ bị bỏ qua ',' - # lọc các từ đó ra ',' hM # chỉ lấy chữ cái đầu tiên của tất cả các từ ',' s # nối chúng thành một chuỗi '], "#" -> [' shM-crz1dc4 . "ANDBYOROF # z = input ',' ',' rz1 # chuyển đổi đầu vào thành chữ hoa ',' cd # split input on space ',' c4." ANDBYOROF # tạo danh sách các từ từ một chuỗi được đóng gói sẽ là ' , ' # mặc kệ', '- # lọc những từ đó ra ',' hM # chỉ lấy chữ cái đầu tiên của tất cả các từ ',' s # nối chúng thành một chuỗi ']
['Cododecode e # Giải thích', 'sdf dsf sdf e # A Rất rất rất rất rất rất rất dài rất dài dài dài dài dài dài giải thích dài và nó cứ ngày càng dài hơn', '', 'một số thêm codee # và một số giải thích thêm '], "e #" -> [' codecodecode e # Giải thích ',' sdf dsf sdf e # A Rất rất rất rất rất rất rất rất dài rất dài ',' e # dài dài dài giải thích dài dài và nó tiếp tục dài hơn ',' e # và dài hơn ',' ',' thêm một số mã e # và một số giải thích thêm ']

Chúc mừng mã hóa!


1
@Matt Tất cả các ngăn cách luôn ở cột length of the longest code-line + 5. Điều này cũng áp dụng cho các dòng chỉ chứa một lời giải thích, bởi vì chúng được gói.
Denker

Ôi chúa ơi tôi đã làm điều này sai trong 3 giờ qua. Tôi đã cố gắng để bọc mã dài và để lại những lời giải thích dài ..... Vâng bắt đầu lại. Ít nhất bây giờ thì dễ dàng hơn. Cảm ơn. Bạn nói nó tốt .... Tôi chỉ là ngớ ngẩn.
Matt

Bao bọc tất cả các dòng dài hơn 93 ký tự Điều đó có nghĩa là mã, bao gồm các khoảng trắng hàng đầu, sẽ không bao giờ dài hơn 87 ký tự?
Matt

@Matt Mã bộ tách biệt với nhau sẽ không bao giờ dài hơn 87 ký tự vì chúng ta cần 5 khoảng cách giữa mã và bộ tách biệt và một ký tự để giải thích.
Denker

1
Mã Pyth tìm thấy tên viết tắt của bất kỳ chuỗi nào. Tôi sẽ biết vì đó là một câu trả lời cho câu hỏi của tôi.
Aplet123

Câu trả lời:


3

Ruby, 245 237 220 216 212 209 205 byte

Chức năng ẩn danh. Cách tiếp cận khá cơ bản (tìm độ dài tối đa, thêm 5, sau đó thực hiện xử lý trên mỗi dòng, với đệ quy để xử lý gói) và có thể có một cách tiếp cận khác giúp tiết kiệm nhiều byte hơn.

Tôi đã xóa câu trả lời trước đó mà không đáp ứng tất cả các yêu cầu; Tôi không muốn có một mã được trả lời một nửa như một câu trả lời (bây giờ nó đang bị hạ thấp vì không đầy đủ) nhưng bây giờ nó phải làm mọi thứ mà câu hỏi yêu cầu.

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

Thay đổi:

  • Đã lưu một số byte bằng cách tận dụng một số lời hứa trong đầu vào, đặc biệt là lời hứa rằng tất cả các dòng không trống có ký tự phân tách và giải thích.
  • Quản lý để chơi golf nhiều hơn một chút bằng cách lưu các chuỗi phân tách từ mapcuộc gọi đầu tiên và thực hiện một số stripchức năng không cần thiết dựa trên lời hứa rằng các từ trong lời giải thích luôn có chính xác một khoảng cách giữa chúng. Ngoài ra, " "bây giờ được gán cho một hằng số vì tôi sử dụng nó rất nhiều.
  • Kết hợp cả hai mapcuộc gọi với nhau bằng cách tận dụng sức mạnh của các hàm bậc cao hơn, nghĩa là lệnh gọi bản đồ đầu tiên sẽ đặt biến độ dài lchính xác ngay cả khi nó được gọi sau khi khai báo hàm trợ giúp s. -4 byte.
  • Các chuỗi multiline bị lạm dụng để thay thế \nbằng các dòng mới thực tế, cộng với một mẹo nhỏ sử dụng các iftoán tử ternary (khi joinđược gọi trên một mảng có nilgiá trị, chúng trở thành các chuỗi rỗng)
  • .joinrõ ràng có thể được thay thế bằng a *.

Tôi nghĩ nó nên được sửa chữa bây giờ?
Mực giá trị

Làm thế nào để bọc này ở 94?
Ven

Được rồi, bây giờ tôi đã có nhiều thời gian hơn để làm việc với mã, nó kết thúc tốt đẹp.
Mực giá trị

"Mặc dù phần giải thích có thể có độ dài không giới hạn, dấu phân cách và mã chỉ có thể có độ dài tối đa kết hợp của 93 - 5 = 87ký tự. 5 ký tự là khoảng cách giữa mã và dấu phân cách. Mã và dấu phân cách sẽ luôn dài ít nhất một ký tự." Phần mã của bạn vượt quá giới hạn, với 97 ký tự, vì vậy chương trình có hành vi không xác định.
Mực giá trị

ah, phát hiện tốt, có ý nghĩa!
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

Cách thức hoạt động: chủ yếu giống như mã Java. Bắt đầu bằng độ dài răng cưa (LiveScript cho phép tạo hàm từ toán tử bằng cách sử dụng dấu ngoặc đơn). .=a = a.b- mà chúng tôi sử dụng ở đây để lập bản đồ.

=> blabla ..là cấu trúc bậc thang Smalltalk-ish: phía bên trái =>có thể truy cập như ..đối với phần còn lại của khối; và sẽ được trả lại. Ở đây, đó là phần tử phân chia trên k. Lưu ý: Tôi đang sử dụng phép nội suy chuỗi, bởi vì /chỉ có nghĩa là "chia" với một chuỗi bằng chữ.

LS cũng cho phép chúng tôi sử dụng a-=/regexp/trong lambda này (cũng hoạt động với chuỗi ký tự): đó chỉ là đường cho một .replacecuộc gọi.

Cuối cùng, toán tử -assin >?=kết hợp >?, trả về giá trị lớn hơn của hai toán hạng.

LS có kiểu Python / Haskell để hiểu, không có gì lạ mắt trong chúng, ngoại trừ "chuỗi * lần" để lặp lại không gian đủ lâu.

Điều này để hiểu được phục vụ như là chủ đề (xem khối về thác anove).

Sau đó, chúng tôi lặp lại từng phần tử của mảng (cái mà chúng tôi vừa xây dựng với sự hiểu biết) và nếu bất kỳ dòng nào lớn hơn 93chars, chúng tôi sẽ tìm thấy chỉ mục cuối cùng, phân tách ở đó và đẩy dòng tách ra ngay sau lần lặp hiện tại này ( ... Vì vậy, lần lặp tiếp theo sẽ phân tách một lần nữa nếu dòng quá lớn).

Điều duy nhất cuối cùng a[j to]là một phạm vi (từ j đến cuối), nhưng vì nó sử dụng các phương thức Array nên chúng ta phải nối nó lại thành một chuỗi, mà chúng ta sử dụng quá tải *: *''.

thí dụ

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

đầu ra:

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
cho bất cứ ai downvote: câu trả lời là cố định.
Ven

2
Khi một lời giải thích tràn ra, bạn cần (các) dòng mới để căn chỉnh các ký tự phân tách của chúng với phần còn lại, IIRC.
Mực giá trị

@KevinLau cũng phát hiện, đã sửa!
Ven

Bạn có thể cập nhật đầu ra ví dụ của bạn là tốt?
Mực giá trị

@KevinLau đã xong.
Ven

6

Java, 347 + 19 = 366 byte

Đòi hỏi

import java.util.*;

Do đó, +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);}}

Có định dạng f.accept(List<String> code, String seperator). Các định dạng tại chỗ. Một phiên bản tạo và trả về một cái mới List<String>sẽ không quan trọng để thực hiện nhưng tốn một số byte.

Sử dụng ví dụ + thụt lề:

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

... Có lẽ tôi nên chạy nó qua chính nó: P


Nếu bất cứ ai cũng có thể hiểu tại sao replace(" *"+s)nó không hoạt động nhưng replaceAll(" *"+s)tôi rất thích nghe nó - tôi không thể hiểu được.
CAD97

<badguess> replacesử dụng chuỗi nhưng replaceAllsử dụng biểu thức chính quy. </ badguess>
CalculatorFeline

@CatsAreFluffy tốt, bạn đã đúng ! Không biết làm thế nào tôi không nhận ra rằng: P
CAD97

Bạn không thể xóa dòng mới?
Máy

Vâng, dòng mới có thể bị xóa vì yêu cầu semi: s (nên là .s nhưng bất cứ điều gì)
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}

Đã cập nhật logic để xác định độ dài chuỗi mã tối đa. Cập nhật để cho phép nhiều dấu phân cách bao gồm các ký tự meta regex.


Giải thích nhỏ

Điều này có trong một chuỗi giới hạn hoàn toàn mới cho đầu vào.

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
}

Kết quả mẫu với một số 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

@nimi Hy vọng các bản cập nhật bây giờ làm cho một giải pháp tốt hơn.
Matt

@nimi Còn điều gì bạn nhận thấy sai không? Tôi dường như có vấn đề đọc vài ngày qua.
Matt

Không. Bây giờ có +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

Chương trình chấp nhận đầu vào Idưới dạng một chuỗi ô trong đó mỗi phần tử của mảng ô là một dòng riêng của đầu vào. Nó cũng chấp nhận đầu vào thứ hai cho biết ký tự nhận xét là gì (nghĩa là #). Hàm trả về một chuỗi nhiều dòng được định dạng đúng.

Giải thích ngắn gọn

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

Ví dụ đầu vào

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

Ví dụ đầu ra

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.