逆インデント


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

しかし、何らかの理由で、メモ帳にはこれを自動的に行う設定がないため、それを行うプログラムが必要です。

説明

提出には、入力としてコードスニペットを使用し、インデントを反転し、結果のコードを出力する必要があります。

これは、次の手順で実行されます。

  • コードを行に分割します。各行はゼロ個以上のスペースで始まります(タブはありません)。

  • コード内のすべての一意のインデントレベルを見つけます。たとえば、上記の例では、これは

    0
    4
    8
    12
    
  • このインデントレベルのリストの順序を逆にし、逆のリストを元のリストにマッピングします。これは言葉で説明するのは難しいですが、例では、次のようになります

    0  — 12
    4  — 8
    8  — 4
    12 — 0
    
  • このマッピングを元のコードに適用します。この例では、0スペースのインデントがある行は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」ではなく「JavaScript」:/
オプティマイザー14

75
@Optimizer最初の2つのパラグラフでできるだけ多くの人々を激怒させるという私の目標は達成されたと思います。;)
ドアノブ

7
1!=できるだけ多くの人。
オプティマイザー14

23
@JanDvorak MLAスタイルの引用を発明したのと同じ人は、これが良い考えだと考えています。
レインボルト14

6
おそらく、それは高速です。委員会を割り当てて、その目的を忘れて数年待ちましょう。
コナーオブライエン14

回答:


10

CJam、43 39 36 35バイト

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

これは長すぎます。最適化が十分ではないと確信しています!

使い方:

基本的な考え方は、入力を改行で分割し、各行の先頭のスペースの数を計算し、一意の番号を並べ替えて取得し、その配列をコピーしてコピーを逆にし、この2つの配列で元の順序番号を音訳してから、最終的にこの情報を使用した最終文字列。

最も長い部分は、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";

Martinのおかげで7バイト、Dennisのおかげで1バイト節約

こちらからオンラインでお試しください


1. {}#バグがあります:整数を返しますが、Longを返す必要があります。皮肉なことに、i(整数にキャスト)これを修正します。2. ""#同じバグがないため、_Sm0=#1バイト短くなります。
デニス14

@デニスうん、バグは奇妙だ。回避策をありがとう!
オプティマイザー14

2
拡張のこのインデントは読みやすいです!逆にする必要があります!
DLeh 14

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

説明

最初の3行はかなり簡単です。入力内のすべての行のリストを作成し、文字列の先頭の空白の量を示す関数を定義し、関数が入力の各行に対して吐き出す値のソートされたリストを作成します。

最後の行はもっと楽しいです。

                                 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ありがとう:)
地下

1
これは、すべて(のための2を支払うあなたに2つのバイトを保存する必要のあるパイソン3に罰金だ()ため4保存raw_
FryAmTheEggman

1
f(s)for s in iする必要がありますmap(f,i)
feersum

1
魔法のかけら:d=[];d+=set(L)はの短縮版ですd=sorted(set(L))
xnor 14

7

JavaScriptを、ES6、113の103 101バイト

これは少なくとももう少しゴルフできると確信していますが、ここに行きます。

Pythonを破って101バイトのJSソリューションがあるとは思わなかったでしょう!

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>


正規表現は2回使用されるため(\sスペース文字で置換できるはずです)、変数として正規表現を保存xし、replace関数で括弧を削除することにより、クーペバイトを保存できます。
NinjaBearMonkey

@hsl gee、ありがとう!なぜ書いたのかさえわからない(x):/
オプティマイザー14

あなたは両方bを必要とcしませんか?とにかく同じ配列を参照するだけです。
ニール

5

ルビー、63バイト

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

これは、文字列を受け取って返す無名の関数を定義します。["string here"]それを変数に追加または割り当てることで呼び出してから、その変数を呼び出すことができます。

仕組み:s.scan(r=/^ */)すべての先行スペースのリストを提供しr、後で使用するために正規表現を格納します。uniq重複を排除します。sort...並べ替えます。

最後にスキップして、l.zip(l.reverse)置換したいペアの配列を指定します。to_hこれをハッシュに変換し、ペアをキーと値のペアとして解釈します。

次にs.gsub、そのハッシュをルックアップテーブルとして使用して置換を見つけることにより、正規表現のすべての一致(すべての先行スペース)を置換しました。



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

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

最後に余分な改行が追加されます。行の最後にスペースを保持する必要がなかった場合、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'}}

ゴルフをしていない:

      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.