5
\$\begingroup\$

A space cleaner is a special character which removes all spaces between it and the first non space character to its left and it is represented by a '!' character. If it reaches the beginning of the string it stops.

Given a string output the string in any reasonable format after the cleaning process.

Trailing spaces at the end of the string must be still be in the output.

Remember that space cleaners remain after their job.

Input will only consist of printable ASCII characters.

This is code-golf, so least number of bytes win.

Test Cases

" ! a! !b c!d !" => "! a!!b c!d!"
"a    !" => "a!"
"!    a" => "!    a"
"!    !    !" => "!!!"
"! " => "! "
\$\endgroup\$
  • 8
    \$\begingroup\$ Some test cases would be good. I assume that the cleaners are represented by !s, since it isn't quite clear. So basically, this boils down to "remove any spaces before a space cleaner", correct? \$\endgroup\$ – Jo King Sep 10 at 6:07
  • 2
    \$\begingroup\$ Can we get some examples? What is the minimum string length? What do we do with the input string !? This looks like it would be trivially solved by a regex looking for any number of spaces followed by a bang? \$\endgroup\$ – streetster Sep 10 at 6:08
  • 1
    \$\begingroup\$ May we choose which character to use as the "pipe cleaner"? \$\endgroup\$ – Shaggy Sep 10 at 7:00
  • 3
    \$\begingroup\$ Suggested test case "! " => "! " \$\endgroup\$ – Jitse Sep 10 at 8:05
  • 1
    \$\begingroup\$ @AZTECCO Test case added. For the question, nope. \$\endgroup\$ – HighlyRadioactive Sep 10 at 9:56

22 Answers 22

5
\$\begingroup\$

Retina, 5 bytes

 +!
!

Try it online.

Not much to say. Simply removes all spaces in front of every ! with a simple replace.

