Due to technical limitations of Stack Exchange, the title is rendered incorrectly. The correct title for this challenge is

Make a

Word Icicle!
Word Icicle 
Word  cicle 
 ord  cicle 
 ord   icle 
 ord   i le 
 or    i le 
 or    i l  
 or      l  

Today's challenge is to make icicles out of the input word. Given a string of entirely printable ASCII, and at least 2 non-space characters, perform the following steps:

  1. Print the current state of the string.

  2. Replace the lexically smallest character (other than spaces) with a space. If there is a tie, replace the leftmost character.

  3. Repeat on consecutive lines until the string contains only 1 non-space character.

This creates the effect that the input string looks like it's melting...

I'm Melting!!!
I'm Melting !!
I'm Melting  !
I'm Melting   
I m Melting     
  m Melting   
  m  elting   
  m   lting   
  m   ltin    
  m   lt n    
  m    t n    
       t n    


  • After a couple iterations, your output will almost surely have trailing spaces on each line. If you choose to truncate these, that is allowed.

  • You may have one trailing empty line, but not more.

  • Remember that the input may contain several spaces, but these are all effectively skipped. For example, the input a a should give

    a      a
  • You may take input as a list of strings if you want. For output, you may return or print a list of strings, a single string with newlines, or char matrix/2D array. Generally, I prefer permissive IO formats, so other formats are most likely allowed as long as they are consistent and clearly correspond to the right output. If in doubt, feel free to ask. As usual, full programs or functions are allowed.

  • Remember, this is a contest to make the shortest answer in any language! If you choose to answer in Java, try to make the shortest Java answer (in bytes) that you can.

Test cases

Hello World! -->

Hello World!
Hello World 
 ello World 
 ello  orld 
 ello  orl  
  llo  orl  
   lo  orl  
    o  orl  
    o  or   

AbCdEfGhIjKlMnOpQrStUvWxYz -->

 b dEfGhIjKlMnOpQrStUvWxYz
 b d fGhIjKlMnOpQrStUvWxYz
 b d f hIjKlMnOpQrStUvWxYz
 b d f h jKlMnOpQrStUvWxYz
 b d f h j lMnOpQrStUvWxYz
 b d f h j l nOpQrStUvWxYz
 b d f h j l n pQrStUvWxYz
 b d f h j l n p rStUvWxYz
 b d f h j l n p r tUvWxYz
 b d f h j l n p r t vWxYz
 b d f h j l n p r t v xYz
 b d f h j l n p r t v x z
   d f h j l n p r t v x z
     f h j l n p r t v x z
       h j l n p r t v x z
         j l n p r t v x z
           l n p r t v x z
             n p r t v x z
               p r t v x z
                 r t v x z
                   t v x z
                     v x z
                       x z

PPCG is da BEST --> 

PPCG is da  EST
PP G is da  EST
PP G is da   ST
PP   is da   ST
 P   is da   ST
     is da   ST
     is da    T
     is da     
     is d      

({({})({}[()])}{}) -->

 { {})({}[()])}{})
 { {}) {}[()])}{})
 { {}) {}[ )])}{})
 { {}  {}[ )])}{})
 { {}  {}[  ])}{})
 { {}  {}[  ] }{})
 { {}  {}[  ] }{} 
 { {}  {}   ] }{} 
 { {}  {}     }{} 
   {}  {}     }{} 
    }  {}     }{} 
    }   }     }{} 
    }   }     } } 
        }     } } 
              } } 
  • 1
    \$\begingroup\$ "lexically smallest" means by code point? \$\endgroup\$
    – Giuseppe
    Commented Apr 13, 2018 at 18:03
  • 1
    \$\begingroup\$ @Giuseppe Yes, the character with the smallest ASCII code point (other than space obviously) \$\endgroup\$
    – DJMcMayhem
    Commented Apr 13, 2018 at 18:04
  • 2
    \$\begingroup\$ Reminds me of another challenge where we had to, I think, vertically repeat a character by its index in the alphabet. \$\endgroup\$
    – Shaggy
    Commented Apr 13, 2018 at 18:23
  • 7
    \$\begingroup\$ @Shaggy You're probably thinking of Make some Alphabet Rain. \$\endgroup\$
    – Rainbolt
    Commented Apr 13, 2018 at 20:11
  • 3
    \$\begingroup\$ That reference to MediaWiki though... \$\endgroup\$ Commented Apr 14, 2018 at 12:56

