เยื้องกลับด้าน


63

ฉันได้ยินมาว่าโค้ดของคุณสามารถทำงานได้เร็วขึ้นหากคุณเยื้องในสิ่งที่ตรงกันข้ามเพื่อให้คอมไพเลอร์สามารถประมวลผลมันเหมือนรูปแบบการออกแบบต้นไม้จากส่วนบนสุดของ "สาขา" ลง สิ่งนี้จะช่วยได้เนื่องจากแรงโน้มถ่วงจะช่วยเร่งเวลาที่ต้องใช้ในการรวบรวมรหัสของคุณและปรับปรุงประสิทธิภาพของโครงสร้างข้อมูล นี่คือตัวอย่างในการเขียนสคริปต์ Java:

            function fib(n) {
        var a = 1, b = 1;
        while (--n > 0) {
    var tmp = a;
    a = b;
    b += tmp;
    if (a === Infinity) {
return "Error!";
    }
        }
        return a;
            }

แต่ด้วยเหตุผลบางอย่าง Notepad ไม่ได้ตั้งค่าให้ทำสิ่งนี้โดยอัตโนมัติดังนั้นฉันต้องการโปรแกรมที่จะทำเพื่อฉัน

ลักษณะ

การส่งต้องใช้ข้อมูลโค้ดเป็นข้อมูลป้อนกลับการเยื้องและส่งออกโค้ดผลลัพธ์

ทำตามขั้นตอนต่อไปนี้:

  • แยกรหัสออกเป็นเส้น ๆ แต่ละบรรทัดจะเริ่มต้นด้วยศูนย์หรือมากกว่าช่องว่าง (จะไม่มีแท็บ)

  • ค้นหาระดับการเยื้องที่ไม่ซ้ำกันทั้งหมดในรหัส ตัวอย่างเช่นสำหรับตัวอย่างข้างต้นนี้จะเป็น

    0
    4
    8
    12
    
  • กลับลำดับของรายการของระดับการเยื้องนี้และแมปรายการที่กลับรายการกับรายการเดิม นี่เป็นการยากที่จะอธิบายในคำพูด แต่สำหรับตัวอย่างมันจะดูเหมือน

    0  — 12
    4  — 8
    8  — 4
    12 — 0
    
  • ใช้การจับคู่นี้กับรหัสต้นฉบับ ในตัวอย่างบรรทัดที่มี 0-space-เยื้องจะกลายเป็นเยื้องโดย 12 ช่องว่าง 4 ช่องว่างจะกลายเป็น 8 ช่องว่าง ฯลฯ

อินพุต / เอาต์พุต

อินพุตและเอาต์พุตสามารถให้ได้ตามที่คุณต้องการ (STDIN / STDOUT, พารามิเตอร์ฟังก์ชัน / ค่าส่งคืน, ฯลฯ ); หากภาษาของคุณไม่รองรับการป้อนหลาย|บรรทัด(หรือคุณไม่ต้องการ) คุณสามารถใช้อักขระเพื่อแยกบรรทัดแทน

อินพุตจะประกอบด้วยบรรทัดใหม่ ASCII + ที่พิมพ์ได้เท่านั้นและจะไม่มีบรรทัดว่างเปล่า

กรณีทดสอบ

การป้อนข้อมูล:

function fib(n) {
    var a = 1, b = 1;
        while (--n > 0) {
            var tmp = a;
            a = b;
            b += tmp;
            if (a === Infinity) {
                return "Error!";
            }
        }
    return a;
}

ผลลัพธ์: รหัสตัวอย่างด้านบน

การป้อนข้อมูล:

a
  b
  c
d
   e
        f
  g
   h

เอาท์พุท:

        a
   b
   c
        d
  e
f
   g
  h

การป้อนข้อมูล:

1
 2
  3
 2
1

เอาท์พุท:

  1
 2
3
 2
  1

การป้อนข้อมูล:

  foo

เอาท์พุท:

  foo

21
"JavaScript" ไม่ใช่ "Java scripting": /
Optimizer

