48
\$\begingroup\$

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

0 leading, 2 trailing: "Hello.."
Hello..
Hello.
Hello

0 leading, 0 trailing: "World"
World

21 leading, 5 trailing: ".....................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
a

A gentleman/lady is concise, so the shortest answer in bytes wins.

\$\endgroup\$
  • \$\begingroup\$ From Sandbox: codegolf.meta.stackexchange.com/a/13765/71426 \$\endgroup\$ – Nathan.Eilisha Shiraini Sep 21 '17 at 9:19
  • \$\begingroup\$ Can we assume that there will be at least one non-space character? \$\endgroup\$ – Martin Ender Sep 21 '17 at 9:34
  • 2
    \$\begingroup\$ @KevinCruijssen You only have to handle ASCII characters in the printable space (0x20 to 0x7E). The other ones are Undefined Behavior. \$\endgroup\$ – Nathan.Eilisha Shiraini Sep 21 '17 at 10:54
  • 1
    \$\begingroup\$ @KevinCruijssen Yes, there will be no test case like this. There will be no things like " test\r " or " \v test" either. \$\endgroup\$ – Nathan.Eilisha Shiraini Sep 21 '17 at 10:57
  • 1
    \$\begingroup\$ 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) \$\endgroup\$ – Cinaski Sep 21 '17 at 13:54

41 Answers 41

1
2
1
\$\begingroup\$

Haskell, 109 bytes

(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

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

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.
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

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.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Welcome to the site! \$\endgroup\$ – James Sep 28 '17 at 19:56
0
\$\begingroup\$

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
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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)
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Japt -R, 18 bytes

ÈrYg"^  $"ò}hUÊN â

Try it

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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.
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Perl 5 -n, 33 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.