# Indent your code according to Fibonacci

Okay, so I saw this in a meme and decided it'd be the perfect code golf challenge:

I prefer to increase the side of my indents according to the Fibonacci sequence:

class Kls
def method
t = Time.now
if t.hour >= 12
puts "It's afternoon"
if t.hour == 18
puts "It's time for your meal of:"
%w(bread sausage brocolli milk).each do |food|
"Some #{food}"
end
end
else
puts "It's not afternoon"
end
end
end


This means each line is indented by the sum of the spaces indented in the previous indentation-level. The first indention-level is indented by one space, then subsequent indention-levels are indented by 1, 2, 3, 5, 8, 13, 21, etc additional spaces.

## The challenge

Given a multi-line string with multiples of 2 spaces as indentation, convert it to a Fibonacci indented multi-line string instead.
This means every line with 0 indented spaces will remain 0 spaces; every line with 2 indented spaces will become 1 instead (sum of the first two Fibonacci numbers 0+1 = 1); every line with 4 indented spaces will becomes 2 instead (sum of the first three Fibonacci numbers 0+1+1 = 2); etc. So the number of indentations can be calculated as follows:

• Get the current amount of leading spaces (guaranteed to be a multiple of 2, so [0,2,4,6,8,...])
• Divide this by 2, so we have our 0-indexed numbers (let's call it n)
• Get the first [0,n] (0-indexed) Fibonacci numbers
• Sum that sub-sequence together, and use that amount of leading spaces instead in the output

For example, for the output above, the input would have been:

class Kls
def method
t = Time.now
if t.hour >= 12
puts "It's afternoon"
if t.hour == 18
puts "It's time for your meal of:"
%w(bread sausage brocolli milk).each do |food|
"Some #{food}"
end
end
else
puts "It's not afternoon"
end
end
end


If we take a look at the line containing "Some #{food}":

In the input it has 10 amount of leading spaces, so n will be 10/2 = 5. The first [0,5] Fibonacci numbers are: [0,1,1,2,3,5]. When we take the sum of that list (0+1+1+2+3+5) the new amount of leading spaces in the output would be 12.

The amount of indented spaces in the output for every 2 indented spaces in the input will be [0, 1, 2, 4, 7, 12, 20, 33, 54, 88, ...] A000071 on oeis.org (except for the first 0).

## Challenge rules:

• The space-indentation of the input is guaranteed to be multiples of 2 ([0,2,4,6,8,...])
• The input is guaranteed to not contain more than 1 consecutive space elsewhere (except for the leading indentation of course)
• Use whatever language you like
• Input should be a multi-line string (so no, string-lists/arrays aren't allowed)
• Output should also be a multi-line string (either printed or returned as string)
• Your method should work for deeper-indented Fibonacci indented multi-line strings than the example
• This is , so try to do it in the fewest bytes possible.

Input:

this
is
one
of
the
tests
!


Output:

this
is
one
of
the
tests
!


Input:

      And
how
this ?


Output:

    And
how
this ?


Input:

                    20 spaces?


Output:

                                                                                                                                               20 spaces?

• What if there's 2 or more spaces in the code that aren't part of the indentation? – Blue Aug 22 '18 at 11:21
• @AJFaraday I took the liberty of editing your challenge so it can be re-opened. The challenge in general is a nice idea and I personally like it; it was just not properly explained. If you see anything incorrect in what I've edited, let me know. – Kevin Cruijssen Aug 23 '18 at 9:19

# 05AB1E (legacy), 22 21 bytes

|εDgsðÛ©g-;LÅfOð*®J}»


Try it online.

21 bytes alternative using the formula $Fib(\frac{n}{2}+2)-1$ instead of $\sum_{i=1}^{i=\frac{n}{2}}{Fib(i)}$ :
(Credit to @JonathanAllan's Jelly answer for this formula.)

|εDgsðÛ©g-;ÌÅf<ð*®J}»


Try it online.

Explanation:

|                        # Take the input split by newlines
ε                  }    # Map each line to:
Dg                     #  Duplicate the line and take its length
s                    #  Swap so the duplicated line is at the top of the stack again
ðÛ                  #  Remove all leading spaces
©                 #  Store the result in the register (without popping)
g                #  Take its length as well
-               #  Subtract both lengths from each other
;              #  Halve it, because they are multiples of 2 indented spaces
L             #  Create a list in the range [1, n]
Åf           #  Get the i'th Fibonacci number for each
O          #  And sum them together
ð*        #  Have that many space characters
®J      #  And join them with the saved string from the register
»    # And finally print the mapped list with new-lines


# Python 2, 111109100 95 bytes

g=lambda n:n<1or g(n-2)+g(n-4)
def f(I):
for l in I:L=l.lstrip();print~-g(len(l)-len(L))*' '+L


Try it online!

Saved:

• -5 bytes, thanks to ovs.
• g can be g=lambda n:n<1or g(n-2)+g(n-4). – ovs Aug 22 '18 at 11:53
• and you can use strip instead of lstrip as trailing whitespace is insignificant. – ovs Aug 22 '18 at 11:56
• @ovs But it would affect len(l)-len(L). – user202729 Aug 22 '18 at 11:58
• @ovs, Thanks :) – TFeld Aug 22 '18 at 12:16

# Husk, 23 bytes

