[Question]
  [
I've heard that your code can run faster if you indent it in reverse, so that the compiler can process it like a tree design pattern from the very top of the "branches" down. This helps because gravity will speed up the time it takes for your code to be compiled, and the data structure efficiency is improved. Here's an example, in 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;
            }
```
But for some reason Notepad doesn't have a setting to do this automatically, so I need a program to do it for me.
# Description
Submissions must take a code snippet as input, reverse the indentation, and output the resulting code.
This is done by the following procedure:
* Split the code up into lines. Each line will start with zero or more spaces (there will be no tabs).
* Find all unique indentation levels in the code. For example, for the above example, this would be
```
0
4
8
12
```
* Reverse the order of this list of indentation levels, and map the reversed list to the original list. This is hard to explain in words, but for the example, it would look like
```
0  — 12
4  — 8
8  — 4
12 — 0
```
* Apply this mapping to the original code. In the example, a line with 0-space-indentation would become indented by 12 spaces, 4 spaces would become 8 spaces, etc.
# Input / Output
The input and output can be provided however you would like (STDIN/STDOUT, function parameter/return value, etc.); if your language does not support multiline input (or you just don't want to), you can use the `|` character to separate lines instead.
The input will consist of only printable ASCII + newlines, and it will not contain empty lines.
# Test cases
Input:
```
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;
}
```
Output: the example code above.
Input:
```
a
  b
  c
d
   e
        f
  g
   h
```
Output:
```
        a
   b
   c
        d
  e
f
   g
  h
```
Input:
```
1
 2
  3
 2
1
```
Output:
```
  1
 2
3
 2
  1
```
Input:
```
  foo
```
Output:
```
  foo
```
  
[Answer]
# 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()
```
Takes input with `|` instead of `\n`.
**Explanation**
The first three lines are fairly straightforward. Make a list of all the lines in the input, define a function that tells you how much leading whitespace a string has, and make a sorted list of values that function spits out for each line of input.
The last line is way more fun.
```
                                 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
```
[Answer]
# CJam, ~~43 39 36~~ 35 bytes
```
qN/_{_Sm0=#}%___&$_W%er]z{~S*@+>N}%
```
~~This looks toooo long. I am sure I am not *Optimizing* enough!~~
How it works:
Basic idea is to split the input on newline, calculate the number of leading spaces in each line, sort and get unique numbers, copy that array and reverse the copy, transliterate the original in-order numbers with this two arrays and then finally form the final string using this information.
The lengthiest part is to figure out how many leading spaces are there in each line as CJam does not have an easy way of doing it.
Code expansion:
```
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";
```
And in the spirit of the question. A real expansion of the code:
```
                                          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 bytes saved thanks to Martin and 1 byte thanks to Dennis
[Try it online here](http://cjam.aditsu.net/)
[Answer]
# JavaScript, ES6, ~~113 103~~ 101 bytes
~~I am pretty sure this can be golfed at least a little further, but here goes.~~
Never would have thought that there will be a 101 bytes JS solution, beating 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]))
```
This creates a method named `f` which can be called with the input string. If you are in a latest Firefox, you have template strings and you can call the method like
```
f(`a
  b
  c
