Сделай Слово Сосулька

45

Из-за технических ограничений Stack Exchange заголовок отображается неверно. Правильное название для этой задачи является

Делать

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

Сегодняшняя задача состоит в том, чтобы сделать сосульки из входного слова. При наличии строки полностью печатаемого ASCII и не менее 2 непробельных символов выполните следующие действия:

  1. Вывести текущее состояние строки.

  2. Замените наименьший лексический символ (кроме пробелов) пробелом. Если есть связь, замените крайний левый символ.

  3. Повторяйте в последовательных строках, пока строка не будет содержать только 1 непробельный символ.

Это создает эффект того, что входная строка выглядит как тающая ...

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    
       t      

правила

  • После нескольких итераций ваш вывод почти наверняка будет содержать пробелы в каждой строке. Если вы решите их усечь, это разрешено.

  • У вас может быть одна конечная пустая строка, но не более.

  • Помните, что ввод может содержать несколько пробелов, но все они эффективно пропускаются. Например, вход a aдолжен дать

    a      a
           a
    
  • Вы можете принять ввод как список строк, если хотите. Для вывода вы можете вернуть или распечатать список строк, одну строку с символами новой строки или символьную матрицу / 2D-массив. Обычно я предпочитаю разрешающие форматы ввода-вывода, поэтому другие форматы, скорее всего, допустимы, если они согласованы и четко соответствуют правильному выводу. Если есть сомнения, не стесняйтесь спрашивать. Как обычно, полные программы или функции разрешены.

  • Помните, это конкурс на самый короткий ответ на любом языке! Если вы решите ответить в Java, попробуйте сделать самый короткий ответ Java (в байтах), какой только сможете.

Контрольные примеры

Hello World! -->

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


AbCdEfGhIjKlMnOpQrStUvWxYz -->

AbCdEfGhIjKlMnOpQrStUvWxYz
 bCdEfGhIjKlMnOpQrStUvWxYz
 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
                         z


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        


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

({({})({}[()])}{})
 {({})({}[()])}{})
 { {})({}[()])}{})
 { {}) {}[()])}{})
 { {}) {}[ )])}{})
 { {}  {}[ )])}{})
 { {}  {}[  ])}{})
 { {}  {}[  ] }{})
 { {}  {}[  ] }{} 
 { {}  {}   ] }{} 
 { {}  {}     }{} 
   {}  {}     }{} 
    }  {}     }{} 
    }   }     }{} 
    }   }     } } 
        }     } } 
              } } 
                } 
DJMcMayhem
источник
1
«лексически наименьшее» означает под кодовой точкой?
Джузеппе
1
@Giuseppe Да, персонаж с наименьшей кодовой точкой ASCII (очевидно, кроме пробела)
DJMcMayhem
2
Напоминает мне еще один вызов, когда мы должны были, по-моему, вертикально повторить символ по его индексу в алфавите.
Лохматый
6
@Shaggy Вы, наверное, думаете о создании алфавитного дождя .
Rainbolt
2
Эта ссылка на MediaWiki, хотя ...
Эрик Outgolfer

Ответы:

8

Сетчатка , 28 байт

/\S/+¶<~(O`.
0L$`\S
0`$\$&¶ 

Попробуйте онлайн! Объяснение:

/\S/+

Повторите, пока входное значение не пустое.

¶<

Распечатать текущее значение.

~(

Выполните оставшуюся часть сценария для значения. Затем выполните результат этого сценария как сценарий для значения.

O`.

Сортировка символов в порядке.

0L$`\S
0`$\$&¶ 

Выберите первый непустой символ и выведите программу Retina, которая заменяет первое $\вхождение литерала ( ) этого символа ( $&) пробелом (конечный пробел в исходном коде).

Нил
источник
6

APL (Dyalog Unicode) , 18 11 байтов

∪∘↓∘⍉⍋∘⍋⍴⌸⊢

Попробуйте онлайн!

использует ⎕io←1; возвращает массив строк (вектор символьных векторов)

СПП
источник
Это необходимо?
Критиси Литос
@ Cowsquack да, в противном случае первые несколько строк выходных данных могут быть идентичны
ngn
@ Cowsquack спасибо, я этого не заметил
августа
к счастью, исправление этого привело к более короткому решению :)
ngn
Хороший, действительно умный ⍋∘⍋
способ
6

05AB1E , 9 байтов