75
@Optimizer ฉันเห็นว่าเป้าหมายของฉันในการทำให้คนโมโหมากที่สุดเท่าที่จะทำได้ในสองย่อหน้าแรกนั้นประสบความสำเร็จ ;)
Doorknob

7
1! = ผู้คนให้มากที่สุด
เครื่องมือเพิ่มประสิทธิภาพ

23
@JanDvorak พวกเดียวกับที่คิดค้นการอ้างอิงแบบ MLA คิดว่านี่เป็นความคิดที่ดี
Rainbolt

6
คิดว่ามันเร็วกว่า ลองมอบหมายให้คณะกรรมการและรอสักสองสามปีในขณะที่เราลืมจุดประสงค์ของมัน
Conor O'Brien

คำตอบ:


10

CJam, 43 39 36 35 bytes

qN/_{_Sm0=#}%___&$_W%er]z{~S*@+>N}%

ดูเหมือนจะนานเกินไป ฉันแน่ใจว่าฉันไม่ได้เพิ่มประสิทธิภาพเพียงพอ!

มันทำงานอย่างไร:

แนวคิดพื้นฐานคือการแบ่งอินพุตในบรรทัดใหม่คำนวณจำนวนช่องว่างนำในแต่ละบรรทัดเรียงลำดับและรับหมายเลขที่ไม่ซ้ำกันคัดลอกอาร์เรย์นั้นและย้อนกลับสำเนาคัดลอกหมายเลขต้นฉบับตามลำดับด้วยสองอาร์เรย์นี้จากนั้นจึงสร้าง สตริงสุดท้ายโดยใช้ข้อมูลนี้

ส่วนที่ยาวที่สุดคือการหาจำนวนช่องว่างนำหน้าในแต่ละบรรทัดเนื่องจาก CJam ไม่มีวิธีการทำที่ง่าย

การขยายรหัส:

qN/_                                      "Split the string on newline and take copy";
    {_Sm0=#}%                             "Map this code block on the copy";
     _Sm                                  "Copy the string and remove spaces from the copy";
        0=                                "Get first non space character";
          #                               "Gets its index in original string";
             ___                          "Get 3 copies of the above array";
                &$_W%                     "Get unique elements, sort, copy and reverse";
                     er                   "Transliterate unique sorted elements with";
                                          "the unique reverse sorted in the copy";
                       ]z                 "Get array of [row,
                                          " original number of leading spaces,
                                          " required number of leading spaces]";
                         {~S*@+>N}%       "For each above combination";
                          ~S*             " unwrap and get leading space string";
                             @+           " prepend to the row";
                               >          " remove original spaces";
                                N         " put newline";

และในจิตวิญญาณของคำถาม การขยายตัวที่แท้จริงของรหัส:

                                          qN/_                                      "Split the string on newline and take copy";
                                {_Sm0=#}%                             "Map this code block on the copy";
                               _Sm                                  "Copy the string and remove spaces from the copy";
                             0=                                "Get first non space character";
                          #                               "Gets its index in original string";
                         ___                          "Get 3 copies of the above array";
                       &$_W%                     "Get unique elements, sort, copy and reverse";
                     er                   "Transliterate unique sorted elements with";
"the unique reverse sorted in the copy";
                ]z                 "Get array of [row,
" original number of leading spaces,
" required number of leading spaces]";
             {~S*@+>N}%       "For each above combination";
          ~S*             " unwrap and get leading space string";
        @+           " prepend to the row";
     >          " remove original spaces";
    N         " put newline";

บันทึกไปแล้ว 7 ไบต์ด้วย Martin และอีก 1 ไบต์ขอบคุณ Dennis

ลองออนไลน์ได้ที่นี่


1. {}#มีข้อบกพร่อง: มันคืนค่าจำนวนเต็ม แต่ควรคืนค่า Long แดกดันi(cast to จำนวนเต็ม) แก้ไขสิ่งนี้ 2. เนื่องจาก""#ไม่มีข้อผิดพลาดเดียวกัน_Sm0=#จึงสั้นลงหนึ่งไบต์
เดนนิส

@Dennis Yeah ข้อผิดพลาดแปลก ขอบคุณสำหรับการแก้ปัญหา!
เครื่องมือเพิ่มประสิทธิภาพ

2
การเยื้องในการขยายตัวนี้เป็นเรื่องง่ายมากที่จะอ่าน! คุณควรย้อนกลับ!
DLeh

13

Python 2 - 137 131 ไบต์

i=raw_input().split('|')
f=lambda s:len(s)-len(s.lstrip())
d=sorted(set(map(f,i)))
for l in i:print' '*d[~d.index(f(l))]+l.lstrip()

จะเข้ากับแทน|\n

คำอธิบาย

สามบรรทัดแรกนั้นค่อนข้างตรงไปตรงมา ทำรายการของบรรทัดทั้งหมดในอินพุตกำหนดฟังก์ชันที่บอกให้คุณทราบว่ามีช่องว่างนำหน้าสตริงเท่าไรและทำรายการเรียงลำดับของค่าที่ฟังก์ชันแยกออกสำหรับแต่ละบรรทัดของอินพุต

บรรทัดสุดท้ายคือวิธีที่สนุกมากขึ้น

                                 l               # string with the line
                               f(l)              # amount of leading whitespace
                       d.index(f(l))             # where it is in list of whitespace amounts
                      ~d.index(f(l))             # bitwise NOT (~n == -(n+1))
                    d[~d.index(f(l))]            # index into the list (negative = from end)
           print' '*d[~d.index(f(l))]            # print that many spaces...
           print' '*d[~d.index(f(l))]+l.lstrip() # plus everything after leading whitespace
for l in i:print' '*d[~d.index(f(l))]+l.lstrip() # do the above for every line


@frya ขอบคุณ :)
undergroundmonorail