mȯF+M(R' !∫Θİf→½L)↕=' ¶


Try it online!

### Explanation

m(F+M(R' !∫Θİf→½L)↕=' )¶  -- full program
¶  -- lines
m(                    )   -- map
↕='     -- | split on first non-space
M(           )        -- | with the spaces
L         -- | | length
½          -- | | halve
→           -- | | increment
İf            -- | | Fibonacci numbers: [1,1,2,3,5..]
Θ              -- | | prepend 0: [0,1,1,2,3,5..]
∫               -- | | cumulative sums: [0,1,2,4,7,12..]
!                -- | | 1-based index
R'                  -- | | replicate that many spaces
F+                      -- | join

• This answer appears to have three levels of indent with only 1 space, then continuing in Fibonacci. – AJFaraday Aug 22 '18 at 12:29
• I had the same mistake at first. Instead of having the indexed Fibonacci amount of spaces in the result, it's actually the sum of the first [1,n] amount of Fibonacci numbers. So instead of [0,1,1,2,3,5,8,...] indented spaces, it's (sum_each([0,[0,1],[0,1,1],[0,1,1,2],[0,1,1,2,3],[0,1,1,2,3,5],[0,1,1,2,3,5,8],...]) -> [0,1,2,4,7,12,20,...] indented spaces instead. – Kevin Cruijssen Aug 22 '18 at 12:35
• @KevinCruijssen: I was able to fix it w/o additional bytes, thanks a lot! – ბიმო Aug 22 '18 at 13:21

# Retina 0.8.2, 37 bytes

m^

+( +	)( +)
$2$1$1 *  Try it online! Warning: Lots of white space. Explanation: m^  Prefix each line with space tab space tab. These keep track of the previous and current Fibonacci number. +( + )( +)$2$1$1


For each two spaces of the original indentation, compute the next Fibonacci number by summing the previous two.

 	 *



Subtract 1 from the result and delete the previous Fibonacci number.

Ỵµ=⁶i0‘H‘ÆḞ’⁶ẋ;t⁶$)Y  Try it online! # Explanation Let $x$ be the 1-indexing index of the first non-whitespace character ($1,3,5,7,\dots$). Then the new indent is $$F_{(x+1)/2+1}-1$$ where $F$ is the Fibonacci function. • Save 1 from both with Ỵµ...)Y – Jonathan Allan Aug 22 '18 at 14:24 # Jelly, 17 bytes Ỵµwt©⁶$HÆḞ€⁶ẋ;®)Y


A full program which prints the result.

Try it online!

### How?

The indentations required for a line of the output is $Fib(\frac{s}{2}+2)-1$ where $s$ is the number of spaces in the line of the input, and:

$$Fib(\frac{s}{2}+2)-1=\sum_{i=1}^{i=\frac{s}{2}}{Fib(i)}$$

($i$ could also start at $0$ since $Fib(0)=0$)

Ỵµwt©⁶$HÆḞ€⁶ẋ;®)Y - Main Link: list of characters Ỵ - split at newlines µ ) - for each line:$           -   last 2 links as a monad:
⁶            -     literal space character
t              -     trim from both sides
w               -   first index of that substring in the line
H          -   halve (this is (s+1)/2)
ÆḞ€       -   Fibonacci of €ach (using an implicit range [1,2,...,s/2]
-                      where the (s+1)/2 is floored to s/2)
⁶      -   literal space character
ẋ     -   repeat (vectorises) (e.g. [1,1,2,3,5] -> [[' '],[' '],[' ',' '],[' ',' ',' '],[' ',' ',' ',' ',' ']]
®   -   recall from register
;    -   concatenate
Y - join with newline characters
- implicit print
-  ...smashes, so e.g. [[' '],[' '],[' ',' '],['x']] is just "    x"


# Java 11, 150 bytes

s->{for(var l:s.split("\n"))System.out.println(" ".repeat(f(l.length()-(l=l.stripLeading()).length())-1)+l);};int f(int n){return n<1?1:f(n-2)+f(n-4);}


Try it online (NOTE: Both String.repeat(int) and String.stripLeading() are emulated as repeat(String,int) and stripLeadingE(String) respectively, because Java 11 isn't on TIO yet.)

Explanation:

s->{                   // Method with String parameter and no return-type
for(var l:s.split("\n"))
//  Loop over the lines of the input:
System.out.println(//   Print with trailing new-line:
" ".repeat(      //    Repeat a space this many times:
f(          //     Call the separated (recursive) method f with the parameter:
l.length()//      The length of the line,
//      minus the length of the line without leading spaces
)-1         //     minus 1
)+l);};          //    And append the line without leading spaces

int f(int n){          // Separated method with integer as both parameter and return-type
return n<1?          //  If the input is 0 or lower:
1            //   Return 1
:             //  Else:
f(n-2)+f(n-4);}
//   Return a recursive call to n-2 plus a recursive call to n-4


# Japt v2.0a0, 20 19 bytes

r/^ +/m@ÓMgXÊz ÄÄ)ç


Try it

## Explanation

r                        :Replace
/^ +/m                  :Global, multiline regular expression matching one or more spaces at the start of each line
_                 :Pass each match through a function
Ê                :  Length
z               :  (Floor) divide by 2
õ             :  Range [0,result]
@          :  Map each X
MgX       :    Xth Fibonacci number
Ã      :  End mapping
ç     :  Repeat <space> that many times


# JavaScript (Node.js), 87 81 bytes

x=>x.replace(/^ */gm,s=>" ".repeat((g=(n,a=b=1)=>n?g(n-2,b,b+=a):b-1)(s.length)))


Try it online!

## For small indent levels (up to 15), 61 bytes using approximation:

x=>x.replace(/^ */gm,s=>" ".repeat(1.272**s.length*1.171-.5))


Use 1.27202 ** s.length * 1.17082 - .5 for indents up to 21 levels

# Perl 6, 62 bytes

*.trans(/[\n|^]' '+/=>{"\n"~' 'x(1,1,*+*...*)[\$/.ords/2+1]-1})


Try it online!