GNU sed , 178 158 132 + 1 = 133 bajty
+1 bajt dla -rflagi.
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
Wypróbuj online!
Wyjaśnienie
W poprzednich wersjach używałem wielu bajtów zajmujących się matematyką, specjalnymi przypadkami i porządkami, chociaż intuicyjnie byłem pewien, że można ich uniknąć. Od tego czasu głównie to zrobiłem.
Załóżmy, że mamy dane wejściowe abcdEFGHIJKLMnop. Litery EFGHIJKLMbędą na dole trójkąta, więc wykorzystałem je jako pomoc wizualną.
Najpierw przygotowujemy dane wejściowe, umieszczając pierwszy znak we własnej linii (poprzedzonej spacją) i wstawiając kursor ( ;) przed ostatnim znakiem:
s/(.)(.*)(.)/ \1\n\2;\3/
Teraz mamy:
a
bcdEFGHIJKLMno;p
Teraz, w pętli, zrobimy kilka rzeczy do ostatniego wiersza: 1. Skopiuj spacje z poprzedniego wiersza i wstaw je po pierwszym znaku plus dwa; 2. Przenieś ostatni znak w prawo za spacjami, a następnie nowy wiersz; i 3. Przesuń kursor o trzy znaki w lewo.
:
s/( *)(.\n.)(.*)(...);(.*)(.)/\1\2\1 \6\n\3;\4\5/m
t
Oto wynik każdej iteracji:
a
b p
cdEFGHIJKL;Mno
a
b p
c o
dEFGHI;JKLMn
a
b p
c o
d n
EF;GHIJKLM
Możesz zobaczyć, jak piramida zaczyna nabierać kształtu. Możesz także zobaczyć, do czego służył kursor: w każdej iteracji przesuwał się w lewo o trzy znaki, a gdy nie ma już trzech znaków po jego lewej stronie, przerywa pętlę, co zdarza się, gdy osiągamy „dół” piramidy.
Teraz zrobimy podobną operację, ale w odwrotnej kolejności. W pętli skopiujemy spacje od początku linii kursorem do początku poprzedniej linii plus jeden, w trakcie przesuwania kursora do tej linii.
:A
s/(.*\n)( *)(.*);/ \2;\1\2\3/m
tA
Oto kilka iteracji i wynik końcowy:
a
b p
c o
;d n
EFGHIJKLM
a
b p
;c o
d n
EFGHIJKLM
...
; a
b p
c o
d n
EFGHIJKLM
Skończyliśmy teraz, z wyjątkiem kilku dodatkowych znaków: A ;i dodatkowe spacje w pierwszej linii oraz dwa spacje w „środku” piramidy w następnych trzech liniach. Pozbywa się ich prosta zamiana:
s/. (.)$/\1/gm
Wszystko gotowe!
a
b p
c o
d n
EFGHIJKLM
✂s?