ðм{v=yð.;

Попробуйте онлайн!

объяснение

ð      # 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
{ðKv=yð.;был мой, хороший.
Волшебная Урна Осьминога
@MagicOctopusUrn Хех, очень похоже
Луис Мендо
1
@MagicOctopusUrn На самом деле, это будет все те же 9 байтов в последней версии 05AB1E .. :заменяет все символы вместо того, .;который заменяет первый (т.е. посмотрите, что делает ваш 7-байтовый символ !в тестовом примере). Кроме того, в задаче явно указано исключение пробелов, поэтому ваш 7-байтовый код не будет работать для ввода с несколькими пробелами. PS: Хороший ответ, Луис! +1 от меня. :)
Кевин Круйссен
1
@KevinCruijssen предоставьте мне возможность забыть, почему я должен был использовать .;в первую очередь. Я буквально помню, как боролся с этим 1 мая в начале этого года, когда вы упомянули об этом.
Волшебная Урна Осьминога
1
@ LuisMendo Ну, ни одна из команд, которые вы использовали в этом ответе, не изменилась в переписывании эликсира 05AB1E. :)
Кевин Круйссен
5

Pyth, 17 14 13 байтов

V-SQdQ=XQxQNd

Попробуй здесь

V-SQdQ=XQxQNd
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.
мнемонический
источник
5

sed -rn , 142 143 байта

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

Попробуйте онлайн!

(примечание: в программе есть вкладки)

Поскольку у sed нет понятия лексикографического порядка, мне пришлось жестко задавать набор печатных символов ASCII, и это занимает более половины байта.

Использование sed 4.2.2 сократит количество пользователей на 2, так как это позволяет использовать неназванные ярлыки. Попробуйте онлайн!


-r позволяет расширенные регулярные выражения (игрок в гольф)

-n отключает неявную печать пространства шаблона в конце программы

Пространство образца начинается с ввода

:aметка a, это основной цикл программы

p напечатать пространство шаблона (причудливое имя для буфера)

Теперь мы добавляем набор печатных символов ASCII (исключая пробел)

s/$/ ABCDEFGHIJKLMNOPQRSTUVWXYZ/ добавить вкладку, выступающую в качестве 1-байтового разделителя, за которой следует алфавит в верхнем регистре

s<tab>заменитель (sed может принимать любой символ в качестве разделителя, в этом случае вкладка используется для сохранения байта от выхода из него /)

  • \w+$ прописной алфавит, который мы только что добавили

  • <tab> с участием

  • !"#$%\&'()*+,-./0123456789:;<=>?@&[\\]^_\`\L&{|}~<tab>остальные символы, обратите внимание, что \L&это строчная версия прописного алфавита

:bметка b, удалить символы из начального набора, которые отсутствуют во вводе

/(.).* \1/! если первый символ из набора ASCII отсутствует на входе

  • s/ ./ / убери это

tbповторять bдо тех пор, пока замена не завершится неудачно

s/(.)(.*) \1.*/ \2/ замените первый символ в наборе ASCII, присутствующем на входе, пробелом, и удалите набор ASCII

ta рекурсию

Kritixi Lithos
источник
Нежадное сопоставление было бы действительно полезным, но я смог придумать что-то такое, что обмануло sedдостаточно, чтобы сэкономить как минимум 4 байта: попробуйте онлайн!
Нил
(Коровья кряка указала, что я только частично смог обмануть Седа, поскольку я удаляю идентичных персонажей в неправильном порядке.)
Нейл,
4

Рубин , 60 58 55 47 байтов

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

Попробуйте онлайн!

Кирилл Л.
источник
Вы можете поменять местами a-b=[' ']и a-bбыстро -2 байта
benj2240
Да, спасибо за это, но теперь я немного изменил подход, поэтому он больше не используется.
Кирилл Л.
Мне нравится новый подход!
benj2240
4

R , 140 100 байт

-40 байт благодаря Джузеппе!

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

Попробуйте онлайн!

Решение, использующее outerмагию Джузеппе для правильной работы, длиннее - 104 байта. Вдохновлен этим ответом .

function(x,z=utf8ToInt(x)-32)apply(t(outer(rank(z,,"f"),(2-(min(z)>0)):nchar(x),">=")*z+32),1,intToUtf8)

Попробуйте онлайн!

Jayce
источник
109 байтов, принимающих входные данные как вектор символов
Джузеппе
1
100 байт, принимающих входные данные в виде строки!
Джузеппе
Тем не менее, очень хороший ответ; моя раздулась до 200 байтов, так как я не помнил об этом rank!
Джузеппе
@ Giuseppe Расскажи мне об этом - я сначала попробовал «упорядочить» результат, который таял, но не в правильном порядке!
JayCe
@Giuseppe и моя попытка использовать внешнее, вдохновленное вашим постом, удалось только удалить все пробелы. TIO Я бы хотел, чтобы рабочий внешний подход был опубликован как отдельный ответ. Все еще работаю над этим, но это может быть не так элегантно.
JayCe
3