47 Answers 47


Retina, 28 bytes


Try it online!Explanation:


Repeat while the input value isn't blank.


Print the current value.


Execute the rest of the script on the value. Then, execute the result of that script as a script on the value.


Sort the characters into order.


Select the first nonblank character and output a Retina program that replaces the first literal ($\) occurrence of that character ($&) with a space (trailing space in original code).


Python 2, 71 70 bytes

-1 byte thanks to ovs

while x.strip():print x;r=x.replace;x=r(min(r(*' ~')),' ',1)

Try it online!


APL (Dyalog Unicode), 18 11 bytes


Try it online!

uses ⎕io←1; returns an array of strings (vector of character vectors)

  • \$\begingroup\$ Is the necessary? \$\endgroup\$
    – user41805
    Commented Apr 13, 2018 at 20:16
  • \$\begingroup\$ @Cowsquack yes, otherwise the first few rows of the output could be identical \$\endgroup\$
    – ngn
    Commented Apr 13, 2018 at 20:19
  • \$\begingroup\$ @Cowsquack thanks, I didn't notice that \$\endgroup\$
    – ngn
    Commented Apr 13, 2018 at 20:26
  • \$\begingroup\$ fortunately, fixing this led to a shorter solution :) \$\endgroup\$
    – ngn
    Commented Apr 13, 2018 at 21:43
  • \$\begingroup\$ Nice one, really clever usage of ⍋∘⍋ :) \$\endgroup\$
    – user41805
    Commented Apr 14, 2018 at 7:14

05AB1E, 9 bytes


Try it online!


