GNU sed , 178 158 132 + 1 = 133 bytes
+1 byte para -r
sinalizador.
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
Experimente online!
Explicação
Nas revisões anteriores , usei muitos bytes lidando com matemática, casos especiais e limpeza, embora intuitivamente eu tivesse certeza de que eles poderiam ser evitados. Desde então, consegui fazê-lo, principalmente.
Suponha que tenhamos a entrada abcdEFGHIJKLMnop
. As letras EFGHIJKLM
estarão na parte inferior do triângulo, então eu as coloquei em maiúsculas como uma ajuda visual.
Primeiro, preparamos a entrada colocando o primeiro caractere em sua própria linha (precedido por um espaço) e inserindo um cursor ( ;
) antes do último caractere:
s/(.)(.*)(.)/ \1\n\2;\3/
Agora temos:
a
bcdEFGHIJKLMno;p
Agora, em um loop, faremos algumas coisas até a última linha: 1. Copie os espaços da linha anterior e insira-os após o primeiro caractere, mais dois; 2. Mova o último caractere para a direita após os espaços, seguido por uma nova linha; e 3. Mova o cursor três caracteres para a esquerda.
:
s/( *)(.\n.)(.*)(...);(.*)(.)/\1\2\1 \6\n\3;\4\5/m
t
Aqui está o resultado de cada iteração:
a
b p
cdEFGHIJKL;Mno
a
b p
c o
dEFGHI;JKLMn
a
b p
c o
d n
EF;GHIJKLM
Você pode ver a pirâmide começar a tomar forma. Você também pode ver para que serve o cursor: em cada iteração, ele moveu para a esquerda três caracteres e, quando não há mais três caracteres à esquerda, ele interrompe o loop, que acontece exatamente quando atingimos o "fundo" da pirâmide.
Agora vamos fazer uma operação semelhante, mas ao contrário. Em um loop, copiaremos os espaços do início da linha com o cursor para o início da linha anterior, mais um, no processo de mover o cursor até essa linha.
:A
s/(.*\n)( *)(.*);/ \2;\1\2\3/m
tA
Aqui estão algumas iterações e o resultado final:
a
b p
c o
;d n
EFGHIJKLM
a
b p
;c o
d n
EFGHIJKLM
...
; a
b p
c o
d n
EFGHIJKLM
Já terminamos agora, exceto alguns caracteres extras: A ;
e espaço extra na primeira linha e dois espaços no "meio" da pirâmide nas próximas três linhas. Uma simples substituição se livra deles:
s/. (.)$/\1/gm
Tudo feito!
a
b p
c o
d n
EFGHIJKLM
✂
s fazem?