Python 3 , 71 байт

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

Попробуйте онлайн!

-4 байта благодаря овсу

HyperNeutrino
источник
Сохраните 2 байта, используя *bool({*a}-{" "})вместоif{*a}-{" "}else[a]
RootTwo
@ RootTwo не приведет ли это к RecursionError?
овс
@RootTwo if/elseярлыки, но *boolне, так что да,
recursionerror
Конечно, вы правы. Из-за ошибки моя функция рекурсировала, вызывая вашу функцию, чтобы она работала.
RootTwo
3

Python 2 , 70 69 66 64 байта

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

Попробуйте онлайн!

Спасибо за 2 байта из ов, используя S and f()вместоif S:f()

Час Браун
источник
Вы пропустили ...If there is a tie, replace the leftmost character...правило, вы можете это исправить с помощьюreplace(min(...),' ',1)
Rod
@ Род: Ах! Понял ...
Час Браун
3

Желе , 8 байт

ẋ"ỤỤ$z⁶Q

Попробуйте онлайн!

идея

Основная идея состоит в том, чтобы создавать столбцы желаемого результата напрямую, а не манипулировать строкой и возвращать все промежуточные результаты.

Начнем с нумерации символов входной строки в порядке их удаления. На данный момент мы будем делать вид, что пробелы также будут удалены.

tee ay oh
845139276

Теперь мы строим столбцы, повторяя каждый символ по индексу в этом перечислении.

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

Осталось только удалить дубликаты, чтобы учесть пробелы.

Код

ẋ"ỤỤ$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.
Деннис
источник
3

Perl 5 -n , 37 34 байта

Сбросил три байта с помощью @TonHospel

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

Попробуйте онлайн!

Xcali
источник
Ах, очень хороший, намного более хороший подход! Я думаю, что вам нужно \Qхотя бы для последнего теста ... Я пропустил это и в первый раз!
Дом Гастингс
Вы правы. Добавил это.
Xcali
Короче: say&&s/\Q$a/ / while($a)=sort/\S/g. Также правильно обрабатывает0
Тон Хоспел
3

JavaScript, 67 66 65 байт

Потому что я давно не играл в гольф!

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

Попробуйте онлайн

Спасибо DanielIndie за указание 4 избыточных байтов, которые включены в пиво!

мохнатый
источник
почему вы указываете у на карте? : P это можно сделать 67
DanielIndie
@DanielIndie, потому что пиво! : D Спасибо за указание на это.
Лохматый
да, я думал, что это будет так: P
DanielIndie
3

K (нгн / к) , 26 24 байта

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

Попробуйте онлайн!

СПП
источник
Красивый! Моя попытка K пришла в 41: `{. [X; (- 1 + # x) & x? _Ci & / _ ic x _dv" ";:;" "]}` Я трачу байты, конвертируя в int и обратно и делая уверен, что это не выходит за пределы.
урыга
@uryga Спасибо. Если бы я правильно реализовал проекции, {@[x;y;:;" "]}мог бы быть @[;;:;" "]. Какую версию k вы используете? Я не знаком с этим _ci _ic _dv.
августа
Я думаю, что это 2,8-иш? Я использую интерпретатор Kona, который предоставляет операторы как встроенные: char-of-int, int-of-char, delete-value.
урыга
2

C # (интерактивный компилятор Visual C #) , 129 байт

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," ");}

Попробуйте онлайн!

Павел
источник
c!=32может быть c>32; c==32может быть c<33; и (char)999может быть '¡'(или любым другим символом выше диапазона Unicode для печати ASCII).
Кевин Круйссен,
О, и вы можете сэкономить еще два байта изменяя whileк forи размещении var s=ReadLine()и s=s.Remove(i,1).Insert(i," ")внутри него (так что две точки с запятой больше не требуется).
Кевин Круйссен,
2

Haskell , 67 байт

12 байтов сэкономлено благодаря Laikoni

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

Попробуйте онлайн!

Этот заканчивается в ошибке

Haskell , 83 79 байт

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

Попробуйте онлайн!

Этот заканчивается в ошибке

Haskell , 86 байт

u=concat.words
g(a,_:b)=a++' ':b
(take.length.u)<*>(iterate$g.(span=<<(/=).minimum.u))

Попробуйте онлайн!

Haskell , 100 91 88 байт

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

Попробуйте онлайн!