ð      # Push space
м      # Implicit input. Remove spaces
{      # Sort. Gives string of sorted, non-space chars
v      # For each char in that string
  =    #   Print latest string, without popping. The first time it prints the input
  y    #   Push current char
  ð    #   Push space
  .;   #   Replace first occurrence of current char by space
       # Implicitly end for-each loop
  • 1
    \$\begingroup\$ {ðKv=yð.; was mine, nice one. \$\endgroup\$ Commented May 1, 2018 at 17:28
  • \$\begingroup\$ @MagicOctopusUrn Heh, pretty similar \$\endgroup\$
    – Luis Mendo
    Commented May 1, 2018 at 17:52
  • 1
    \$\begingroup\$ @MagicOctopusUrn Actually, it would still be the same 9 bytes in the latest 05AB1E version.. : replaces all characters instead of .; which replaces the first (i.e. see what your 7-byter does with the ! in the test case). Also, the challenge explicitly states excluding spaces, so your 7-byter wouldn't work for input with multiple spaces. PS: Nice answer, Luis! +1 from me. :) \$\endgroup\$ Commented Oct 22, 2018 at 14:50
  • 1
    \$\begingroup\$ @KevinCruijssen leave it to me to forget why I had to use .; in the first place. I literally remember struggling with that on May 1st earlier this year now that you mention it. \$\endgroup\$ Commented Oct 22, 2018 at 14:57
  • 1
    \$\begingroup\$ @LuisMendo Well, none of the commands you've used in this answer have changed in the Elixir rewrite of 05AB1E. :) \$\endgroup\$ Commented Oct 22, 2018 at 15:17

Pyth, 17 14 13 bytes


Try it here

V-SQd              For each non-space character in the sorted input (Q)...
     Q             ... print the current value of Q...
      = Q          ... and set Q to itself...
         xQN       ... with the first instance of the character...
       X    d      ... replaced by a space.

Ruby, 60 58 55 47 bytes

->a{[-a]+a.scan(/\S/).sort.map{|x|a[x]=' ';-a}}

Try it online!

  • \$\begingroup\$ You can swap in a-b=[' '] and a-b for a quick -2 bytes \$\endgroup\$
    – benj2240
    Commented Apr 13, 2018 at 19:09
  • \$\begingroup\$ Yeah, thanks for that, but now I've changed the approach a bit, so it is no longer used. \$\endgroup\$
    – Kirill L.
    Commented Apr 13, 2018 at 21:04
  • \$\begingroup\$ I like the new approach! \$\endgroup\$
    – benj2240
    Commented Apr 13, 2018 at 21:41

sed -rn, 142 143 bytes

s	\w+$	!"#$%\&'()*+,-./0123456789:;<=>?@&[\\]^_`\L&{|}~	
/(.).*	\1/!s/	./	/
s/(.)(.*)	\1.*/ \2/

Try it online!

(note: there are tabs in the program)

Since sed has no concept of lexicographical order, I had to hardcode the set of printable ASCII characters in and it takes up more than half the bytecount.

Using sed 4.2.2 will reduce bytecount by 2, since that allows for unnamed labels, Try it online!

-r enables extended regular expressions (golfier)

-n disables implicit printing of the pattern space at the end of the program

The pattern space starts with the input

:a label a, this is the main program loop

p print the pattern space (fancy name for the buffer)

now we append the set of printable ASCII characters (excluding the space)

s/$/ ABCDEFGHIJKLMNOPQRSTUVWXYZ/ append a tab, acting as the 1-byte delimiter, followed by the uppercase alphabet

s<tab> substitute (sed can take any character as the delimiter, in this case the tab is used to save a byte from escaping the /)

  • \w+$ the uppercase alphabet we just appended

  • <tab> with

  • !"#$%\&'()*+,-./0123456789:;<=>?@&[\\]^_\`\L&{|}~<tab> the rest of the characters, note that \L& is the lowercase version of the uppercase alphabet

:b label b, remove characters from the beginning set that are not present in input

/(.).* \1/! if the first character from the ASCII set is not in the input

  • s/ ./ / remove it

tb repeat b until the substitution fails

s/(.)(.*) \1.*/ \2/ replace the first character in the ASCII set present in the input with a space, and remove the ASCII set

ta recurse

  • \$\begingroup\$ Non-greedy matching would have been really helpful here, but I was able to come up with something that fooled sed enough to save at least 4 bytes: Try it online! \$\endgroup\$
    – Neil
    Commented Apr 14, 2018 at 0:35
  • \$\begingroup\$ (Cows quack pointed out that I was only partly able to fool sed, as I remove identical characters in the wrong order.) \$\endgroup\$
    – Neil
    Commented Apr 14, 2018 at 10:33

R, 140 100 bytes

-40 bytes Thanks to Giuseppe !

function(x)for(i in any((z=utf8ToInt(x))<33):max(y<-rank(z,,"f"))){z[y==i]=32

Try it online!

A solution using outer and Giuseppe's magic to work properly is longer at 104 bytes. Inspired by this answer.


Try it online!

  • \$\begingroup\$ 109 bytes taking input as a vector of chars \$\endgroup\$
    – Giuseppe
    Commented May 1, 2018 at 22:07
  • 1
    \$\begingroup\$ 100 bytes taking input as a string! \$\endgroup\$
    – Giuseppe
    Commented May 1, 2018 at 22:08
  • \$\begingroup\$ Still, a very nice answer; mine had ballooned to over 200 bytes since I didn't remember about rank! \$\endgroup\$
    – Giuseppe
    Commented May 1, 2018 at 22:08
  • \$\begingroup\$ @Giuseppe Tell me about it - I first tried "order" for a result that was melting but not in the correct order! \$\endgroup\$
    – JayCe
    Commented May 1, 2018 at 22:40
  • \$\begingroup\$ @Giuseppe and my attempt at using outer inspired by your post only managed to remove all spaces. TIO I'd love to see a working outer approach posted as a separate answer. Still working on it but it might not be that elegant. \$\endgroup\$
    – JayCe
    Commented May 1, 2018 at 23:52

Python 3, 71 bytes

f=lambda a:[*a.strip()]and[a]+f(a.replace(min(a.replace(*" ~"))," ",1))

Try it online!

-4 bytes thanks to ovs

  • \$\begingroup\$ Save 2 bytes using *bool({*a}-{" "}) instead of if{*a}-{" "}else[a] \$\endgroup\$
    – RootTwo
    Commented Apr 13, 2018 at 20:54
  • \$\begingroup\$ @RootTwo wouldn't this result in a RecursionError? \$\endgroup\$
    – ovs
    Commented Apr 13, 2018 at 21:11
  • \$\begingroup\$ @RootTwo if/else shortcuts but *bool doesn't, so yes, recursionerror like ovs said \$\endgroup\$
    – hyper-neutrino
    Commented Apr 14, 2018 at 2:44
  • \$\begingroup\$ Of course you are correct. Because of a bug, my function recursed by calling your function so it appeared to work. \$\endgroup\$
    – RootTwo
    Commented Apr 14, 2018 at 4:41

Python 2, 70 69 66 64 bytes

def f(s):print s;S=set(s)-{' '};S and f(s.replace(min(S),' ',1))

Try it online!

Thx for 2 bytes from ovs via using S and f() instead of if S:f()

  • \$\begingroup\$ You're missing the ...If there is a tie, replace the leftmost character... rule, you can fix that with replace(min(...),' ',1) \$\endgroup\$
    – Rod
    Commented Apr 13, 2018 at 19:55
  • \$\begingroup\$ @Rod: Ah! Got it... \$\endgroup\$
    – Chas Brown
    Commented Apr 13, 2018 at 19:58

Jelly, 8 bytes


Try it online!


The basic idea is to build the columns of the desired output directly, instead of manipulating the string and returning all intermediate results.

We start by numerating the characters of the input string in the order they will be removed. For the moment, we'll pretend spaces will be removed as well.

tee ay oh

Now, we build the columns by repeating each character by its index in this enumeration.

tee ay oh
tee ay oh
tee ay oh
tee  y oh
t e  y oh
t    y oh
t    y o 
t    y   

All that's left is to remove duplicates, to account for the spaces.


ẋ"ỤỤ$z⁶Q  Main link. Argument: s (string)

    $     Combine the two links to the left into a chain.
  Ụ       Grade up; sort the indices of s by their corresponding values.
          Let's call the result J.
          Grade up again, sorting the indices of J by the corr. values in J.
          This enumerates the positions of s as described before.
ẋ"        Repeat each character of s that many times.
     z⁶   Zip the resulting 2D array, filling missing characters with spaces.
       Q  Unique; deduplicate the array of rows.

Perl 5 -n, 37 34 bytes

Dropped three bytes with help from @TonHospel

say&&s/\Q$a/ / while($a)=sort/\S/g

Try it online!

  • \$\begingroup\$ Ah, very nice, much nicer approach! I think you need the \Q though for the last test case.... I missed that the first times too! \$\endgroup\$ Commented Apr 14, 2018 at 5:25
  • \$\begingroup\$ You're right. Added it. \$\endgroup\$
    – Xcali
    Commented Apr 14, 2018 at 5:47
  • \$\begingroup\$ Shorter: say&&s/\Q$a/ / while($a)=sort/\S/g. Also properly handles 0 \$\endgroup\$
    – Ton Hospel
    Commented Apr 15, 2018 at 16:28

JavaScript, 67 66 65 bytes

Because I haven't golfed drunk in a while!

s=>[...t=s].sort().map(x=>x>` `?t+=`
${s=s.replace(x,` `)}`:0)&&t

Try it online

Thanks to DanielIndie for pointing out 4 redundant bytes that beer included!

  • \$\begingroup\$ why do you specify y in the map? :P it can be made 67 \$\endgroup\$ Commented Apr 14, 2018 at 8:17
  • \$\begingroup\$ @DanielIndie, because Beer! :D Thanks for pointing it out. \$\endgroup\$
    – Shaggy
    Commented Apr 14, 2018 at 8:37
  • \$\begingroup\$ yes, i thought that would be the case :P \$\endgroup\$ Commented Apr 14, 2018 at 8:45

K (ngn/k), 26 24 bytes

{?(,x),x{x[y]:" ";x}\<x}

Try it online!

  • \$\begingroup\$ Beautiful! My K attempt came in at 41: `{.[x;(-1+#x)&x?_ci&/_ic x _dv" ";:;" "]}` I'm wasting bytes converting to ints and back and making sure it doesn't go out of bounds. \$\endgroup\$
    – uryga
    Commented May 2, 2018 at 1:34
  • \$\begingroup\$ @uryga Thanks. If I had implemented projections properly, {@[x;y;:;" "]} could have been @[;;:;" "]. Which version of k do you use? I'm not familiar with these: _ci _ic _dv. \$\endgroup\$
    – ngn
    Commented May 2, 2018 at 12:16
  • \$\begingroup\$ I think it's 2.8-ish? I'm using the Kona interpreter which provides operators as builtins: char-of-int, int-of-char, delete-value. \$\endgroup\$
    – uryga
    Commented May 2, 2018 at 12:19

C# (Visual C# Interactive Compiler), 129 bytes

var s=ReadLine();while(s.Any(c=>c!=32)){WriteLine(s);var i=s.IndexOf(s.Min(c=>c==32?(char)999:c));s=s.Remove(i,1).Insert(i," ");}

Try it online!

  • \$\begingroup\$ c!=32 can be c>32; c==32 can be c<33; and (char)999 can be '¡' (or any other character above the printable ASCII unicode range). \$\endgroup\$ Commented Apr 16, 2018 at 7:00
  • \$\begingroup\$ Oh, and you can save two more bytes changing the while to for and placing the var s=ReadLine() and s=s.Remove(i,1).Insert(i," ") inside it (so the two semi-colons are no longer needed). \$\endgroup\$ Commented Apr 16, 2018 at 7:07

Perl 5 with -nlF/\s|/, 39 bytes

@F=sort@F;say,s~\Q$F[$F++]~ ~ while/\S/

This might be pushing the boundaries of Perl's flags not being counted, if so I'll revert to the previous answer.

Try it online!


V, 27 bytes

>>ò2Ùúú^lDhrfDj|@"r kdòdj<H

Try it online!


00000000: 3e3e f232 d9fa fa5e 6c44 6872 6644 6a7c  >>.2...^lDhrfDj|
00000010: 4022 7220 6b64 f264 6a3c 48              @"r kd.dj<H

Haskell, 67 bytes

12 bytes saved thanks to Laikoni

f s|(a,_:b)<-span(/=minimum(id=<<words s))s=putStrLn s>>f(a++' ':b)

Try it online!

This one terminates in an error

Haskell, 83 79 bytes

g(a,_:b)=a++' ':b
mapM_ putStrLn.(iterate$g.(span=<<(/=).minimum.concat.words))

Try it online!

This one terminates in an error

Haskell, 86 bytes

g(a,_:b)=a++' ':b

Try it online!

Haskell, 100 91 88 bytes

f x|(a,_:b)<-span(/=minimum(u x))x=a++' ':b
(take.length.u)<*>(iterate f)

Try it online!

  • \$\begingroup\$ 67 bytes: f s|(a,_:b)<-span(/=minimum(id=<<words s))s=putStrLn s>>f(a++' ':b) Try it online! \$\endgroup\$
    – Laikoni
    Commented Apr 13, 2018 at 22:15
  • \$\begingroup\$ @Laikoni Thanks! I was just on the verge of something like that and I fell asleep. However I don't think I would have come up with id=<< that's pretty clever \$\endgroup\$
    – Wheat Wizard
    Commented Apr 13, 2018 at 23:32

JavaScript (Node.js), 80 65 bytes

x=>[...x].sort().map(c=>x=x.replace(c,' ',c>' '&&console.log(x)))

Try it online!

Didn't know replace take string as string, not regexp


K4, 28 20 18 bytes


?x{x[y]:" ";x}\<x:


q)k)?x{x[y]:" ";x}\<x:"PPCG is da BEST"
"PPCG is da BEST"
"PPCG is da  EST"
"PP G is da  EST"
"PP G is da   ST"
"PP   is da   ST"
" P   is da   ST"
"     is da   ST"
"     is da    T"
"     is da     "
"     is d      "
"     is        "
"      s        "
"               "


It's the same thing as ngn is doing. Find indices that would result in an ascending list, overwrite them one-by-one with " ", then take the distinct to remove any duplicate lines:

?x{x[y]:" ";x}\<x: / the solution
                x: / save input as x
               <   / return indices that would result in ascending sort
 x{        ; }\    / two-line lambda with scan
        " "        / whitespace
       :           / assignment
   x[y]            / x at index y
            x      / return x
?                  / distinct

gcc 32-bit, 66 65 bytes

main(){char s[]="3.1415926";f(s);}

Thanks for Jonathan Frech for -1 byte

  • \$\begingroup\$ *p==i?...:0; could probably be *p-i?0:...;. \$\endgroup\$ Commented Apr 13, 2018 at 20:06
  • \$\begingroup\$ @JonathanFrech No, it's 1 byte longer (though *p-1||(...) is same length) \$\endgroup\$
    – l4m2
    Commented Apr 14, 2018 at 7:45
  • \$\begingroup\$ Sorry, did not recognize the importance to keep the comma expression together. However, this might be 65 bytes. I also do not know how f(a) compiles, as a should be of type char*, but I assume that has something to do with your 32-bit gcc usage. \$\endgroup\$ Commented Apr 14, 2018 at 17:20
  • \$\begingroup\$ @JonathanFrech I think char*p,i;f(long long a){for(i=31;++i;)for(p=a;*p;)*p==i?puts(a),*p=32:++p;} on tio(64bit) may explain how f(a) work \$\endgroup\$
    – l4m2
    Commented Apr 14, 2018 at 18:11
  • \$\begingroup\$ I am sorry, though I asked the OP about the challenge specifications and they said the input string may start with a space. Therefore my proposed solution is invalid (as such an input results in an infinite loop) and you should most likely revert back to your original solution. \$\endgroup\$ Commented Apr 14, 2018 at 20:27

MATLAB, 74 bytes

This uses the 2-output form of the max() function to retrieve the smallest character and its index, having transformed the string to zero values in the spaces and 256-the character value for the printable characters.

s=input('s');x=1;while(x);disp(s);[x,y]=max((256-s).*(s~=' '));s(y)=' ';end
  • 1
    \$\begingroup\$ Welcome to PPCG! Nice work! \$\endgroup\$
    – AJFaraday
    Commented Apr 16, 2018 at 12:58

Common Lisp, 240 228 224 bytes

(setf s(read))(defun f(x)(setf y(char-code(elt s x)))(if(= y 32)1e9 y))(loop for _ across s do(print s)do(setf s(replace s" ":start1(position(code-char(reduce #'min (loop for i from 0 below(length s)collect i):key #'f))s))))

Try it online!

This is my first time posting.
I'm in the process of learning lisp so I'm sure someone can think of something shorter than this.

  • 1
    \$\begingroup\$ Welcome to the site! Good to see some common lisp! \$\endgroup\$
    – Wheat Wizard
    Commented Apr 14, 2018 at 21:24

APL (Dyalog Unicode), 39 bytesSBCS

{⎕←⍵⋄×≢⍵∩g←' '~⍨⎕UCS⍳256:∇' '@(⊃g⍋⍵)⊢⍵}

Try it online!



{⎕←⍵⋄×≢⍵∩g←' '~⍨⎕UCS⍳256:∇' '@(⊃g⍋⍵)⊢⍵} ⍝ Main function, argument ⍵
 ⎕←⍵⋄                                    ⍝ Print ⍵
         g←' '~⍨⎕UCS⍳256                 ⍝ Assign to g every Unicode character except space
     ×≢⍵∩                :               ⍝ If ⍵∩g is not empty
                          ∇              ⍝ Recursively call the function with argument:
                           ' '@       ⍵  ⍝ Space at
                               (⊃g⍋⍵)    ⍝ The first (⊃) element in ⍵ graded up (⍋) with g
                                         ⍝ The dyadic grade up function will index ⍵ according
                                         ⍝ to its left argument, in this case g.

PowerShell, 103 99 bytes

param($a)2..$a.length|%{($x=$a);[regex]$p=""+([char[]]$a-ne' '|sort)[0];$a=($p.replace($x," ", 1))}

Try it online!

Takes input as a string into $a. We then loop from 2 to $a.length (i.e., the appropriate number of vertical times necessary to remove all but one character). Each iteration, we output the current string and conveniently saved into $x at the same time. We then construct a new [regex] object, $pattern consisting of the remaining characters in $a that are -notequal to space, sorted, then the 0th one thereof.

We then set $a equal to a new string of the regex object with the .Replace method to replace in the string $x, the $pattern, with a space " ", but only the 1st match. Yeah, this syntax is weird.

The strings are left on the pipeline and implicit Write-Output gives us a newline between them for free, plus one trailing newline.


Java (JDK 10), 140 bytes

s->{for(int m=1,i;m>0;s=s.substring(0,i=s.indexOf(m=s.chars().filter(c->c>32).min().orElse(0)))+" "+s.substring(i+1))System.out.println(s);}

Try it online!

Technically there's a blank line, but it's not empty.


Stax, 9 bytes


Run and debug it

This is the same algorithm as Luis' 05AB1E solution


MATL, 17 16 bytes


Try it online! Or verify all test cases.


t       % Implicit input. Duplicate
S       % Sort
Xz      % Remove spaces
"       % For each char in that string
  t     %   Duplicate last result. This is the most recent string obtained
        %   from replacing chars by spaces in the input
  O     %   Push 0
  y     %   Duplicate from below
  @     %   Push current char
  =     %   Equals? (element-wise) Gives 1 for occurrences of current char
        %   in the most recent string, 0 otherwise
  f     %   Indices of nonzeros
  1)    %   Get the first entry
  (     %   Write 0 at that position. Char 0 will be displayed as space
]       % End
x       % Delete last result, which consists only of space / char zero

Excel VBA, 167 bytes

An anonymous VBE immediate window function that takes input from range [A1] and outputs to the VBE immediate window.

s="Code(Mid(A$1,Row(),1))":[B1].Resize([Len(A1)])="=If("&s &"=32,1E3,"&s &")":For i=1To[Len(A1)-CountIf(B:B,1E3)]:?[A1]:[A1]=[Substitute(A1,Char(Min(B:B))," ",1)]:Next

Ungolfed and Commented

''  run as `call icicle("Test")` or `icicle"I am the WALRUS`
Sub icicle(Optional str As String)
    If Not IsMissing(str) Then [A1] = str   ''  pipe input
    [B:B].Clear                             ''  reset between runs
    [B1].Resize([Len(A1)]) = "=If(Code(Mid(A$1,Row(),1))=32,1E3,Code(Mid(A$1,Row(),1)))"  ''  get char number for every char in input
    For i = 1 To [Len(A1)-CountIf(B:B,1E3)] ''  iterate across from 1 to length of input - number of spaces
        Debug.Print [A1]                    ''  output a single line
        [A1]=[Substitute(A1,Char(Min(B:B))," ",1)]  ''  replace minimum char with space
End Sub

Japt, 32 18 bytes

Saved 14 bytes thanks to Shaggy!

rS ¬£=hSUbZn gYÃiN

Try it online!

  • \$\begingroup\$ Save a byte by returning an array of lines: ethproductions.github.io/japt/… \$\endgroup\$
    – Shaggy
    Commented Apr 13, 2018 at 20:49
  • \$\begingroup\$ 22 bytes. Will try a port of my JS solution soon, see how that works out. \$\endgroup\$
    – Shaggy
    Commented Apr 14, 2018 at 8:46
  • 1
    \$\begingroup\$ Got it down to 18 bytes. \$\endgroup\$
    – Shaggy
    Commented Apr 14, 2018 at 9:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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