Chuyển đổi niềng răng thành Nẹp tay phải (Niềng răng buồn)


26

Nẹp tay phải là một kiểu dấu ngoặc trong đó các dấu ngoặc nhọn và dấu chấm phẩy đều được căn chỉnh theo một điểm duy nhất ở phía bên phải của tệp aa.

Ví dụ hình ảnh ở đây

Nói chung, điều này được coi là thực hành xấu, vì một số lý do.

Các thách thức

Lấy một chuỗi nhiều dòng thông qua bất kỳ phương pháp nào và chuyển đổi kiểu niềng răng của nó thành Niềng tay phải.

Đối với thử thách này, bạn chỉ cần nó hoạt động trên mã Java, tuy nhiên, về mặt lý thuyết, nó sẽ hoạt động trên bất kỳ mã nào sử dụng Dấu ngoặc và Dấu chấm phẩy.

Bạn phải lấy tất cả các {};ký tự liên tiếp, với bất kỳ khoảng trắng nào giữa chúng. VÍ DỤ. }}, ; } }\n\t\t}và sắp xếp chúng ở phía bên phải của tệp thông qua việc sử dụng khoảng trắng.

ví dụ:

a {
b;
{c

nên trở thành

a {
b ;{
c

Hoặc, trừu tượng hơn, đẩy bất kỳ và tất cả khoảng trắng từ bên trái của tất cả các {};ký tự, sang bên phải.

Lõm dòng nên được bảo tồn khác. Các dòng chỉ chứa khoảng trắng sau khi chuyển động của các {};ký tự có thể được loại bỏ tùy ý.

Ví dụ:

a{
    b{
        c;
    }
}
d;

Có thể trở thành một trong hai

a        {
    b    {
        c;}}
d        ;

hoặc là

a        {
    b    {
        c;}}


d        ;

Đẩy sang phải là tất cả các {};ký tự được căn chỉnh đến một điểm không ngắn hơn dòng dài nhất. Bất kỳ số lượng không gian sau đó là chấp nhận được.

Vì vậy, tất cả những điều dưới đây là chấp nhận được:

a {
bc;

a  {
bc ;

a   {
bc  ;

v.v ...

Các dòng trong bất kỳ mã nào có thể chứa các {};ký tự giữa các ký tự không phải khoảng trắng khác, việc xử lý trường hợp này là không cần thiết, mặc dù nếu bạn nghiêng, bạn nên để chúng tại chỗ. Các dòng cũng có thể không chứa bất kỳ {};ký tự nào và điều này cần được xử lý chính xác. Như được hiển thị dưới đây.

a {
b ;
c
d }

Vì chúng tôi không muốn Đánh giá mã để xem những điều khủng khiếp mà chúng tôi đang thực hiện, bạn cần làm cho mã của mình nhỏ nhất có thể.

Ví dụ / Testcase

Java chung

public class HelloWorld{
       public static void main(String[] args){
           System.out.println("Hello, World!");
       }
}

trở thành ...

public class HelloWorld                        {
    public static void main(String[] args)     {
        System.out.println("Hello, World!")    ;}}

Hình ảnh chính nó

public class Permuter{
    private static void permute(int n, char[] a){
        if (n == 0){
            System.out.println(String.valueOf(a));
        }else{
            for (int i=0; i<= n; i++){
                permute(n-1, a);
                swap(a, n % 2 == 0 ? i : 0, n);
            }
        }
    }
    private static void swap(char[] a, int i, int j){
        char saved = a[i];
        a[i] = a[j];
        a[j] = saved;
    }
}

trở thành ...

public class Permuter                                {
    private static void permute(int n, char[] a)     {
        if (n == 0)                                  {
            System.out.println(String.valueOf(a))    ;}
        else                                         {
            for (int i=0; i<= n; i++)                {
                permute(n-1, a)                      ;
                swap(a, n % 2 == 0 ? i : 0, n)       ;}}}
    private static void swap(char[] a, int i, int j) {
        char saved = a[i]                            ;
        a[i] = a[j]                                  ;
        a[j] = saved                                 ;}}

Python không hoàn hảo

Để tương phản

def Main():
    print("Hello, World!");

Main();

trở thành ...

def Main():
    print("Hello, World!")    ;
Main()                        ;

Ghi chú

  • Áp dụng sơ hở tiêu chuẩn
  • Áp dụng IO tiêu chuẩn
  • Đây là , vì vậy chương trình ngắn nhất tính bằng byte thắng!
  • Tôi không chịu trách nhiệm cho các thiệt hại liên quan đến lập trình theo kiểu Niềng tay phải
  • Chúc vui vẻ!

Chỉnh sửa ghi chú

Tôi đã điều chỉnh lại các chi tiết thách thức, Hy vọng rằng tôi đã không phá vỡ quan điểm của bất kỳ ai về các quy tắc, tôi đảm bảo với bạn rằng đó là vô ý. Đây phải là một thông số rõ ràng hơn và ít xung đột hơn.


Phán quyết trên các dòng có nhiều dấu chấm phẩy là gì? Một cái gì đó nhưint a=0;System.out.println(a);
Giá trị mực

2
Đó có thể không phải là hình ảnh tốt nhất cho thử thách nếu chúng ta không cần xử lý các vòng lặp như trong hình ảnh mẫu?
Dennis

1
Có vẻ như hình ảnh trong câu hỏi xuất phát từ ví dụ này , được theo dõi bởi phần tiếp theo này , có ví dụ phức tạp hơn
Ray Toal

2
Có thể nói rõ hơn rằng bạn muốn các ;{}ký tự được tập hợp nếu chúng nằm trên các dòng riêng biệt (nó chỉ rõ ràng từ ví dụ, không phải là các quy tắc và trên thực tế nếu một dòng bao gồm \t}lưu giữ vết lõm có nghĩa là không di chuyển }đến cuối của dòng trước)
Chris H

2
Chúa ơi, xin vui lòng cho tôi biết không ai thực sự làm điều này trong thực tế cho một ngôn ngữ dài dòng như Java ._.
Bạch tuộc ma thuật Urn

Câu trả lời:


5

Tiện ích V + Bash, 64 62 61 60 62 byte

Lưu 1 byte nhờ @DJMcMayhem để đặt các lệnh ex lại với nhau

:se ve=all|%!wc -L
y$uò/^ *<93>[{};]
xk$pòò/<84> {};][{};]«$
lDî^R0|p

^Rlà ký tự theo nghĩa đen của <C-r>( 0x12) và <84>đang 0x84<94>0x94.

wc -Lhoạt động trên hầu hết các hệ thống dựa trên * nix, nhưng không phải macOS. Đối với macOS, bạn phải làm gwc -L sau khi lấy coreutils bằng cách sử dụng brew, nếu bạn chưa có.

Hãy thử trực tuyến! (Java)

Hãy thử trực tuyến! (Con trăn)

Hãy thử trực tuyến! (Lại Java)

Điều này bảo tồn tất cả các dòng trống và không xử lý các tab, chỉ có khoảng trắng.

Hexdump:

00000000: 3a73 6520 7665 3d61 6c6c 7c25 2177 6320  :se ve=all|%!wc 
00000010: 2d4c 0a79 2475 f22f 5e20 2a93 5b7b 7d3b  -L.y$u./^ *.[{};
00000020: 5d0a 786b 2470 f2f2 2f84 207b 7d3b 5d5b  ].xk$p../. {};][
00000030: 7b7d 3b5d ab24 0a6c 44ee 1230 7c70       {};].$.lD..0|p

Giải trình

Đầu tiên chúng ta cần có khả năng di chuyển con trỏ đến bất cứ đâu trong bộ đệm, vì vậy chúng tôi sử dụng

:se ve=all|...

và chúng ta xâu chuỗi này với một lệnh ex khác bằng cách sử dụng |

Chúng ta cần lấy chiều dài của dòng dài nhất trong đầu vào. Điều này có thể được thực hiện với lệnh shell wc -L.

       ...|%!wc -L

Điều này ghi đè lên bộ đệm hiện tại (chứa đầu vào) với kết quả là wc -L. Nó cung cấp một đầu ra của một cái gì đó như:

            42

và con trỏ vùng đất trên 4trong 42. Sau đó, chúng tôi sao chép số này bằng cách sử dụng y$: kéo văn bản từ vị trí của con trỏ đến cuối dòng. Điều này thuận tiện lưu trữ số này trong đăng ký 0. Nhưng nhiều hơn về điều này sau. Đầu vào được thay thế bằng số này, vì vậy để hoàn nguyên, chúng tôi undo.

Bây giờ nói đầu vào trông giống như thế này:

public class HelloWorld{
    public static void main(String[] args){
        System.out.println("Hello, World!");
    }
}

chúng ta cần di chuyển dấu ngoặc }từ cuối bộ đệm sang ngay sau printlncâu lệnh.

ò                  " recursively do this until a breaking error:
 /^ *<93>[{};]     "   this compressed regex becomes /^ *\zs[{};]
                   "   this finds any character from `{};` after leading spaces
                   "   the cursor then goes to the `{};`

x                  "   delete character
 k$                "   go to the end of the line above
   p               "   and paste
    ò

Nếu regex không thể được tìm thấy, một lỗi phá vỡ xảy ra và thoát ra khỏi đệ quy gây ra bởi ò.

Bây giờ đến phần chính của chương trình này, di chuyển tất cả các dấu ngoặc nhọn và dấu chấm phẩy và căn chỉnh chúng như đã nêu trong câu hỏi.

ò                  " starts recursion
 /<84> {};][{};]«$ "   compressed form of [^ {};][{};]\+$
                   "   finds a sequence of `{};`s at the end of the line with a non-`{};` char to preceding it
 l                 "   move the cursor 1 to the right (since we were on the non-`{};` char now)
  D                "   delete everything from this position to the end of line
                   "   the deleted text contains `{};`
   î               "   execute as normal commands:
    ^R0            "   contains what's in register `0`, ie the length of the longest line
       |           "   now go to the column specified by that number
        p          "   and paste the contents 
                   " implicit ending `ò`

Một lần nữa, đệ quy này sẽ bị dừng bởi một lỗi phá vỡ gây ra khi không thể tìm thấy regex trong bộ đệm.

Chỉnh sửa

  • Được sử dụng Dthay vì d$(tôi thậm chí không biết tại sao tôi lại bỏ lỡ điều đó)
  • Được nén [^(trong regex) để<84>
  • Sửa lỗi bằng cách sử dụng \zs(nén nó vào <93>) và bằng cách loại bỏ $trong$xk$pò
  • Xóa dòng mới vô dụng
  • Đã thay đổi regex để thực hiện đệ trình tuân thủ các quy tắc mới và nhận được 2 byte

Bạn có thể lưu một byte nếu bạn tham gia các lệnh cũ của mình cùng nhau:se ve=all|%!wc -L
DJMcMayhem

@DJMcMayhem Cảm ơn, TIL
Kritixi Lithos

4

Ruby, 100 114 108 byte

Đọc tên tệp dưới dạng đối số dòng lệnh. Nếu không có tên tệp nào được cung cấp, nó sẽ đọc từ STDIN. Không xử lý các tab.

Hãy thử trực tuyến!

f=$<.read.gsub(/[\s;{}]*$/){$&.tr"
 ",''}
$><<f.gsub(/(.*?)([;{}]+)$/){$1.ljust(f.lines.map(&:size).max)+$2}



Không hoạt động với cái này
Pavel

@Pavel cảm ơn đã cho tôi biết. Hai vấn đề tôi thấy sau khi chuyển thành tập tin là A. một catchcâu lệnh thụt lề và B. một dấu chấm phẩy được thụt lề quá nhiều, trên dòng dài nhất trong mã. Tôi nghĩ rằng tôi chỉ biết điều tôi cần sửa nó, cho tôi một giây. (Ngoài ra, tôi đã cập nhật thông số kỹ thuật để đề cập đến việc nó không thể xử lý các tab và tệp của bạn có các tab.)
Ink Ink

Nó có các tab không? Tôi vừa tìm và thay thế nó, và nó đã thực hiện 0 thay đổi.
Pavel

3

Perl , 90 byte

88 byte mã + -p0cờ.

\@a[y///c]for/.*/g;s/(.*?)\K[{};]$/$"x(@a-$1=~y%%%c).$&/gme;1while s/ *
 *([{};]+)$/$1/m

Hãy thử trực tuyến!

Giải thích ngắn:
\@a[y///c]for/.*/g; đếm chiều dài của dòng dài nhất: đối với mỗi dòng, nó xác định phần tử tại chỉ mục y///c(tức là kích thước của dòng) của mảng @a. Cuối cùng, chỉ số tối đa của @a(tức là kích thước của @a) là kích thước của dòng dài nhất.
s/(.*?)\K[{};]$/$"x(@a-$1=~y%%%c).$&/gmeđặt các {};ký tự ở cuối dòng.
1while s/ *\n *([{};]+)$/$1/mlàm cho các dấu ngoặc trên các dòng trống đi trên dòng trên.

Nhờ @primo từ người mà tôi đã "đánh cắp" phần đầu mã của tôi từ đây để đếm độ dài của dòng dài nhất.


Niềng răng phải quay trở lại dòng trên nếu chỉ có khoảng trắng trước chúng, câu trả lời này không làm điều đó
Kritixi Lithos

@KritixiLithos thực sự, có vẻ ổn trước khi thử thách được điều chỉnh lại (từ những gì tôi hiểu từ cả những thách thức và bình luận). Dù sao, giờ nó đã được sửa (tôi đã có mã được viết trong câu trả lời của mình trong trường hợp bạn không để ý).
Dada

1

Python 2: 228 byte

import re
g=re.search
def b(a):
    s,l="",a.split('\n')
    r=max([len(k)for k in l]) 
    for k in l:
        n,m=g('[;}{]',k),g('[\w]',k)
        if n:n=n.start()
        if m:m=m.start()
        if n>m and m!=None:s+="\n"+k[:n]+" "*(r-n)
        s+=k[n:]
    print s

Dài khủng khiếp. Tôi có lẽ nên bắt đầu lại từ đầu khi tôi nhận ra ;{}cần phải đi một mình ở cuối dòng trước.
Chris H

1

xếp chồng lên nhau , 133 byte

'\s+([;{}])' '$1'repl lines{!n'[\s;{}]+$'match''join:n\'$'+del\,}"!tr:$size"!$MAXmap@k{e i:e[' 'k i#rpad]"!}map tr[' 'join]map'
'join

Hãy thử trực tuyến! Tôi có thể suy nghĩ rất nhiều về điều này ... nhưng whatevs. Tôi sẽ xem xét lại vào ngày mai. Một số lời khuyên hay:

  1. "!thường có thể được sử dụng thay thế map, lưu một hoặc hai byte, tùy thuộc vào việc mã thông báo tiếp theo bắt đầu bằng một từ. Tuy nhiên, nó chỉ có thể được sử dụng khi mỗi nguyên tử của mảng muốn được ánh xạ. Nó tương tự như một bản đồ sâu.
  2. Một không gian là không cần thiết sau một chức năng được trích dẫn, do đó, $MAXmaptương đương với $MAX map, lần lượt là tương đương với [MAX] map. (Ánh xạ từng mảng thành phần tử tối đa của nó.)

1

JavaScript (Đề xuất ES), 139 121 byte

f=
s=>s.replace(/^(.*?)\s*(([;{}]\s*)+)$/gm,(_,t,u)=>t.padEnd(Math.max(...s.split`
`.map(s=>s.length)))+u.replace(/\s/g,``))
<textarea rows=10 cols=40 oninput=o.textContent=f(this.value)></textarea><pre id=o>

Yêu cầu Firefox 48 / Chrome 57 / Opera 44 / Safari 10 / Edge 15 cho padEnd. Chỉnh sửa: Đã lưu 18 byte nhờ @ValueInk.


Bạn có thực sự cần phải chạy s.replace(r,`$1`)khi tính toán độ dài dòng? Bất kỳ số lượng đệm phải hợp lý nào cũng đủ, do đó, đếm chiều dài dòng bằng dấu chấm phẩy và dấu ngoặc sẽ ổn.
Mực giá trị

0

PHP, 201 194 185 172 167 byte

foreach($f=file(f)as$s)$x=max($x,strlen($a[]=rtrim($s,"{} ;
")));foreach($a as$i=>$c)echo str_pad($c,""<$c|!$i?$x:0),trim(substr($f[$i],strlen($c))),"
"[""==$a[$i+1]];

lấy đầu vào từ tập tin f; giả định ngắt dòng byte đơn và không có tab; bảo quản các dòng trống.

  • +2 byte để phân định khoảng trắng: nối +1vào str_padtham số thứ hai .
  • -6 byte nếu được đảm bảo rằng không có dòng mã nào bao gồm một dòng duy nhất 0:
    Xóa ""<và thay thế ""==bằng !.

phá vỡ

foreach($f=file(f)as$s)             // loop through file
    $x=max($x,strlen(                   // 3. set $x to maximum code length
        $a[]=                           // 2. append to array $a
            rtrim($s,"{} ;\n")          // 1. strip trailing whitespace and braces
    ));
foreach($a as$i=>$c)echo            // loop through $a
    str_pad($c,                         // 1. print code:
        !$i|""<$c                       // if first line or not empty
        ?$x                             // then padded to length $x
        :0                              // else unpadded (= print nothing)
    ),
    trim(substr($f[$i],strlen($c))),    // 2. print braces
    "\n"[""==$a[$i+1]]                  // 3. if next line has code, print newline
;

Bạn có chắc chắn cần phải thoát khỏi {}niềng răng trong regex?
Kritixi Lithos

@KritixiLithos Có lẽ là không; nhưng dù sao tôi cũng tìm thấy một cách tiếp cận ngắn hơn.
Tít

0

Java 8, 312 305 byte

s->{String t="([;{}]+)",z[],r="",a;s=s.replaceAll(t+"[\\s\\n]*","$1").replaceAll(t,"$1\n");int m=0,l;for(String q:s.split("\n"))m=m>(l=q.length())?m:l;for(String q:s.split("\n")){z=q.split("((?<="+t+")|(?="+t+"))",2);for(a="",l=0;l++<m-z[0].length();a+=" ");r+=z[0]+a+(z.length>1?z[1]:"")+"\n";}return r;}

Giải trình:

Hãy thử nó ở đây.

s->{                                  // Method with String parameter and String return-type
  String t="([;{}]+)",                //  Temp regex-String we use multiple times
    z[],a,                            //  Temp String-array and temp String
    r="";                             //  Result-String
  s=s.replaceAll(t+"[\\s\\n]*","$1")  //  We replace all ;{} in the input with zero or more whitespaces/newlines to just ;{}
     .replaceAll(t,"$1\n");           //  and then add a single newline after each group of ;{}
  int m=0,l;                          //  Two temp integers
  for(String q:s.split("\n"))         //  Loop (1) over the lines
    m=m>(l=q.length())?m:l;           //   To determine the longest line
                                      //  End of loop (1)
  for(String q:s.split("\n")){        //  Loop (2) over the lines again
    z=q.split("((?<="+t+")|(?="+t+"))",2);
                                      //   Split on groups of ;{}, but keep them in the array
    for(a="",l=0;l++<m-z[0].length();a+=" "); 
                                      //   Amount of spaces we should add
    r+=z[0]+a+(z.length>1?z[1]:"")+"\n"; 
                                      //   Append this line to the result-String
  }                                   //  End of loop (2)
  return r;                           //  Return the result-String
}                                     // End of method

Này, tôi đang bình luận về câu trả lời này, nhưng nó áp dụng cho nhiều người khác của bạn. Chúng tôi hiện yêu cầu các tham số lambda phải có các loại trong Java .
Nathan Merrill

1
@NathanMerrill Đã sợ ngày phán xét sẽ đến. Jk, sẽ thêm nó từ bây giờ và tôi đã chỉnh sửa câu trả lời của mình, cảm ơn. ;)
Kevin Cruijssen
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.