GNU sed , 178 158 132 + 1 = 133 byte
+1 byte untuk -r
bendera.
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
Cobalah online!
Penjelasan
Dalam revisi sebelumnya saya menggunakan banyak byte yang berurusan dengan matematika, kasus khusus, dan pembersihan, meskipun secara intuitif saya yakin mereka bisa dihindari. Sejak itu saya berhasil melakukannya, kebanyakan.
Misalkan kita punya input abcdEFGHIJKLMnop
. Surat-surat EFGHIJKLM
akan menjadi bagian bawah segitiga, jadi saya telah memanfaatkannya sebagai alat bantu visual.
Pertama kita menyiapkan input dengan meletakkan karakter pertama pada barisnya sendiri (didahului oleh spasi) dan memasukkan kursor ( ;
) sebelum karakter terakhir:
s/(.)(.*)(.)/ \1\n\2;\3/
Sekarang kita punya:
a
bcdEFGHIJKLMno;p
Sekarang, dalam satu lingkaran, kita akan melakukan beberapa hal ke baris terakhir: 1. Salin spasi dari baris sebelumnya dan masukkan setelah karakter pertama, ditambah dua; 2. Pindahkan karakter terakhir ke kanan setelah spasi, diikuti oleh baris baru; dan 3. Pindahkan kursor tiga karakter ke kiri.
:
s/( *)(.\n.)(.*)(...);(.*)(.)/\1\2\1 \6\n\3;\4\5/m
t
Inilah hasil dari setiap iterasi:
a
b p
cdEFGHIJKL;Mno
a
b p
c o
dEFGHI;JKLMn
a
b p
c o
d n
EF;GHIJKLM
Anda dapat melihat piramida mulai terbentuk. Anda juga dapat melihat untuk apa kursor itu: Di setiap iterasi, kursor itu bergerak ke kiri tiga karakter, dan ketika tidak ada lagi tiga karakter di sebelah kirinya, itu mematahkan loop, yang kebetulan hanya ketika kita telah mencapai "bawah" dari piramida.
Sekarang kita akan melakukan operasi serupa tetapi secara terbalik. Dalam satu lingkaran, kami akan menyalin spasi dari awal baris dengan kursor ke awal baris sebelumnya, ditambah satu, dalam proses memindahkan kursor ke baris itu.
:A
s/(.*\n)( *)(.*);/ \2;\1\2\3/m
tA
Berikut adalah beberapa iterasi dan hasil akhirnya:
a
b p
c o
;d n
EFGHIJKLM
a
b p
;c o
d n
EFGHIJKLM
...
; a
b p
c o
d n
EFGHIJKLM
Kita semua sudah selesai sekarang, kecuali untuk beberapa karakter tambahan: A ;
dan ruang ekstra pada baris pertama, dan dua ruang di "tengah" piramida pada tiga baris berikutnya. Substitusi sederhana menghilangkan mereka:
s/. (.)$/\1/gm
Semua selesai!
a
b p
c o
d n
EFGHIJKLM
✂
lakukan?