แปลงเครื่องมือจัดฟันเป็นรั้งมือขวา (Sad Brace)


26

รั้งมือขวาคือรูปแบบของการใส่รหัสในการจัดฟันแบบหยักและอัฒภาคให้อยู่ในตำแหน่งเดียวที่ด้านขวาของไฟล์ aa

ภาพตัวอย่างไปที่นี่

โดยทั่วไปถือว่าเป็นการปฏิบัติที่ไม่ดีด้วยเหตุผลหลายประการ

ความท้าทาย

ใช้สตริงหลายบรรทัดผ่านวิธีการใด ๆ และแปลงรูปแบบการรั้งเป็น Right Hand Brace

สำหรับความท้าทายนี้คุณจะต้องใช้มันเพื่อทำงานกับโค้ด Java เท่านั้นอย่างไรก็ตามในทางทฤษฎีมันควรทำงานกับโค้ดใด ๆ ที่ใช้เครื่องมือจัดฟันและเครื่องหมายอัฒภาค

คุณต้องคว้า{};ตัวละครทั้งหมดในแถวด้วยช่องว่างใด ๆ ระหว่างพวกเขา เช่น. }},, ; } }\n\t\t}และจัดเรียงมันทางด้านขวาของไฟล์ผ่านการใช้ช่องว่าง

ตัวอย่างเช่น:

a {
b;
{c

ควรกลายเป็น

a {
b ;{
c

หรืออย่างเป็นนามธรรมมากขึ้นผลักช่องว่างใด ๆ และทั้งหมดจากด้านซ้ายของ{};ตัวละครทั้งหมดไปทางขวา

ควรเยื้องบรรทัด บรรทัดที่มีช่องว่างหลังจากการเคลื่อนไหวของ{};ตัวละครอาจถูกลบออก

ตัวอย่างเช่น:

a{
    b{
        c;
    }
}
d;

อาจกลายเป็นอย่างใดอย่างหนึ่ง

a        {
    b    {
        c;}}
d        ;

หรือ

a        {
    b    {
        c;}}


d        ;

กดไปทางขวาหมายถึง{};อักขระทั้งหมดที่จัดอยู่ในตำแหน่งที่ไม่สั้นกว่าบรรทัดที่ยาวที่สุด จำนวนพื้นที่ใด ๆ หลังจากนั้นเป็นที่ยอมรับ

ดังนั้นด้านล่างทั้งหมดเป็นที่ยอมรับ:

a {
bc;

a  {
bc ;

a   {
bc  ;

ฯลฯ ...

บรรทัดในรหัสใด ๆ อาจมี{};อักขระระหว่างอักขระที่ไม่ใช่ whitspace อื่น ๆ การจัดการกรณีนี้ไม่จำเป็นแม้ว่าคุณจะเอียงก็ตามคุณควรปล่อยให้อยู่ในตำแหน่ง บรรทัดอาจไม่มี{};อักขระใด ๆเลยและควรจัดการอย่างถูกต้อง ตามที่แสดงด้านล่าง

a {
b ;
c
d }

เนื่องจากเราไม่ต้องการให้Code Reviewเห็นสิ่งที่น่ากลัวที่เรากำลังทำอยู่คุณต้องทำให้โค้ดของคุณเล็กที่สุดเท่าที่จะทำได้

ตัวอย่าง / Testcases

Java ทั่วไป

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

กลายเป็น...

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

ภาพนั้นเอง

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

กลายเป็น...

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 ไม่ธรรมดาอย่างสมบูรณ์แบบ

สำหรับความคมชัด

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

Main();

กลายเป็น...

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

หมายเหตุ

  • มาตรฐานช่องโหว่ใช้
  • ใช้IO มาตรฐาน
  • นี่คือโปรแกรมที่สั้นที่สุดในหน่วยไบต์ชนะ!
  • ฉันไม่รับผิดชอบต่อความเสียหายที่เกี่ยวข้องกับการเขียนโปรแกรมในรูปแบบ Right Hand Brace
  • มีความสุข!

แก้ไขหมายเหตุ

ฉันยืนยันรายละเอียดการท้าทายอีกครั้งหวังว่าฉันจะไม่ขัดต่อกฎของทุกคนฉันรับประกันว่าคุณจะไม่ได้ตั้งใจ นี่ควรเป็นข้อมูลจำเพาะที่ชัดเจนและขัดแย้งกันน้อยกว่า


คำตัดสินของบรรทัดที่มีอัฒภาคหลายรายการคืออะไร บางสิ่งที่เหมือนกันint a=0;System.out.println(a);
Value Ink

2
นั่นอาจไม่ใช่ภาพที่ดีที่สุดสำหรับความท้าทายถ้าเราไม่จำเป็นต้องจัดการกับลูปเหมือนในภาพตัวอย่าง?
เดนนิส

1
ดูเหมือนว่าภาพในคำถามมาจากตัวอย่างนี้ซึ่งติดตามโดยการติดตามนี้ซึ่งมีตัวอย่างที่ซับซ้อนมากขึ้น
Ray Toal

2
อาจทำให้ชัดเจนขึ้นว่าคุณต้องการให้;{}ตัวละครรวมตัวกันหากแยกกัน (ชัดเจนจากตัวอย่างไม่ใช่กฎและในความเป็นจริงหากบรรทัดประกอบด้วย\t}การรักษาการเยื้องจะหมายถึงการไม่เลื่อน}ขึ้นไปจนถึงจุดสิ้นสุด ของบรรทัดก่อนหน้า)
Chris H

2
พระเจ้าที่ดีโปรดบอกฉันว่าไม่มีใครทำสิ่งนี้ในทางปฏิบัติสำหรับภาษา verbose เช่น Java ._
Magic Octopus Urn

คำตอบ:


5

ยูทิลิตี้V + Bash, 64 62 61 60 62 ไบต์

บันทึก 1 ไบต์ด้วย @DJMcMayhem สำหรับการรวมคำสั่ง ex เข้าด้วยกัน

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

^Rเป็นตัวอักษรตัวอักษรสำหรับ<C-r>( 0x12) และ<84>เป็น0x84และเป็น<94>0x94

wc -Lทำงานบนระบบที่ใช้ * nix ส่วนใหญ่ แต่ไม่ใช่ macOS สำหรับ macOS คุณต้องทำgwc -L หลังจากได้รับ coreutils โดยใช้การชงถ้าคุณยังไม่ได้ทำ

ลองออนไลน์! (Java)

ลองออนไลน์! (งูใหญ่)

ลองออนไลน์! (Java อีกครั้ง)

สิ่งนี้จะเก็บรักษาบรรทัดว่างทั้งหมดและไม่ได้จัดการกับแท็บเว้นวรรคเท่านั้น

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

คำอธิบาย

ก่อนอื่นเราต้องสามารถย้ายเคอร์เซอร์ไปที่ใดก็ได้ในบัฟเฟอร์ดังนั้นเราจึงใช้

:se ve=all|...

และเราเชื่อมโยงสิ่งนี้กับคำสั่ง ex อีกคำสั่งโดยใช้ |

เราต้องรับความยาวของบรรทัดที่ยาวที่สุดในอินพุต wc -Lซึ่งสามารถทำได้ด้วยคำสั่งของเชลล์

       ...|%!wc -L

นี้เขียนทับบัฟเฟอร์ปัจจุบัน (ที่มีการป้อนข้อมูล) wc -Lที่มีผลมาจากการ มันให้ผลลัพธ์ของสิ่งที่ชอบ:

            42

และเคอร์เซอร์ที่ดินบนใน4 42จากนั้นเราก็คัดลอกหมายเลขนี้โดยใช้y$: ดึงข้อความจากตำแหน่งเคอร์เซอร์ไปที่ท้ายบรรทัด 0นี้สิ่งอำนวยความสะดวกจัดเก็บหมายเลขนี้ในการลงทะเบียน แต่เพิ่มเติมในภายหลังว่า อินพุตถูกแทนที่ด้วยหมายเลขนี้ดังนั้นหากต้องการย้อนกลับเราจะuไม่

ตอนนี้พูดว่าอินพุตดูเหมือนเป็นเช่นนี้:

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

เราจำเป็นต้องย้ายวงเล็บปีกกา}จากจุดสิ้นสุดของบัฟเฟอร์ไปหลังprintlnคำสั่ง

ò                  " 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
    ò

หากไม่พบ regex จะเกิดข้อผิดพลาดที่เกิดขึ้นและแตกออกจากการสอบถามซ้ำที่เกิดจาก òไม่สามารถพบข้อผิดพลาดที่เกิดขึ้นทำลายและแบ่งออกมาจากการเรียกซ้ำที่เกิดจากการ

ตอนนี้เป็นส่วนหลักของโปรแกรมนี้ย้ายเครื่องมือจัดฟันและเซมิโคลอนทั้งหมดแล้วจัดเรียงตามที่ระบุในคำถาม

ò                  " 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 `ò`

อีกครั้งการเรียกซ้ำนี้จะหยุดลงเนื่องจากข้อผิดพลาดที่เกิดจากการแตกเมื่อไม่พบ regex ในบัฟเฟอร์

การแก้ไข

  • ใช้Dแทนd$(ฉันไม่รู้ด้วยซ้ำว่าทำไมฉันถึงพลาดในตอนแรก)
  • บีบอัด[^(ใน regex) ถึง<84>
  • แก้ไขข้อผิดพลาดโดยใช้\zs(การบีบอัดมันเข้าไป<93>) และโดยการลบ$ใน$xk$pò
  • ลบบรรทัดใหม่ที่ไม่มีประโยชน์
  • เปลี่ยน regex เพื่อให้การส่งเป็นไปตามกฎใหม่และได้รับ 2 ไบต์

คุณสามารถบันทึกหนึ่งไบต์หากคุณเข้าร่วมคำสั่งอดีตด้วยกัน:se ve=all|%!wc -L
DJMcMayhem

@DJMcMayhem ขอบคุณ TIL
Kritixi Lithos

4

ทับทิม100 114 108 ไบต์

อ่านชื่อไฟล์เป็นอาร์กิวเมนต์บรรทัดคำสั่ง หากไม่มีการระบุชื่อไฟล์มันจะอ่านจาก STDIN ไม่จัดการแท็บ

ลองออนไลน์!

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



ไม่ได้ทำงานกับนี้
พาเวล

@Pavel ขอบคุณที่แจ้งให้เราทราบ ปัญหาสองข้อที่ฉันเห็นหลังจากการไพพ์ลงในไฟล์คือ A. catchคำสั่งที่เยื้องและบีเซมิโคลอนที่ถูกเยื้องทางมากเกินไปบนบรรทัดที่ยาวที่สุดในรหัส ฉันคิดว่าฉันรู้เพียงแค่สิ่งที่ฉันต้องการแก้ไขให้ฉันสักครู่ (นอกจากนี้ฉันได้อัปเดตข้อมูลจำเพาะเพื่อระบุว่าไม่สามารถจัดการแท็บได้และไฟล์ของคุณมีแท็บ)
หมึกมูลค่า

มันมีแท็บหรือไม่ ฉันเพิ่งค้นหาและแทนที่มันและทำให้มีการเปลี่ยนแปลง 0 ครั้ง
Pavel

3

Perl , 90 ไบต์

88 ไบต์ของรหัสเมือง + -p0ธง

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

ลองออนไลน์!

คำอธิบายสั้น:
\@a[y///c]for/.*/g;นับยาวของเส้นที่ยาวที่สุดเพราะแต่ละบรรทัดจะกำหนดองค์ประกอบที่ดัชนีy///c(เช่นขนาดของบรรทัด) @aของอาร์เรย์ ในตอนท้ายดัชนีสูงสุดของ@a(เช่นขนาด@a) เป็นขนาดของเส้นที่ยาวที่สุด
s/(.*?)\K[{};]$/$"x(@a-$1=~y%%%c).$&/gmeวาง{};อักขระที่ท้ายบรรทัด
1while s/ *\n *([{};]+)$/$1/mทำให้ทำให้วงเล็บปีกกาในบรรทัดว่างไปในบรรทัดข้างต้น

ขอบคุณ@primoที่ฉัน "ขโมย" จุดเริ่มต้นของรหัสของฉันจากที่นี่บางส่วนเพื่อนับความยาวของบรรทัดที่ยาวที่สุด


วงเล็บต้องกลับไปถึงบรรทัดข้างต้นหากมีเพียงช่องว่างก่อนที่พวกเขาคำตอบนี้ไม่ได้ทำ
Kritixi Lithos

@KritixiLithos แน่นอนมันดูดีก่อนที่ความท้าทายจะได้รับการรับรองใหม่ (จากสิ่งที่ฉันเข้าใจจากทั้งความท้าทายและความคิดเห็น) อย่างไรก็ตามตอนนี้ได้รับการแก้ไขแล้ว (ฉันมีรหัสที่เขียนไว้ในคำตอบของฉันแล้วในกรณีที่คุณไม่ได้สังเกตเห็น)
Dada

1

Python 2: 228 ไบต์

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

ยาวมาก ฉันน่าจะเริ่มจากศูนย์ได้เมื่อฉันรู้ว่า;{}ต้องใช้คนเดียวในตอนท้ายของบรรทัดก่อนหน้า
Chris H

1

ซ้อนกัน , 133 ไบต์

'\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

ลองออนไลน์! ฉันอาจจะคิดมากเรื่องนี้อย่างหนัก แต่ ... ฉันจะดูอีกครั้งในวันพรุ่งนี้ เคล็ดลับดี ๆ :

  1. "!สามารถใช้แทนการmapบันทึกไบต์หรือสองขึ้นอยู่กับว่าโทเค็นถัดไปเริ่มต้นด้วยคำ อย่างไรก็ตามสามารถใช้ได้เฉพาะเมื่อต้องการทำแผนที่แต่ละอะตอมของอาเรย์ มันคล้ายกับแผนที่ลึก
  2. พื้นที่ไม่จำเป็นต้องหลังจากที่ฟังก์ชั่นที่ยกมาเพื่อให้$MAXmapเทียบเท่ากับซึ่งจะเทียบเท่ากับ$MAX map [MAX] map(แม็พแต่ละอาร์เรย์กับองค์ประกอบสูงสุด)

1

JavaScript (ข้อเสนอ ES), 139 121 ไบต์

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>

ต้องใช้ Firefox 48 / Chrome 57 / โอเปร่า 44 / ซาฟารี 10 / ขอบ 15 padEndสำหรับ แก้ไข: บันทึกแล้ว 18 ไบต์ขอบคุณ @ValueInk


คุณจำเป็นต้องเรียกใช้s.replace(r,`$1`)เมื่อคำนวณความยาวบรรทัดหรือไม่ จำนวนช่องว่างด้านขวาที่เหมาะสมควรเพียงพอดังนั้นการนับความยาวบรรทัดด้วยเครื่องหมายอัฒภาคและวงเล็บควรจะดี
หมึกมูลค่า

0

PHP, 201 194 185 172 167 ไบต์

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]];

รับอินพุตจากไฟล์ f; ถือว่า linebreaks ไบต์เดียวและไม่มีแท็บ; เก็บรักษาบรรทัดว่างไว้

  • +2 ไบต์สำหรับการลบช่องว่าง: ผนวก+1เข้ากับstr_padพารามิเตอร์ที่สอง
  • -6 ไบต์ถ้ามันเป็นที่รับประกันว่าไม่มีสายรหัสประกอบด้วยเดียว0:
    เอาออก""<และแทนที่ด้วย""==!

ทำให้พังถล่ม

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
;

คุณแน่ใจหรือว่าต้องการหลบหนี{}วงเล็บปีกกาใน regex?
Kritixi Lithos

@KritixiLithos อาจจะไม่ใช่ แต่ฉันก็พบวิธีที่สั้นกว่าอยู่ดี
ติตัส

0

Java 8, 312 305 ไบต์

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

คำอธิบาย:

ลองที่นี่

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

สวัสดีฉันกำลังแสดงความคิดเห็นกับคำตอบนี้ แต่มันใช้ได้กับคนอื่น ๆ ของคุณ ขณะนี้เราต้องใช้พารามิเตอร์แลมบ์ดาจะมีประเภทในชวา
Nathan Merrill

1
@NathanMerrill กลัวว่าจะถึงวันพิพากษา Jk จะเพิ่มมันจากนี้ไปและฉันได้แก้ไขคำตอบแล้วขอบคุณ ;)
Kevin Cruijssen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.