Lõm ngược


63

Tôi đã nghe nói rằng mã của bạn có thể chạy nhanh hơn nếu bạn thụt lề ngược lại, để trình biên dịch có thể xử lý nó giống như một mẫu thiết kế cây từ đầu "các nhánh" trở xuống. Điều này giúp vì trọng lực sẽ tăng tốc thời gian để mã của bạn được biên dịch và hiệu quả cấu trúc dữ liệu được cải thiện. Đây là một ví dụ, trong kịch bản 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;
            }

Nhưng vì một số lý do, Notepad không có cài đặt để thực hiện việc này một cách tự động, vì vậy tôi cần một chương trình để thực hiện điều đó cho tôi.

Sự miêu tả

Đệ trình phải lấy một đoạn mã làm đầu vào, đảo ngược thụt lề và xuất mã kết quả.

Điều này được thực hiện theo thủ tục sau đây:

  • Chia mã thành các dòng. Mỗi dòng sẽ bắt đầu bằng 0 hoặc nhiều khoảng trắng (sẽ không có tab).

  • Tìm tất cả các mức thụt đầu dòng duy nhất trong mã. Ví dụ, với ví dụ trên, đây sẽ là

    0
    4
    8
    12
    
  • Đảo ngược thứ tự của danh sách các mức thụt dòng này và ánh xạ danh sách đảo ngược vào danh sách ban đầu. Điều này thật khó để giải thích bằng lời, nhưng ví dụ, nó sẽ giống như

    0  — 12
    4  — 8
    8  — 4
    12 — 0
    
  • Áp dụng ánh xạ này cho mã gốc. Trong ví dụ, một dòng có thụt lề 0 không gian sẽ bị thụt vào bởi 12 khoảng trắng, 4 khoảng trắng sẽ trở thành 8 khoảng trắng, v.v.

Đầu ra đầu vào

Đầu vào và đầu ra có thể được cung cấp theo bất kỳ cách nào bạn muốn (STDIN / STDOUT, tham số hàm / giá trị trả về, v.v.); nếu ngôn ngữ của bạn không hỗ trợ đầu vào đa dòng (hoặc bạn chỉ không muốn), bạn có thể sử dụng |ký tự để phân tách các dòng thay thế.

Đầu vào sẽ chỉ bao gồm các dòng mới ASCII + có thể in và nó sẽ không chứa các dòng trống.

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

Đầu vào:

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

Đầu ra: mã ví dụ ở trên.

Đầu vào:

a
  b
  c
d
   e
        f
  g
   h

Đầu ra:

        a
   b
   c
        d
  e
f
   g
  h

Đầu vào:

1
 2
  3
 2
1

Đầu ra:

  1
 2
3
 2
  1

Đầu vào:

  foo

Đầu ra:

  foo

21
"JavaScript" của nó không phải là "Java scripting": /
Trình tối ưu hóa

75
@Optimizer Tôi thấy rằng mục tiêu của tôi là làm điên đảo càng nhiều người càng tốt với hai đoạn đầu tiên đã đạt được. ;)
Doorknob

7
1! = Càng nhiều người càng tốt.
Trình tối ưu hóa

23
@JanDvorak Những người cùng phát minh ra các trích dẫn kiểu MLA nghĩ rằng đây là một ý tưởng hay.
Rainbolt

6
Giả sử, nó nhanh hơn. Chúng ta hãy chỉ định một ủy ban cho nó và chờ vài năm trong khi chúng ta quên mất mục đích của nó.
Conor O'Brien

Câu trả lời:


10

CJam, 43 39 36 35 byte

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

Điều này có vẻ dài. Tôi chắc chắn rằng tôi không đủ tối ưu hóa !

Làm thế nào nó hoạt động:

Ý tưởng cơ bản là phân chia đầu vào trên dòng mới, tính toán số lượng khoảng trắng hàng đầu trong mỗi dòng, sắp xếp và lấy số duy nhất, sao chép mảng đó và đảo ngược bản sao, phiên âm các số theo thứ tự ban đầu với hai mảng này và cuối cùng tạo thành chuỗi cuối cùng sử dụng thông tin này.

Phần dài nhất là tìm ra có bao nhiêu không gian hàng đầu trong mỗi dòng vì CJam không có cách dễ dàng để làm điều đó.

Mở rộng mã:

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

Và theo tinh thần của câu hỏi. Một bản mở rộng thực sự của mã:

                                          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 byte được lưu nhờ Martin và 1 byte nhờ Dennis

Dùng thử trực tuyến tại đây


