GNU sed , 178 158 132 + 1 = 133 байта
+1 байт за -r
флаг.
s/(.)(.*)(.)/ \1\n\2;\3/
:
s/( *)(.\n.)(.*)(...);(.*)(.)/\1\2\1 \6\n\3;\4\5/m
t
:A
s/(.*\n)( *)(.*);/ \2;\1\2\3/m
tA
s/. (.)$/\1/gm
Попробуйте онлайн!
объяснение
В предыдущих версиях я использовал много байтов, связанных с математикой, особыми случаями и очисткой, хотя интуитивно я был уверен, что их можно избежать. С тех пор мне это удалось, в основном.
Предположим, у нас есть вход abcdEFGHIJKLMnop
. Буквы EFGHIJKLM
будут в нижней части треугольника, поэтому я использовал их в качестве наглядного пособия.
Сначала мы подготовим ввод, поместив первый символ в отдельной строке (с пробелом) и вставив курсор ( ;
) перед последним символом:
s/(.)(.*)(.)/ \1\n\2;\3/
Теперь у нас есть:
a
bcdEFGHIJKLMno;p
Теперь, в цикле, мы собираемся сделать несколько вещей до последней строки: 1. Скопируйте пробелы из предыдущей строки и вставьте их после первого символа плюс два; 2. Переместите последний символ справа после пробелов, за которым следует новая строка; и 3. Переместите курсор на три символа влево.
:
s/( *)(.\n.)(.*)(...);(.*)(.)/\1\2\1 \6\n\3;\4\5/m
t
Вот результат каждой итерации:
a
b p
cdEFGHIJKL;Mno
a
b p
c o
dEFGHI;JKLMn
a
b p
c o
d n
EF;GHIJKLM
Вы можете видеть, как пирамида начинает обретать форму. Вы также можете увидеть, для чего был выбран курсор: на каждой итерации он перемещался влево на три символа, а когда слева уже не осталось трех символов, он прерывал цикл, как раз тогда, когда мы достигли «дна» пирамиды.
Теперь мы собираемся сделать аналогичную операцию, но в обратном порядке. В цикле мы скопируем пробелы от начала строки с курсором до начала предыдущей строки, плюс один, в процессе перемещения курсора к этой строке.
:A
s/(.*\n)( *)(.*);/ \2;\1\2\3/m
tA
Вот пара итераций и конечный результат:
a
b p
c o
;d n
EFGHIJKLM
a
b p
;c o
d n
EFGHIJKLM
...
; a
b p
c o
d n
EFGHIJKLM
Мы все закончили, за исключением некоторых дополнительных символов: A ;
и дополнительного пробела в первой строке и двух пробелов в «середине» пирамиды в следующих трех строках. Простая замена избавляет от них:
s/. (.)$/\1/gm
Все сделано!
a
b p
c o
d n
EFGHIJKLM
✂
с?