# Undress a string

We already now how to strip a string from its spaces.

However, as proper gentlemen/ladies, we should rather undress it.

Undressing a string is the same as stripping it, only more delicate. Instead of removing all leading and trailing spaces at once, we remove them one by one. We also alternate between leading and trailing, so as not to burn steps.

Example, starting with " codegolf " (five leading and trailing spaces):

codegolf
codegolf
codegolf
codegolf
codegolf
codegolf
codegolf
codegolf
codegolf
codegolf
codegolf

1. First output the string unchanged. Then, output every step. Begin by removing a leading space (if applicable - see rule #2).

2. The input may have a different number of leading and trailing spaces. If you run out of spaces on one side, keep undressing the other until the string is bare.

3. The input may have no leading nor trailing spaces. If that's the case, output it as-is.

4. Use PPCG's default I/O methods. PPCG Default loopholes are forbidden.

5. Undefined behaviour on empty input, or input that only contains spaces, is OK.

6. You can assume that the string will only contain characters from the ASCII printable space (0x20 to 0x7E).

Examples - spaces are replaced by dots . for better readability:

4 leading spaces, 5 trailing: "....Yes, Sir!....."
....Yes, Sir!.....
...Yes, Sir!.....
...Yes, Sir!....
..Yes, Sir!....
..Yes, Sir!...
.Yes, Sir!...
.Yes, Sir!..
Yes, Sir!..
Yes, Sir!.
Yes, Sir!

6 leading, 3 trailing: "......Let's go golfing..."
......Let's go golfing...
.....Let's go golfing...
.....Let's go golfing..
....Let's go golfing..
....Let's go golfing.
...Let's go golfing.
...Let's go golfing
..Let's go golfing
.Let's go golfing
Let's go golfing

Hello..
Hello.
Hello

World

.....................a.....
....................a.....
....................a....
...................a....
...................a...
..................a...
..................a..
.................a..
.................a.
................a.
................a
...............a
..............a
.............a
............a
...........a
..........a
.........a
........a
.......a
......a
.....a
....a
...a
..a
.a
a

• From Sandbox: codegolf.meta.stackexchange.com/a/13765/71426 – Nathan.Eilisha Shiraini Sep 21 '17 at 9:19
• Can we assume that there will be at least one non-space character? – Martin Ender Sep 21 '17 at 9:34
• @KevinCruijssen You only have to handle ASCII characters in the printable space (0x20 to 0x7E). The other ones are Undefined Behavior. – Nathan.Eilisha Shiraini Sep 21 '17 at 10:54
• @KevinCruijssen Yes, there will be no test case like this. There will be no things like " test\r " or " \v test" either. – Nathan.Eilisha Shiraini Sep 21 '17 at 10:57
• Is this a valid test case ".....................a....."? If so I suggest to add it since some answers seems to fail this kind of test. (dots are for better readability of course) – Cinaski Sep 21 '17 at 13:54

(b%e)
t=last
b(' ':s)=s
b l=l
e l|t l>' '=l|1>0=init l
(g%h)l=l:t((h%g$g l):[t$(h%g$h l):[[]|h l==l]|g l==l]) Try it online! b removes leading space if there is a leading space e removes trailing space if there is a trailing space % switches between b and e # Haskell, 86 bytes (f#g) r=reverse f(' ':s)=s f s=g s g=r.f.r (a#b)s=s:[x|last s<'!'||s<"!",x<-(b#a)$a s]

Try it online! Usage: (f#g) " test " yields a list of strings.

### Explanation

• Function f removes a leading space from a given string. If there is no leading space, it calls function g.
• Function g reverses the string, calls f and reverses back. This removes a trailing space if there is one, and an leading space otherwise.
• If a string has neither leading nor trailing spaces, then f and g diverge, so this needs to be checked before.
• The main function # is initialized with f as first and g as second argument. The third argument s is the input string, which is appended to the recursively computed list of results:
• If s has no leading or trailing spaces, then last s<'!'||s<"!" is false and the list of results empty.
• Otherwise the function given as first argument is applied to s and # is applied recursively with f and g exchanged.

# D, 142 140 bytes

import std.stdio;void u(T)(s){s.writeln;while(s[0]<33||s[$-1]<33){if(s[0]<33){s=s[1..$];s.writeln;}if(s[$-1]<33){s=s[0..$-1];s.writeln;}}}

Try it online!

This is a port of HatsuPointerKun's C++ answer.

# Julia, 138 bytes

a(s)=' ' in s?s[1]==' '?(println(s);z(s[2:end])):z(s[1:end]):print(s)
z(s)=' ' in s?s[end]==' '?(println(s);a(s[1:end-1])):a(s[1:end]):print(s)

Not sure if there is a way to substitute another character for end, but if there was that would probably save some bytes.

• Welcome to the site! – James Sep 28 '17 at 19:56

# Jq 1.5, 149 116 bytes

def G(p):if p==[]then. else sub(p[0];"")as$n|if.!=$n then.,($n|G(p|reverse))else($n|G(p[1:]))end end;G(["^ "," $"]) Expanded def G(p): if p==[] then . # stop when no patterns remain else sub(p[0];"") as$n            # use first pattern
| if .!=$n # if we removed something then ., ($n|G(p|reverse))     #   return result and switch patterns
else ($n|G(p[1:])) # otherwise remove failed pattern end end ; G(["^ ","$"])

Sample Run

$jq -MRr 'def G(p):if p==[]then. else sub(p[0];"")as$n|if.!=$n then.,($n|G(p|reverse))else($n|G(p[1:]))end end;G(["^ ","$"])' <<<'     codegolf     '
codegolf
codegolf
codegolf
codegolf
codegolf
codegolf
codegolf
codegolf
codegolf
codegolf
codegolf

$wc -c <<<'def G(p):if p==[]then. else sub(p[0];"")as$n|if.!=$n then.,($n|G(p|reverse))else($n|G(p[1:]))end end;G(["^ ","$"])'
116

# Kotlin, 151 150 bytes

{var v=it
var c={println(v)}
while(0<((if(v[0]<'!'){c()
v=v.substring(1)
1}else 0)+if(v.endsWith(' ')){c()
v=v.slice(0..v.length-2)
1}else 0
)){}
c()}

## Beautified

{
var v = it
var c={println(v)}
while ( 0 <(
(if (v[0] < '!') {
c()
v = v.substring(1)
1
} else 0)
+
if (v.endsWith(' ')) {
c()
v = v.slice(0..v.length-2)
1
} else 0
)){}
c()
}

## Test

/** Shows spaces, just helps viewing answer. */
fun println(i: String) {
for (c in i) {
if (c == ' ') {
print('~')
} else {
print(c)
}
}
print('\n')
}
var u: (String) -> Unit =
{var v=it
var c={println(v)}
while(0<((if(v[0]<'!'){c()
v=v.substring(1)
1}else 0)+if(v.endsWith(' ')){c()
v=v.slice(0..v.length-2)
1}else 0
)){}
c()}

fun main(args: Array<String>) {
u("      Let's go golfing   ")
}

# Edits

-1 -> x == ' ' => x < '!' Jonathan French

• – Jonathan Frech Sep 23 '17 at 16:13

This is not a successful contender, because it works only for len(left whitespace) between [len(right whitespace), len(right whitespace)+1]. Anyway, just for the fun of it:

Python 3, 56 bytes:

def f(a,e=0):print(a);a[e]<'!'and f(a[e+1:e or None],~e)

# GolfScript - 46 bytes

'
'+{.(32={.1}{;.0}if\);)32={'
'+\1}{;0}if|}do

### Explanation

'\n'+    Adds endline to the argument
{.       Starts do loop and duplicates the top of the stack
(32=     Is the first character a ' '?
{.1}     It is, duplicate result and push 1
{;.0}if  It isn't, remove cut string, duplicate and push 0
\        The number (0 or 1) we pushed before sinks one position
);)      Obtains the last character of the string
32=      Is it a space?
{'\n'+\1} Add a new line, make the number we pushed before rise
one position, and push another 1
{;0}if   Same as before
|        'Or' between the two numbers we pushed before
}do      If at least one of them was 1, repeat!

### Test

It works with dots by replacing 32 with 46.

Input: ...test..

Output:

...test..
..test..
..test.
.test.
.test
test

# Japt-R, 18 bytes

ÈrYg"^  $"ò}hUÊN â Try it # Stax, 16 bytes ùG⌐♦ò⌡╩d♪º"╪8·`; Run and debug it ### Procedure: • Alternate replacing regexes "^ " and "$" with "". Do this n times where n is the length of the input.
• Remove duplicate values.

# Perl 5-n, 33 bytes

(s/^ //&&say)|(s/ \$//&&say)&&redo

Try it online!