-join("$args"-split'\b'|%{(,$(,$_[0]*$n+$_))[!!($n=$($_-1))]})
Попробуйте онлайн!
Сломать
Какой беспорядок!
Начиная с $args , который является массивом из одного элемента, содержащего строку RLE, я добавляю фактическую строку, заключая ее в кавычки.
Затем разделите его по границе слова ( \bв регулярном выражении). Это даст мне массив строк, где каждый элемент является либо номером, либо токеном (ами) BF, которые идут после числа. Таким образом , в примере, первые 4 элемента этого массива являются сплит 10, +]>+>, 3,+> (все строки).
Затем я передаю это в ForEach-Object( %) для работы с каждым элементом .
Середина - хорошо известный гольфизм PowerShell с изюминкой; по сути это троичный оператор DIY, в котором вы создаете массив из 2 элементов, а затем индексируете его, используя логическое выражение, которое вы хотите проверить, в результате чего ложный результат дает вам элемент 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чтобы получить строку вывода.