-join("$args"-split'\b'|%{(,$(,$_[0]*$n+$_))[!!($n=$($_-1))]})
Спробуйте в Інтернеті!
Зламатися
Який безлад!
Починаючи з $args, що представляє собою єдиний масив елементів, що містить рядок RLE, я змушую його до фактичного рядка, загортаючи його в лапки.
Потім розділіть його за межею слова ( \bв регулярному виразі). Це дасть мені масив рядків, де кожен елемент є або числом, або BF-маркерами, які надходять після числа. Таким чином , в прикладі, перші 4 елемента цього масиву є спліт 10, +]>+>, 3,+> (всі рядки).
Далі я передаю це в ForEach-Object( %) для обробки кожного елемента .
Середина - добре відомий гольфізм PowerShell, з поворотом; це, по суті, потрійний оператор DIY, в якому ви створюєте масив з двома елементами, а потім індексуєте його за допомогою булевого виразу, яке ви хочете перевірити, при цьому помилковий результат дає вам елемент 0, а справжній результат дає елемент 1.
У цьому випадку я фактично створюю єдиний масив елементів з унарною комою , оператором , тому що я не хочу виводити в справжньому випадку.
Спочатку давайте подивимось на індексатор, хоча він буде виконаний пізніше.
Ідея цього полягає в тому, що $_(поточний елемент) може бути або дійсним числом, або деяким іншим рядком. Якщо це число, я хочу $nбути значенням цього числа мінус 1 (як число, а не рядок). Якщо це не так, я хочу $nбути помилковим.
Зазвичай PowerShell намагається примусити праворучне значення до типу лівої сторони, але це може залежати від операції. Крім того, "10"+5дасть вам нову рядок "105", тоді як 10+"5"дасть вам ціле число ( 15).
Але рядки не можна віднімати, тому натомість PowerShell може автоматично виводити числове значення за допомогою рядка з лівого боку віднімання, тому "10"-5дає5 .
Отже, я починаю з того $_-1, що дасть мені число, яке я хочу, коли $_насправді це число, але коли це не так, я нічого не отримую. На поверхні "фальсифікація" нічого, але проблема полягає в тому, що це зупиняє виконання цього завдання, тому $nзбереже попереднє значення; не те, що я хочу!
Якщо я обернути його в подвираженія, а потім , коли це не вдається, я отримую свою цінність falsey: $($_-1).
Якщо все присвоюється, $nі оскільки це призначення саме загорнене в круглі дужки, значення, яке було призначено, $nтакож передається в конвеєр.
Оскільки я використовую його в індексаторі, і я хочу, 1якщо перетворення вдалося, я використовую два булеві notвирази !!для перетворення цього значення в булеве. Успішне перетворення чисел закінчується як істинне, тоді як фальсийне небуття дає нам це миле, миле0 яке дозволяє повернути єдиний елемент у цьому підробленому потрійному масиві.
Повертаючись до цього масиву, елемент полягає в наступному: $("$($_[0])"*$n*$_) $(,$_[0]*$n+$_)
"$($_[0])"- це набридливо довгий шлях отримання першого символу поточного елемента (скажімо, отримання +від +[>+), але як рядок, а не як [char]об'єкт. Мені потрібно, щоб це був рядок, тому що я можу помножити рядок на число, щоб дублювати його, але я не можу зробити це з символом.
Насправді мені вдалося зберегти 4 символи, використовуючи [char]масив замість рядка (за допомогою іншої унарної коми ,), тому мені вдалося видалити лапки та додатковий підвираз. Я можу помножити масив, щоб дублювати його елементи. А оскільки весь результат цієї ітерації все-таки стає масивом і повинен бути-join редагувати, використання масиву тут не додаткових витрат.
Потім я помножую цей рядковий масив на $n, щоб дублювати його $nразів. Нагадаємо, що $nможе бути $nullабо може бути значення попередніх цифр мінус одна.
Потім +$_додає поточний елемент до кінця дублюється першого символу цього елемента. Ось чому $nмінус один.
Таким чином, в 10+[>+кінцевому підсумку $nдорівнює 9, потім робимо 9 +і додаємо це назад до +[>+рядка, щоб отримати необхідний 10, плюс інші окремі елементи для проїзду.
Елемент загорнутий у підвираз, $()тому що коли $nє $null, весь вираз виходить з ладу, тому створення масиву виходить з ладу, тому індексатор ніколи не працює, тому $nніколи не присвоюється.
Причина, по якій я застосував цей потрійний трюк, полягає в одній із його особливостей: на відміну від реального потрійного оператора, вирази, що визначають елементи , оцінюються незалежно від того, чи вони обрані чи ні, і спочатку з цього питання.
Оскільки мені потрібно призначити, а потім використовувати $nдля окремих ітерацій, це корисно. Значення елемента потрійного масиву оцінюється за значенням попередньої ітерації $n, потім індексатор повторно призначає$n поточну ітерацію.
Таким чином, ForEach-Objectцикл закінчується виведенням всього, що належить (купі помилок, які ми ігноруємо), але як масив нових рядків.
Таким чином, вся ця річ загортається в дужки, а потім передує унарному, -joinщоб дати вихідний рядок.