d
   e
        f
  g
   h`)
```
Otherwise, you can also call it like
```
f("a\n\
  b\n\
  c\n\
d\n\
   e\n\
        f\n\
  g\n\
   h")
```
or, try the snippet below:
```
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>
```
[Answer]
# Ruby, 63 bytes
```
->s{l=s.scan(r=/^ */).uniq.sort;s.gsub r,l.zip(l.reverse).to_h}
```
This defines an unnamed function which takes and returns a string. You can call it by appending `["string here"]` or by assigning it to a variable, and then calling that variable.
How it works: `s.scan(r=/^ */)` gives a list of all leading spaces and stores that regex in `r` for later use. `uniq` eliminates duplicates. `sort`... sorts.
Now skip to the end, `l.zip(l.reverse)` gives an array of pairs we want to substitute. `to_h` turns that into a hash, interpreting the pairs as key-value pairs.
Now `s.gsub` replaced all matches of the regex (all leading spaces) by using that hash as a look up table to find the replacement.
[Answer]
## [Pyth](https://github.com/isaacg1/pyth) 39
```
L-/bd/rb6dJcz\|KS{mydJFNJ+*d@_KxKyN>NyN
```
[Try it online.](http://isaacg.scripts.mit.edu/pyth/index.py)
Uses the `|` delimiter option.
[Answer]
# [Japt](https://github.com/ETHproductions/japt) `-R`, 27 bytes
```
·
mâ\S
Vâ n
Ëx2 iSpWg~WbVgE
```
[Try it online!](https://ethproductions.github.io/japt/?v=2.0a0&code=twpt4lxTClbiIG4Ky3gyIGlTcFdnfldiVmdF&input=LVIKJ2EKICBiCiAgYwpkCiAgIGUKICAgICAgICBmCiAgZwogICBoJw==)
### Unpacked & How it works
```
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
```
### How it *really* works
```
                 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
```
[Answer]
# 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]
```
[Answer]
# 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'}}
```
It will add an extra newline at the end. If I did not have to preserve spaces at the end of the line, I can get it to 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'
    }
      }
```
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), 112 bytes
```
$x=@($args|sls '(?m)^ *'-a|% m*|% v*|sort -u)
[regex]::Replace($args,'(?m)^ *',{$x[-1-$x.IndexOf($args.Value)]})
```
[Try it online!](https://tio.run/##lZNPb5swGMbv/hTPWjogg2pZb63Yctmhp0k77FK1E39egiUwmW1aqoTPntkQUGC5zBK2efz8jN8HeVe/kVQFleXRyRFhf3TaaOM5sdyqgyoVXO9b5b9g5Ybx4QbVynSvq4OqpUbY@OxJ0pba5/v7n7Qr45QGMpioYO@0T@E6dNrbR5FR@yMfHLe/4rIh/7nzjx1jG4@xwNu4bM3whQF3dlgzdxMYDejVu2HJqr51u27guv6JA/K6nvzDfFyLjZKYJ2WZ6UG261tuZlv7Vkzk0CzRI4YZNcsSs0jPFGcfyBuRal4L5DzxhI99D73GErFJdB0gscPDtNVbwUuCF4YCX/F59I/NcrraGSR@mC3YzZK5lOBTZM1zlefwjDmK8ChyLrh@X37DNkm6kQJX36Ws5Yer@RYdm89OZnOibpHVFObFEM6L@p8w/gnhrPh50ZeLvVjcsqhFEou4B5/9yz4OuDkdzEnrjAI41O4o1ZSZYzm/hxVJqim1ET6am9T7zvWQ/kxQr1@PwDVMdHVVkdDQBVcouSDoGhlX5k69Y/Ap1h3/Ag "PowerShell – Try It Online")
Less golfed:
```
$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
```
[Answer]
## PHP - 173 bytes
The unoptimized code should be stored in the `$v` variable:
```
<?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);
```
Here is the ungolfed and commented 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);
```
I've probably never written something so dirty. I'm ashamed.
[Answer]
## 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);
```
### Testing
```
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);
```
```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre><code id="i">
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;
}
</code></pre>
```
```
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);
```
```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre><code id="i">
a
  b
  c
d
   e
        f
  g
   h
</code></pre>
```
```
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);
```
```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre><code id="i">
1
 2
  3
 2
1
</code></pre>
```
```
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);
```
```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre><code id="i">
  foo
</code></pre>
```
[Answer]
# Perl 5, 112
111 + 1 for `-n` (`-E` is free)
```
@{$.[$.]}=/( *)(.*)/;++$_{$1}}{map$_{$_[$#_-$_]}=$_[$_],0..(@_=sort keys%_);say$_{$.[$_][0]}.$.[$_][1]for 0..$.
```
I'm sure it can be done in fewer strokes, but I don't see how at the moment.
]