1. {}#có một lỗi: nó trả về một số nguyên, nhưng nó sẽ trả về một Long. Trớ trêu thay, i(chuyển thành số nguyên) sửa lỗi này. 2. Vì ""#không có cùng một lỗi, nên _Sm0=#ngắn hơn một byte.
Dennis

@Dennis Yeah, lỗi thật kỳ lạ. Cảm ơn cách giải quyết!
Tối ưu hóa

2
vết lõm này trong bản mở rộng rất dễ đọc! Bạn nên đảo ngược nó!
DLeh

13

Python 2 - 137 131 byte

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

Đưa đầu vào với |thay vì \n.

Giải trình

Ba dòng đầu tiên khá đơn giản. Tạo một danh sách tất cả các dòng trong đầu vào, xác định một hàm cho bạn biết khoảng trắng hàng đầu của một chuỗi có bao nhiêu và tạo một danh sách sắp xếp các giá trị mà hàm phát ra cho mỗi dòng đầu vào.

Dòng cuối cùng là cách thú vị hơ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 nhờ :)
undergroundmonorail

1
Tất cả điều này có vẻ ổn trong python 3, nó sẽ giúp bạn tiết kiệm 2 byte (trả 2 cho ()tiết kiệm 4 cho raw_)
FryAmTheEggman

1
f(s)for s in inên map(f,i).
frageum

1
Một mảnh ma thuật: d=[];d+=set(L)là một phiên bản ngắn hơn của d=sorted(set(L)).
xnor

7

JavaScript, ES6, 113 103 101 byte

Tôi khá chắc chắn rằng điều này có thể được chơi golf ít nhất một chút nữa, nhưng ở đây đi.

Không bao giờ có thể nghĩ rằng sẽ có một giải pháp JS 101 byte, đánh bại 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]))

Điều này tạo ra một phương thức có tên fcó thể được gọi với chuỗi đầu vào. Nếu bạn đang ở trong một Firefox mới nhất, bạn có các chuỗi mẫu và bạn có thể gọi phương thức như

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

Nếu không, bạn cũng có thể gọi nó như

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

hoặc, thử đoạn trích dưới đây:

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>


Bạn có thể lưu một byte coupe bằng cách lưu trữ regex dưới dạng một biến, vì nó được sử dụng hai lần (bạn sẽ có thể thay thế \sbằng một ký tự khoảng trắng) và loại bỏ dấu ngoặc xtrong hàm thay thế.
NinjaBearMonkey

@hsl gee, cảm ơn! Tôi thậm chí không biết tại sao tôi đã viết (x): /
Trình tối ưu hóa

Bạn không cần cả hai bcphải không? Họ chỉ đề cập đến cùng một mảng.
Neil

5

Ruby, 63 byte

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

Điều này xác định một hàm không tên sẽ nhận và trả về một chuỗi. Bạn có thể gọi nó bằng cách nối thêm ["string here"]hoặc gán nó vào một biến, và sau đó gọi biến đó.

Cách thức hoạt động: s.scan(r=/^ */)đưa ra danh sách tất cả các không gian và cửa hàng hàng đầu regex rđể sử dụng sau này. uniqloại bỏ trùng lặp. sort... sắp xếp

Bây giờ bỏ qua đến cuối, l.zip(l.reverse)đưa ra một loạt các cặp chúng ta muốn thay thế. to_hbiến nó thành một hàm băm, diễn giải các cặp thành các cặp khóa-giá trị.

Bây giờ s.gsubthay thế tất cả các kết quả khớp của regex (tất cả các khoảng trắng hàng đầu) bằng cách sử dụng hàm băm đó làm bảng tra cứu để tìm sự thay thế.



2

Japt -R , 27 byte

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

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

Giải nén & Cách thức hoạt động

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

Làm thế nào nó thực sự hoạt động

                 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

Scala, 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'}}

Nó sẽ thêm một dòng mới vào cuối. Nếu tôi không phải bảo toàn khoảng trắng ở cuối dòng, tôi có thể đưa nó tới 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'}}

Ung dung:

      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 byte

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

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

Ít chơi gôn hơn:

$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 byte

Mã không được tối ưu hóa nên được lưu trữ trong $vbiến:

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

Đây là phiên bản chưa được chỉnh sửa và nhận xét:

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

Có lẽ tôi chưa bao giờ viết một cái gì đó quá bẩn. Tôi xấu hổ.


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

Phiên bản bị đánh cắp:

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

Kiểm tra


0

Perl 5, 112

111 + 1 cho -n( -Emiễn phí)

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

Tôi chắc chắn rằng nó có thể được thực hiện trong ít đột quỵ hơn, nhưng tôi không thấy làm thế nào vào lúc này.

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.