Goodness, it's covered in tabs!

K5, 53 45 bytes

{{,/(b+a&~b:x*&\a:9=y){$[x;x#" ";y]}'y}[x]'y}

In action:

  {{,/(b+a&~b:x*&\a:9=y){$[x;x#" ";y]}'y}[x]'y}[4;(,"a";"\t\tb\tc";,"d")]
(,"a"
 "        b c"
 ,"d")

I just want the record to show that this question is morally reprehensible.


Perl, 23 bytes

22 bytes code + 1 bytes command line

Hopefully not too cheeky to assume the numeric input can be given via the -i parameter! Ensure to replace \t in the below code with the actual tab character.

s/\G\t/$"x$^I/ge;y/\t/ /

Usage example:

printf "a\n\t\tb\tc\nd" | perl -p entry.pl -i4

Or for convenience:

printf "a\n\t\tb\tc\nd" | perl -pe 's/\G\t/$"x$^I/ge;y/\t/ /' -i4

Explanation:

Using the -p argument will execute the program for every line in the input, then print the result at the end.

In the above example, the regex substitution replaces \G\t with " "x4 (a space repeated four times). \G is a little-known regex construct which matches either the position of first match if the first iteration, or from the position of the previous match if not the first iteration, meaning it will only replace all tabs at the start of the string, and will do so one-by-one. The y/\t/ / simply replaces all remaining tabs with spaces.


CJam, 30 24 23 bytes

q{_9=NA=Seasi*' ?@?:N}/

I usually refuse to post malicious code on the internet…

This is a full program that reads the string from STDIN and the number as a command-line argument.

Try it online in the CJam interpreter.

How it works

q                        Read all input from STDIN.
 {                   }/  For each character C in the input:
  _9=                      Push 1 if C is a tab and 0 otherwise.
     NA=                   See below.
        Seasi*             Push a string of W spaces, where W is the integer from
                           the command-line arguments.
              '            Push a spaces character.
                ?          Select the string if NA= pushed a truthy value, the
                           single space otherwise.
                 @         Rotate C on top of the stack.
                  ?        Select the string of spaces or the single space if _9=
                           pushed 1, the character C otherwise.
                   :N      Save the result in N.

What NA= does:

  • For the first character, N will contain its default value, i.e., the string "\n".

    For all subsequent characters, N will contain the result of the last iteration, i.e., the last character from input, a space character or a string of one or more spaces.

  • If N is a string, NA= selects the element at index 10 of N (wrapping around). The result will be a space or a linefeed character. Both are truthy.

    If N is a character, NA= pushes 1 for a linefeed and 0 otherwise.

  • Because of the above, NA= will push a truthy value for the first character, a character preceded by a linefeed or a character preceded by a string of spaces (indentation that has already been replaced).

    In all other cases (including a tabulator that has been replace by a space character), NA= will push a falsy value.