1
ทั้งหมดนี้ดูเหมือนดีใน python 3 ซึ่งจะช่วยให้คุณประหยัด 2 ไบต์ (จ่าย 2 เพื่อ()ประหยัด 4 สำหรับraw_)
FryAmTheEggman

1
f(s)for s in imap(f,i)ควรจะเป็น
feersum

1
ชิ้นส่วนของเวทมนตร์: เป็นรุ่นสั้นd=[];d+=set(L) d=sorted(set(L))
xnor

7

JavaScript, ES6, 113 103 101 ไบต์

ฉันค่อนข้างมั่นใจว่าสิ่งนี้สามารถเล่นกอล์ฟได้อย่างน้อยอีกเล็กน้อย แต่นี่จะไป

ไม่เคยคิดเลยว่าจะมีโซลูชัน JS ขนาด 101 ไบต์เต้น Python!

f=a=>(b=c=[...Set(a.match(r=/^ */gm).sort())],c.map((x,i)=>b[x]=c.slice(~i)[0]),a.replace(r,x=>b[x]))

สิ่งนี้จะสร้างวิธีการตั้งชื่อfซึ่งสามารถเรียกได้ด้วยสตริงอินพุต หากคุณอยู่ใน Firefox ล่าสุดคุณมีสตริงแม่แบบและคุณสามารถเรียกวิธีการเช่น

f(`a
  b
  c
d
   e
        f
  g
   h`)

มิฉะนั้นคุณสามารถโทรหาได้เช่นกัน

f("a\n\
  b\n\
  c\n\
d\n\
   e\n\
        f\n\
  g\n\
   h")

หรือลองตัวอย่างด้านล่าง:

g=_=>O.textContent=f(D.value)

f=a=>(b=c=[...Set(a.match(r=/^ */gm).sort())],c.map((x,i)=>b[x]=c.slice(~i)[0]),a.replace(r,x=>b[x]))
<textarea id=D></textarea><button id=B onclick=g()>Inverse!</button>
<pre id=O></pre>


คุณสามารถบันทึก coupes bytes ได้โดยจัดเก็บ regex เป็นตัวแปรเนื่องจากมีการใช้สองครั้ง (คุณควรจะสามารถแทนที่\sด้วยอักขระเว้นวรรค) และลบวงเล็บxในฟังก์ชันแทนที่
NinjaBearMonkey

@hsl gee ขอบคุณ! ฉันไม่รู้ด้วยซ้ำว่าทำไมฉันจึงเขียน(x): /
เครื่องมือเพิ่มประสิทธิภาพ