Мастер пшеницы
источник
67 байт: f s|(a,_:b)<-span(/=minimum(id=<<words s))s=putStrLn s>>f(a++' ':b) попробуйте онлайн!
Лайкони
@Laikoni Спасибо! Я был на грани чего-то подобного, и я уснул. Однако я не думаю, что мог бы придумать id=<<это довольно умно
Wheat Wizard
2

K4 , 28 20 18 байт

Решение:

?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        "
"               "

Объяснение:

Это то же самое, что делает ngn . Найдите индексы, которые приведут к появлению списка по возрастанию, перезапишите их один за другим " ", а затем возьмите отличительные, чтобы удалить дубликаты строк:

?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
streetster
источник
2

gcc 32-bit, 66 65 bytes

char*p,i;f(a){for(i=32;i++;)for(p=a;*p;)*p==i?puts(a),*p=32:++p;}
main(){char s[]="3.1415926";f(s);}

Спасибо за Джонатана Фреха за -1 байт

l4m2
источник
*p==i?...:0;возможно, может быть *p-i?0:...;.
Джонатан Фрех
@JonathanFrech Нет, это на 1 байт длиннее (хотя и *p-1||(...)такой же длины)
l4m2
Извините, не признал важность сохранения запятой вместе. Однако это может быть 65 байтов . Я также не знаю, как f(a)компилируется, как aдолжно быть типа char*, но я предполагаю, что это как-то связано с вашим 32-разрядным использованием GCC.
Джонатан Фрех
@JonathanFrech Я думаю, что char*p,i;f(long long a){for(i=31;++i;)for(p=a;*p;)*p==i?puts(a),*p=32:++p;}на tio (64 бита ) можно объяснить, как f(a)работает
l4m2
Я извиняюсь, хотя я спросил у ОП о спецификациях вызова, и они сказали, что входная строка может начинаться с пробела. Поэтому мое предложенное решение является недействительным (так как такой ввод приводит к бесконечному циклу), и вам, скорее всего, следует вернуться к исходному решению.
Джонатан Фрех
2

MATLAB, 74 байта

При этом используется 2-выходная форма функции max () для получения наименьшего символа и его индекса, преобразовав строку в нулевые значения в пробелах и 256-символьное значение для печатных символов.

s=input('s');x=1;while(x);disp(s);[x,y]=max((256-s).*(s~=' '));s(y)=' ';end
Ричард
источник
1
Добро пожаловать в PPCG! Хорошо сделано!
AJFaraday
2

Common Lisp , 240 228 224 байта

(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))))

Попробуйте онлайн!

Это моя первая публикация.
Я нахожусь в процессе изучения шрифта, поэтому я уверен, что кто-то может придумать что-то более короткое, чем это.

JoshM
источник
1
Добро пожаловать на сайт! Приятно видеть некоторые общие шутки!
Пшеничный волшебник
1

APL (Dyalog Unicode) , 39 байтов SBCS

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

Попробуйте онлайн!

Dfn.

Как?

{⎕←⍵⋄×≢⍵∩g' '~⍨⎕UCS256:∇' '@(⊃g⍋⍵)⊢⍵}  Main function, argument 
 ⎕←⍵⋄                                     Print 
         g' '~⍨⎕UCS256                  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.
Ж. Салле
источник
1

PowerShell , 103 99 байт

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

Попробуйте онлайн!

Принимает ввод как строку в $a. Затем мы выполняем цикл от 2до $a.length(т.е. соответствующее количество вертикальных времен, необходимых для удаления всех символов, кроме одного). Каждую итерацию мы выводим текущую строку и удобно сохраняем в $xодно и то же время. Затем мы строим новый [regex]объект, $pattern состоящий из оставшихся символов $a, которые -nВЗ eкаче пространству, sortизд, то 0й один из них.

Затем мы устанавливаем $aравным новую строку объекта regex с .Replaceметодом для замены в строке $x, $pattern, пробелом " ", но только с соответствием 1st. Да, этот синтаксис странный.

Строки остаются в конвейере, и неявный Write-Outputдает нам новую строку между ними бесплатно, плюс один завершающий перевод строки.

AdmBorkBork
источник
1

Java (JDK 10) , 140 байт

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);}

Попробуйте онлайн!

Технически есть пустая строка, но она не пустая .

Оливье Грегуар
источник
1

MATL , 17 16 байт

tSXz"tOy@=f1)(]x

Попробуйте онлайн! Или проверьте все тестовые случаи .

объяснение

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
Луис Мендо
источник
1

Excel VBA, 167 байт

Функция анонимного непосредственного окна VBE, которая берет входные данные из диапазона [A1]и выводит в непосредственное окно VBE.

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 и комментируется

''  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
    Next
End Sub
Тейлор Скотт
источник