-join("$args"-split'\b'|%{(,$(,$_[0]*$n+$_))[!!($n=$($_-1))]})
Cobalah online!
Kerusakan
Berantakan sekali!
Mulai dari $args
, yang merupakan array elemen tunggal yang berisi string RLE, saya memaksa menjadi string yang sebenarnya dengan membungkusnya dengan tanda kutip.
Kemudian pisahkan dengan batas kata ( \b
dalam regex). Itu akan memberi saya array string, di mana setiap elemen adalah angka atau token BF yang datang setelah angka. Jadi dalam contoh, pertama 4 elemen array perpecahan ini 10
, +]>+>
, 3
, +>
(semua string).
Selanjutnya, saya pipa itu ke ForEach-Object
( %
) untuk menangani setiap elemen .
Bagian tengahnya adalah golfism PowerShell yang terkenal, dengan twist; itu pada dasarnya operator DIY ternary, di mana Anda membuat array 2 elemen kemudian indeks ke dalamnya menggunakan ekspresi boolean yang ingin Anda uji, di mana hasil yang salah memberi Anda elemen 0 dan hasil yang benar memberi Anda elemen 1.
Dalam hal ini, saya benar-benar membuat array elemen tunggal dengan ,
operator koma unary , karena saya tidak ingin output dalam kasus yang sebenarnya.
Pertama mari kita lihat pengindeks, meskipun dieksekusi nanti.
Gagasannya adalah $_
(elemen saat ini) dapat berupa angka yang valid, atau string lain. Jika itu angka, saya ingin $n
menjadi nilai angka itu minus 1 (sebagai angka, bukan string). Jika tidak, saya mau$n
salah-y.
PowerShell biasanya mencoba untuk memaksa nilai kanan ke jenis sisi kiri, tetapi itu bisa bergantung pada operasi. Sebagai tambahan, "10"+5
akan memberi Anda string baru "105"
,, sedangkan 10+"5"
akan memberi Anda integer (15
).
Tetapi string tidak dapat dikurangi sehingga PowerShell dapat menyimpulkan nilai numerik secara otomatis dengan string di sisi kiri pengurangan, oleh karena itu "10"-5
memberi 5
.
SO, saya mulai dengan $_-1
, yang akan memberi saya nomor yang saya inginkan ketika $_
sebenarnya angka, tetapi ketika tidak, saya tidak mendapatkan apa-apa. Di permukaan, "tidak ada" adalah falsey, tetapi masalahnya adalah berhenti menjalankan tugas itu, jadi$n
akan mempertahankan nilai sebelumnya; bukan yang saya inginkan!
Jika saya membungkusnya dalam subekspresi, maka ketika gagal, saya mendapatkan nilai falsey saya: $($_-1)
.
Bahwa semua ditugaskan $n
dan karena tugas itu sendiri dibungkus dengan tanda kurung, nilai yang ditugaskan $n
juga akan diteruskan ke pipa.
Karena saya menggunakannya di pengindeks, dan saya ingin 1
jika konversi berhasil, saya menggunakan dua not
ekspresi boolean !!
untuk mengubah nilai ini menjadi boolean. Konversi angka yang sukses berakhir sebagai benar, sedangkan ketiadaan falsey memberi kita manis, manis 0
yang memungkinkan untuk mengembalikan satu-satunya elemen dalam array ternary palsu itu.
Kembali ke array itu, elemennya adalah ini: $("$($_[0])"*$n*$_)
$(,$_[0]*$n+$_)
"$($_[0])"
- Ini adalah cara yang sangat panjang untuk mendapatkan karakter pertama dari elemen saat ini (katakanlah, dapatkan +
dari +[>+
), tetapi sebagai string dan bukan sebagai[char]
objek. Saya membutuhkannya untuk menjadi string karena saya dapat mengalikan string dengan angka untuk menduplikasi, tetapi saya tidak bisa melakukannya dengan karakter.
Sebenarnya saya berhasil menyimpan 4 karakter dengan menggunakan [char]
array alih-alih string (dengan menggunakan koma unary lain ,
), jadi saya dapat menghapus tanda kutip dan sub-ekspresi tambahan. Saya bisa mengalikan array untuk menduplikasi elemen-elemennya. Dan karena seluruh hasil iterasi ini akhirnya menjadi sebuah array dan perlu-join
diedit, menggunakan array di sini tidak menimbulkan biaya tambahan.
Lalu, saya kalikan array string itu dengan $n
, untuk menduplikasinya $n
kali. Ingat itu $n
bisa terjadi$null
atau bisa nilai digit sebelumnya minus satu.
Kemudian +$_
tambahkan elemen saat ini ke akhir karakter pertama yang digandakan dari elemen itu. Itu sebabnya $n
minus satu.
Dengan cara ini, 10+[>+
berakhir dengan $n
sama dengan 9, maka kita menghasilkan 9+
's dan menambahkannya kembali ke +[>+
string untuk mendapatkan 10 yang diperlukan, ditambah elemen tunggal lainnya sepanjang untuk perjalanan.
Unsur ini dibungkus subexpression sebuah $()
karena ketika $n
adalah$null
, seluruh ekspresi gagal, sehingga menciptakan array gagal, sehingga pengindeks tidak pernah berjalan, sehingga$n
tidak pernah akan ditugaskan.
Alasan saya menggunakan trik ternary ini adalah karena salah satu kekhasannya: tidak seperti operator ternary nyata, ekspresi yang menentukan elemen lakukan bisa dievaluasi apakah atau tidak mereka "dipilih", dan pertama dalam hal ini.
Karena saya perlu menetapkan dan kemudian menggunakannya $n
pada iterasi yang terpisah, ini sangat membantu. Nilai elemen array ternary akan dievaluasi dengan nilai iterasi sebelumnya $n
, kemudian pengindeks ditugaskan kembali $n
untuk iterasi saat ini.
Sehingga ForEach-Object
loop akhirnya menghasilkan semua yang seharusnya (banyak kesalahan yang kita abaikan), tetapi sebagai array dari string baru.
Sehingga semuanya dibungkus dalam tanda kurung dan kemudian didahului oleh unary -join
untuk memberikan string keluaran.