คุณไม่ต้องการทั้งคู่bและcทำคุณ? พวกเขาอ้างถึงอาร์เรย์เดียวกันแล้ว
Neil

5

ทับทิม, 63 ไบต์

->s{l=s.scan(r=/^ */).uniq.sort;s.gsub r,l.zip(l.reverse).to_h}

สิ่งนี้จะกำหนดฟังก์ชั่นที่ไม่มีชื่อซึ่งรับและส่งคืนสตริง คุณสามารถเรียกมันได้ด้วยการต่อท้าย["string here"]หรือโดยการกำหนดให้ตัวแปรแล้วเรียกตัวแปรนั้น

มันทำงานอย่างไร: s.scan(r=/^ */)ให้รายการของช่องว่างและร้านค้าชั้นนำที่ regex rเพื่อใช้ในภายหลัง uniqกำจัดรายการที่ซ้ำกัน sort... แปลก ๆ

ตอนนี้ข้ามไปยังจุดสิ้นสุดl.zip(l.reverse)มอบอาร์เรย์ของคู่ที่เราต้องการแทนที่ to_hเปลี่ยนเป็นแฮชแปลความหมายของคู่เป็นคู่ของคีย์ - ค่า

ตอนนี้s.gsubแทนที่การจับคู่ทั้งหมดของ regex (ช่องว่างนำทั้งหมด) โดยใช้แฮชนั้นเป็นตารางค้นหาเพื่อค้นหาการแทนที่



2

Japt -R , 27 ไบต์

·
mâ\S
Vâ n
Ëx2 iSpWg~WbVgE

ลองออนไลน์!

เอาออกแล้วมันทำงานอย่างไร

Input: U = multiline string

qR    Split by newline and implicit assign to U

mâ\S
m     Map over U...
 â\S    .search(/\S/); first index of non-whitespace char
      Implicit assign to V (V = array of indentations)

Vâ n  Take unique elements of V, sort, and implicit assign to W

