Einrückung umkehren

63

Ich habe gehört, dass Ihr Code schneller ausgeführt werden kann, wenn Sie ihn in umgekehrter Richtung einrücken, sodass der Compiler ihn wie ein Baummuster von der Spitze der "Zweige" nach unten verarbeiten kann. Dies ist hilfreich, da die Schwerkraft die Kompilierungszeit Ihres Codes verkürzt und die Effizienz der Datenstruktur verbessert. Hier ist ein Beispiel für Java-Scripting:

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

Aber aus irgendeinem Grund hat Notepad keine Einstellung, um dies automatisch zu tun, deshalb brauche ich ein Programm, um es für mich zu tun.

Beschreibung

Bei Einsendungen muss ein Code-Snippet als Eingabe verwendet, der Einzug umgekehrt und der resultierende Code ausgegeben werden.

Dies geschieht nach folgendem Verfahren:

  • Teilen Sie den Code in Zeilen auf. Jede Zeile beginnt mit null oder mehr Leerzeichen (es gibt keine Tabulatoren).

  • Finden Sie alle eindeutigen Einrückungsstufen im Code. Für das obige Beispiel wäre dies zum Beispiel

    0
    4
    8
    12
    
  • Kehren Sie die Reihenfolge dieser Liste der Einrückungsstufen um und ordnen Sie die umgekehrte Liste der ursprünglichen Liste zu. Dies ist schwer in Worten zu erklären, aber für das Beispiel würde es so aussehen

    0  — 12
    4  — 8
    8  — 4
    12 — 0
    
  • Wenden Sie diese Zuordnung auf den ursprünglichen Code an. In diesem Beispiel wird eine Zeile mit 0-Leerzeichen-Einrückung um 12 Leerzeichen eingerückt, 4 Leerzeichen werden zu 8 Leerzeichen usw.

Input-Output

Der Ein- und Ausgang kann nach Belieben bereitgestellt werden (STDIN / STDOUT, Funktionsparameter / Rückgabewert usw.); Wenn Ihre Sprache keine mehrzeilige Eingabe unterstützt (oder Sie es einfach nicht möchten), können Sie |stattdessen das Zeichen verwenden, um Zeilen zu trennen.

Die Eingabe besteht nur aus druckbaren ASCII- und Zeilenumbrüchen und enthält keine Leerzeilen.

Testfälle

Eingang:

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

Ausgabe: der obige Beispielcode.

Eingang:

a
  b
  c
d
   e
        f
  g
   h

Ausgabe:

        a
   b
   c
        d
  e
f
   g
  h

Eingang:

1
 2
  3
 2
1

Ausgabe:

  1
 2
3
 2
  1

Eingang:

  foo

Ausgabe:

  foo
Türknauf
quelle
21
Es ist "JavaScript" nicht "Java Scripting": /
Optimizer
75
@Optimizer Ich sehe, dass mein Ziel, mit den ersten beiden Absätzen so viele Menschen wie möglich zu verärgern, erreicht wurde. ;)
Türklinke
7
1! = So viele Leute wie möglich.
Optimierer
23
@JanDvorak Die gleichen Leute, die Zitate im MLA-Stil erfunden haben, halten dies für eine gute Idee.
Rainbolt
6
Angeblich ist es schneller. Warten wir ein paar Jahre, bis wir den Zweck vergessen haben.
Conor O'Brien

Antworten:

10

CJam, 43 39 36 35 Bytes

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

Das sieht zu lange aus. Ich bin sicher, ich optimiere nicht genug!

Wie es funktioniert:

Die Grundidee ist, die Eingabe in Zeilenumbrüchen zu teilen, die Anzahl der führenden Leerzeichen in jeder Zeile zu berechnen, eindeutige Zahlen zu sortieren und zu erhalten, dieses Array zu kopieren und die Kopie umzukehren, die ursprünglichen in der Reihenfolge befindlichen Zahlen mit diesen beiden Arrays zu transliterieren und dann das zu bilden letzte Zeichenfolge unter Verwendung dieser Informationen.

Der längste Teil besteht darin, herauszufinden, wie viele führende Leerzeichen in jeder Zeile vorhanden sind, da CJam keine einfache Möglichkeit bietet, dies zu tun.

Code-Erweiterung:

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

Und im Geiste der Frage. Eine echte Erweiterung des Codes:

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

Dank Martin 7 Byte und dank Dennis 1 Byte gespart

Probieren Sie es hier online aus

Optimierer
quelle
1. {}#hat einen Fehler: Es gibt eine Ganzzahl zurück, aber es sollte ein Long zurückgeben. Ironischerweise ibehebt (umgewandelt in eine Ganzzahl) dies. 2. Da ""#es nicht den gleichen Fehler gibt, _Sm0=#ist es ein Byte kürzer.
Dennis
@ Tennis Ja, der Bug ist komisch. Vielen Dank für die Problemumgehung!
Optimierer
2
Diese Einrückung in der Erweiterung ist so einfach zu lesen! Sie sollten es umkehren!
DLeh
13