\$\endgroup\$
  • \$\begingroup\$ 4th test case ! ! ! -> !!! why not ! !! ? \$\endgroup\$ – Nahuel Fouilleul Sep 10 at 7:12
  • 3
    \$\begingroup\$ @NahuelFouilleul Why not? I assume all space cleaners 'walk' simultaneously, so eventually they'll reach the start of the string for that test case. OP never stated the left one walks first, only that all space cleaners travel left. \$\endgroup\$ – Kevin Cruijssen Sep 10 at 7:17
  • 1
    \$\begingroup\$ maybe the OP should clarify \$\endgroup\$ – Nahuel Fouilleul Sep 10 at 7:21
  • 1
    \$\begingroup\$ The assumption is correct. (Which, if I'm not mistaken, is equivalent to "the left ones first".) \$\endgroup\$ – HighlyRadioactive Sep 10 at 9:48
4
\$\begingroup\$

05AB1E, 5 bytes

„ !¤:

Try it online!


Explanation

„ !                  # 2 char string " !"
   ¤                 # Push the tail of that (so "!") 
    :                # Infinite replacement
\$\endgroup\$
4
\$\begingroup\$

JavaScript (ES6), 24 bytes

Thanks to @Nick Kennedy for the TIO link and -2 bytes, since I could omit the function name f=

_=>_.replace(/ +!/g,'!')

Try It Online

Nothing special, same regex as other answers. New to codegolf, was a simple one to translate to js. If anyone can think of improvements I'd love to see them.

\$\endgroup\$
  • \$\begingroup\$ Welcome to the site! \$\endgroup\$ – Wheat Wizard Sep 11 at 16:58
  • \$\begingroup\$ Welcome to the site! I like the underline obfuscation LOL. \$\endgroup\$ – HighlyRadioactive Sep 12 at 5:35
  • \$\begingroup\$ Welcome! Would suggest having a Try it online link with a working example. Also you can move the naming of the lambda to a header and remove it from the byte count. e.g. tio.run/##BcExDoAgDADAr7QsQFRYXfArBCsQDREChu/… \$\endgroup\$ – Nick Kennedy Sep 12 at 13:38
  • \$\begingroup\$ @NickKennedy Thanks! I wasn't sure about the function naming, good to know. I considered the TIO link but figured it's easy enough to test JS with browser console. Although, I will edit it into my post. \$\endgroup\$ – Matsyir Sep 12 at 13:52
3
\$\begingroup\$

Haskell, 48 42 bytes

-6 bytes thanks to H.PWiz!

g(' ':b)|'!':_<-g b=g b
g(a:b)=a:g b
g a=a

Try it online!

Explanation:

g(' ':b)                 -- Given a string starting with space
        |'!':_           -- Check if '!' is the first element of
              <-g b      -- The function applied to the rest of it
                   =g b  -- Return the function applied to the rest of it
g(a:b)=a:g b             -- Otherwise just apply the function recursively
g a=a                    -- Until the string is empty
\$\endgroup\$
  • 1
    \$\begingroup\$ You don't need parens around g b. Also, you can replace g b!!0=='!' with '!':_<-g b \$\endgroup\$ – H.PWiz Sep 12 at 1:42
2
\$\begingroup\$

brainfuck, 66 bytes

,[<<++++[->++++++++<]>>[-<-<+>>]<[+[[+]<<[.<]>[>]]<.>>]>>,]<<<[.<]

Try it online!

It's funny how much space is just taken up by constants, in this case making a space takes up more than a quarter of the code.

\$\endgroup\$
2
\$\begingroup\$

PHP, 35 bytes

<?=preg_replace('/ +!/','!',$argn);

Try it online!

Just a simple RegEx replace.

\$\endgroup\$
2
\$\begingroup\$

R, 25 bytes

gsub(" +!","!",scan(,''))

Straightforward enough with a simple regex substitution!

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Haskell, 34 bytes

foldr(%)""
' '%r@('!':_)=r
c%s=c:s

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Perl 5 (-p), 9 bytes

s/ *!/!/g

TIO

\$\endgroup\$
1
\$\begingroup\$

Python 3, 50 bytes

f=lambda s:' !'in s and f(s.replace(' !','!'))or s

Try it online!

Port of Expired Data's 05AB1E answer, so make sure to upvote him!


Original answer:

Python 3, 63 bytes

lambda s:'!'.join(i.rstrip(' ')for i in(s+'_').split('!'))[:-1]

Try it online!

\$\endgroup\$
1
\$\begingroup\$

PowerShell, 22 bytes

$args-replace' +!','!'

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Zsh with extended_glob, 14 bytes

<<<${1// #!/!}

Zsh with extended_glob is not an arbitrary whim: it's the language in which zsh completion functions are written. Inspired by roblogic's initial attempt. Try it online.

\$\endgroup\$
1
\$\begingroup\$

ksh, 18 bytes

try it online!

echo ${1//+( )!/!}

zsh, 32 bytes
Since there's another zsh answer I changed to ksh. Thanks to @Gilles at unix.se for zsh help. try it online!
setopt ksh_glob;<<<${1//+( )!/!}

\$\endgroup\$
0
\$\begingroup\$

Japt, 7 bytes

Recursive replacement. Could save 2 bytes if we could choose the "cleaner" character.

e" !"'!

Try it

\$\endgroup\$
  • \$\begingroup\$ I didn't get how did you save bytes by changing the cleaner character. \$\endgroup\$ – HighlyRadioactive Sep 10 at 13:20
  • \$\begingroup\$ @TwilightSparkle, Japt has constants for a few characters & digits (e.g., T===0), which would allow me to do something like eS+TT (where S is Japt's constant for a single space). \$\endgroup\$ – Shaggy Sep 10 at 13:29
  • \$\begingroup\$ Thanks for the explanation. I choose ! just because it's next to the space in the ASCII table. \$\endgroup\$ – HighlyRadioactive Sep 11 at 13:31
0
\$\begingroup\$

Perl 6, 14 bytes

{S:g/\s+\!/!/}

Try it online!

Loses bytes over other regex solutions since I can't use a literal space and I have to escape the metaoperator !

\$\endgroup\$
0
\$\begingroup\$

J, 16 bytes

(#~1-' !'E.])^:_

Try it online!

\$\endgroup\$
0
\$\begingroup\$

C (clang), 79 bytes

j,e;f(char*s){for(j=e=0;!e;e=!*s++)*s-32?s-=*s-33?j:0,j=0,*s&&putchar(*s):j++;}

Try it online!

Saved 1 thanks to @ceilingcat *s && instead of !*s ||

j is used to jump back if there is no "!" after spaces.

\$\endgroup\$
0
\$\begingroup\$

Jelly, 11 bytes

œṣ⁾ !j”!µÐL

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Python 3, 38 bytes

lambda s:re.sub(' +!','!',s)
import re

A simple regex substitution. Replaces any amount of space plus an exclamation mark with just an exclamation mark.

\$\endgroup\$
  • \$\begingroup\$ Why using a raw string? lambda s:re.sub(' *!','!',s) is a byte shorter. \$\endgroup\$ – Skillmon Sep 13 at 13:44
  • \$\begingroup\$ @Skillmon Man, that habit is hard to break for code golf. Thanks for pointing it out! \$\endgroup\$ – Triggernometry Sep 13 at 14:22
0
\$\begingroup\$

Ruby -p, 14 bytes

gsub(/ +!/,?!)

Unfortunately the 13-byte gsub / +!/,?! doesn't work because Ruby interprets the first / as division instead of the start of a regex statement.

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Java 8+, 26 bytes

Yet another regex port

s->s.replaceAll(" +!","!")

TIO

\$\endgroup\$
  • 1
    \$\begingroup\$ I think lambdas where first introduced in Java 8. \$\endgroup\$ – Jonathan Frech Sep 14 at 23:39
  • \$\begingroup\$ @JonathanFrech I had a brain short-circuit there \$\endgroup\$ – Benjamin Urquhart Sep 15 at 13:31
0
\$\begingroup\$

Charcoal, 22 bytes

≔ ηF⮌S«≡ι!≔ωη ≔ηι≔ η←ι

Try it online! Link is to verbose version of code. Explanation:

≔ η

h is a variable that specifies whether a space is being cleaned or not.

F⮌S«

Loop over the string in reverse as the spaces are cleaned to the left.

≡ι

Switch over the current character.

!≔ωη

If it's a ! then start cleaning spaces.

 ≔ηι

If it's a space then replace it with the space cleaning flag.

≔ η

Otherwise turn off space cleaning.

←ι

Print the current character leftwards.

Boring 15-byte version:

W№θ !≔⪫⪪θ !¦!θθ

Try it online! Link is to verbose version of code. Explanation:

W№θ !

Repeat while there are spaces to be cleaned.

≔⪫⪪θ !¦!θ

Clean up to one space per space cleaner.

θ

Output the result.

\$\endgroup\$

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.