mDEF{Dx2 iSpWg~WbVgE
mDEF{                 Map over U...
     Dx2                Trim left
         iSp            Indent by this many spaces...
                 VgE      Find the current indentation stored in V
               Wb         Find its index on W
            Wg~           Take the opposite element on W

-R    Join with newline

วิธีการมันจริงๆทำงาน

                 Input: U = multiline string

                 qR    Split by newline and implicit assign to U

                 mâ\S
                 m     Map over U...
               â\S    .search(/\S/); first index of non-whitespace char
         Implicit assign to V (V = array of indentations)

                 Vâ n  Take unique elements of V, sort, and implicit assign to W

                 mDEF{Dx2 iSpWg~WbVgE
                 mDEF{                 Map over U...
            Dx2                Trim left
      iSp            Indent by this many spaces...
VgE      Find the current indentation stored in V
 Wb         Find its index on W
     Wg~           Take the opposite element on W

                 -R    Join with newline

1

สกาลา, 176 171

def g(n:String)={val a=n.split('|').map(a=>a.prefixLength(' '==)->a)
(""/:a){case(s,(l,p))=>val b=a.unzip._1.distinct.sorted
s+" "*b.reverse(b.indexOf(l))+p.drop(l)+'\n'}}

มันจะเพิ่มขึ้นบรรทัดใหม่พิเศษในตอนท้าย หากฉันไม่จำเป็นต้องรักษาช่องว่างท้ายบรรทัดฉันสามารถไปที่ 167:

def t(n:String)={val a=n.split('|').map(a=>a.prefixLength(' '==)->a.trim)
(""/:a){(s,l)=>val b=a.unzip._1.distinct.sorted
s+" "*b.reverse(b.indexOf(l._1))+l._2+'\n'}}

Ungolfed:

      def reverseIndent(inString: String): String = {
    val lines = inString.split('\n')
    val linesByPrefixLength = lines.map { line =>
  line.prefixLength(char => char == ' ') -> line
    }
    val distinctSortedPrefixLengths = linesByPrefixLength.map(_._1).distinct.sorted
    val reversedPrefixes = distinctSortedPrefixLengths.reverse
    linesByPrefixLength.foldLeft("") { case (string, (prefixLength, line)) =>
  val newPrefixLength = reversedPrefixes(distinctSortedPrefixLengths.indexOf(prefixLength))
  val nextLinePrefix = " " * newPrefixLength
  string + nextLinePrefix + line.substring(prefixLength) + '\n'
    }
      }

1

PowerShell , 112 ไบต์

$x=@($args|sls '(?m)^ *'-a|% m*|% v*|sort -u)
[regex]::Replace($args,'(?m)^ *',{$x[-1-$x.IndexOf($args.Value)]})

ลองออนไลน์!

หักกอล์ฟ:

$xIdents=@($args|select-string '(?m)^ *'-AllMatches|% matches|% value|sort -unique) # get a sorted set of indentations
[regex]::Replace($args,'(?m)^ *',{$xIdents[-1-$xIdents.IndexOf($args.Value)]})    # replace each indentation with opposite one


0

PHP - 173 ไบต์

รหัสที่ไม่ได้เพิ่มประสิทธิภาพควรถูกเก็บไว้ใน$vตัวแปร:

<?php $f='preg_replace';$f($p='#^ *#me','$i[]='.$s='strlen("$0")',$v);$a=$b=array_unique($i);sort($a);rsort($b);echo$f($p,'str_repeat(" ",array_combine($a,$b)['.$s.'])',$v);

นี่คือเวอร์ชันที่ไม่น่ารังเกียจและแสดงความคิดเห็น:

<?php
// Get the level of indentation for each line
$preg_replace = 'preg_replace';
$pattern = '#^ *#me';
$strlen = 'strlen("$0")';
$preg_replace($pattern, '$indentationLevelsOldList[] = '. $strlen, $value);

// Create an array associating the old level of indentation with the new expected one
$sortedArray = array_unique($indentationLevelsOldList);
$reverseSortedArray = $sortedArray;

sort($sortedArray);
rsort($reverseSortedArray);

$indentationLevelsNewList = array_combine($sortedArray, $reverseSortedArray);

// Print the correctly indented code
echo $preg_replace($pattern, 'str_repeat(" ", $indentationLevelsNewList['. $strlen .'])', $value);

ฉันอาจไม่เคยเขียนเรื่องสกปรกเลย ฉันละอายใจ.


0

JavaScript, 351

var i=0;var a=$("#i").html().split("\n");var b=[];for(;i<a.length;i++){j=a[i].match(/\s*/)[0];if(b.indexOf(j)<0){b.push(j);}}b.sort(function(a,b){return a - b;});var c=b.slice().reverse();var d="";for(i=0;i<a.length;i++){d+=a[i].replace(/\s*/,c[b.indexOf(a[i].match(/\s*/)[0])])+"\n";j=a[i].search(/\S/);if(b.indexOf(j)<0){b.push(j);}}$("#i").html(d);

เวอร์ชันที่ไม่ถูกปรับแต่ง:

var i = 0;
var a = $("#i").html().split("\n");
var b = [];
for (; i < a.length; i++) {
  j = a[i].match(/\s*/)[0];
  if (b.indexOf(j) < 0) {
    b.push(j);
  }
}
b.sort(function(a, b) {
  return a - b;
});
var c = b.slice().reverse();
var d = "";
for (i = 0; i < a.length; i++) {
  d += a[i].replace(/\s*/, c[b.indexOf(a[i].match(/\s*/)[0])]) + "\n";
  j = a[i].search(/\S/);
  if (b.indexOf(j) < 0) {
    b.push(j);
  }
}
$("#i").html(d);

การทดสอบ


0

Perl 5, 112

111 + 1 สำหรับ-n( -Eฟรี)

@{$.[$.]}=/( *)(.*)/;++$_{$1}}{map$_{$_[$#_-$_]}=$_[$_],0..(@_=sort keys%_);say$_{$.[$_][0]}.$.[$_][1]for 0..$.

ฉันแน่ใจว่ามันสามารถทำได้ในจังหวะที่น้อยลง แต่ฉันไม่เห็นว่าในขณะนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.