Python 2 - 137 131 Bytes

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

Übernimmt die Eingabe mit |statt mit \n.

Erläuterung

Die ersten drei Zeilen sind ziemlich einfach. Erstellen Sie eine Liste aller Zeilen in der Eingabe, definieren Sie eine Funktion, die angibt, wie viel führendes Leerzeichen eine Zeichenfolge enthält, und erstellen Sie eine sortierte Liste der Werte, die die Funktion für jede Eingabezeile ausgibt.

Die letzte Zeile macht viel mehr Spaß.

                                 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
untergrundbahn
quelle
Bestätigt 137 :)
FryAmTheEggman
@ Frya danke :)
U-
1
Das alles scheint in Python 3 in Ordnung zu sein, was Ihnen 2 Bytes ersparen sollte (zahlen Sie 2 für ()4 für raw_)
FryAmTheEggman
1
f(s)for s in isollte sein map(f,i).
Feersum
1
Ein Stück Magie: d=[];d+=set(L)ist eine kürzere Version von d=sorted(set(L)).
Xnor
7

JavaScript, ES6, 113 103 101 Byte

Ich bin mir ziemlich sicher, dass dies zumindest ein bisschen weiter fortgeschritten sein kann, aber hier geht es weiter.

Hätte nie gedacht, dass es eine 101-Byte-JS-Lösung geben wird, die Python schlägt!

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

Dadurch wird eine Methode namens ferstellt, die mit der Eingabezeichenfolge aufgerufen werden kann. Wenn Sie in einem aktuellen Firefox arbeiten, haben Sie Vorlagenzeichenfolgen und können die Methode wie folgt aufrufen

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

Ansonsten kann man es auch gerne nennen

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

Oder probieren Sie das folgende Snippet:

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>

Optimierer
quelle
Sie können Coupes-Bytes speichern, indem Sie den regulären Ausdruck als Variable speichern, da er zweimal verwendet wird (Sie sollten ihn durch \sein Leerzeichen ersetzen können) und die Klammern xin der Ersetzungsfunktion entfernen .
NinjaBearMonkey
@hsl gee, danke! Ich weiß nicht einmal, warum ich schrieb (x): /
Optimizer
Du brauchst nicht beides bund coder? Sie beziehen sich sowieso nur auf dasselbe Array.
Neil
5

Ruby, 63 Bytes

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

Dies definiert eine unbenannte Funktion, die einen String annimmt und zurückgibt. Sie können es aufrufen, indem Sie es anhängen ["string here"]oder einer Variablen zuweisen und dann diese Variable aufrufen.

So funktioniert es: s.scan(r=/^ */)Zeigt eine Liste aller führenden Bereiche und Speicher an, in denen Regex rzur späteren Verwendung gespeichert ist . uniqbeseitigt Duplikate. sort... sortiert.

Springen Sie nun zum Ende und l.zip(l.reverse)geben Sie eine Reihe von Paaren an, die ersetzt werden sollen. to_hverwandelt das in einen Hash und interpretiert die Paare als Schlüssel-Wert-Paare.

s.gsubErsetzen Sie nun alle Übereinstimmungen des regulären Ausdrucks (alle führenden Leerzeichen), indem Sie diesen Hash als Nachschlagetabelle verwenden, um den Ersatz zu finden.

Martin Ender
quelle
2

Japt -R , 27 Bytes

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

Probieren Sie es online!

Ausgepackt und wie es funktioniert

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

Wie es wirklich funktioniert

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

Am Ende wird eine zusätzliche Zeile eingefügt. Wenn ich keine Leerzeichen am Ende der Zeile beibehalten musste, kann ich es auf 167 bringen:

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'
    }
      }
Chad Retz
quelle
1

PowerShell , 112 Byte

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

Probieren Sie es online!

Weniger golfen:

$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
mazzy
quelle
0

Haskell, 116

import Data.List
f s|l<-map(span(==' '))$lines s=unlines[k++b|(a,b)<-l,(k,r)<-reverse>>=zip$sort$nub$map fst l,r==a]
stolzer haskeller
quelle
0

PHP - 173 Bytes

Der nicht optimierte Code sollte in der $vVariablen gespeichert werden:

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

Hier ist die ungolfed und kommentierte Version:

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

Ich habe wahrscheinlich noch nie etwas so dreckiges geschrieben. Ich schäme mich.

Schwarzes Loch
quelle
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);

Ungolfed-Version:

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

Testen

Der Typ mit dem Hut
quelle
0

Perl 5, 112

111 + 1 für -n( -Eist kostenlos)

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

Ich bin mir sicher, dass es mit weniger Hüben möglich ist, aber ich verstehe nicht, wie.

msh210
quelle