-join("$args"-split'\b'|%{(,$(,$_[0]*$n+$_))[!!($n=$($_-1))]})
Experimente online!
Demolir
Que bagunça!
Começando de $args
, que é uma matriz de elemento único que contém a string RLE, estou forçando uma string real, envolvendo as aspas.
Em seguida, divida-o pelo limite da palavra ( \b
em regex). Isso me dará uma matriz de strings, onde cada elemento é um número ou o (s) token (s) BF que vem após o número. Assim, no exemplo, os primeiros elementos 4 de matriz esta separação são 10
, +]>+>
, 3
,+>
(todos são corda).
Em seguida, canalizo isso para ForEach-Object
( %
) para lidar com cada elemento .
O meio é um conhecido golfismo do PowerShell, com um toque; é essencialmente um operador ternário DIY, no qual você cria uma matriz de 2 elementos e a indexa usando a expressão booleana que deseja testar, em que um resultado falso fornece o elemento 0 e um resultado verdadeiro fornece o elemento 1.
Nesse caso, eu realmente crio uma matriz de elemento único com a vírgula unária ,
, porque não quero saída no caso verdadeiro.
Primeiro, vamos olhar para o indexador, mesmo que seja executado mais tarde.
A ideia disso é que $_
(o elemento atual) possa ser um número válido ou alguma outra string. Se for um número, quero $n
ser o valor desse número menos 1 (como um número, não como uma sequência). Se não for, eu quero$n
ser falso.
O PowerShell geralmente tenta coagir o valor do lado direito ao tipo do lado esquerdo, mas pode depender da operação. Além disso,"10"+5
forneceria uma nova string,, "105"
enquanto 10+"5"
forneceria um número inteiro ( 15
).
Como as seqüências não podem ser subtraídas, o PowerShell pode inferir o valor numérico automaticamente com uma sequência no lado esquerdo da subtração. Portanto, "10"-5
fornece 5
.
Então, eu começo com $_-1
, o que me dará o número que eu quero quando $_
na verdade é um número, mas quando não é, não recebo nada. Na superfície, "nada" é falsey, mas o problema é que interrompe a execução dessa atribuição, $n
mantendo assim seu valor anterior; não é o que eu quero!
Se o envolver em uma subexpressão, quando falhar, obtenho meu valor de falsey: $($_-1)
.
Tudo isso é atribuído a $n
e, uma vez que essa atribuição é entre parênteses, o valor que foi atribuído a$n
também é passado para o pipeline.
Como estou usando-o no indexador e quero 1
que a conversão seja bem-sucedida, uso duas not
expressões booleanas !!
para converter esse valor em booleano. Uma conversão bem-sucedida de números acaba sendo verdadeira, enquanto o nada falsey nos dá aquele doce, doce0
que permite retornar o único elemento nesse falso array ternário.
Voltando a essa matriz, o elemento é este: $("$($_[0])"*$n*$_)
$(,$_[0]*$n+$_)
"$($_[0])"
- esta é uma maneira irritantemente longa de obter o primeiro caractere do elemento atual (digamos, sair +
de +[>+
), mas como uma string e não como um [char]
objeto. Preciso que seja uma sequência, porque eu posso multiplicar uma sequência por um número para duplicá-la, mas não posso fazer isso com um caractere.
Na verdade, eu consegui salvar 4 caracteres usando uma [char]
matriz em vez de uma string (usando outra vírgula unária ,
), para que eu pudesse remover as aspas e subexpressão extra. Eu posso multiplicar uma matriz para duplicar seus elementos. E como todo o resultado dessa iteração acaba sendo uma matriz de qualquer maneira e precisa ser-join
editado, o uso de uma matriz aqui não gera custos adicionais.
Então, eu multiplicar esse corda array $n
, para duplicá-lo $n
vezes. Lembre-se de que $n
poderia ser $null
ou poderia ser o valor dos dígitos anteriores menos um.
Em seguida, +$_
adiciona o elemento atual ao final do primeiro caractere duplicado desse elemento. É por isso que $n
é menos um.
Dessa forma, 10+[>+
termina com $n
igual a 9, então criamos 9 +
e adicionamos isso de volta à +[>+
string para obter os 10 necessários, além dos outros elementos únicos durante o passeio.
O elemento é envolvido em uma subexpressão $()
porque, quando $n
ocorre $null
, toda a expressão falha, portanto, a criação da matriz falha, portanto o indexador nunca é executado e $n
nunca é designado.
A razão pela qual usei esse truque ternário é por causa de uma de suas peculiaridades: ao contrário de um operador ternário real, as expressões que definem os elementos fazer se avaliou se eles estão ou não "selecionado", e em primeiro lugar para esse assunto.
Como preciso atribuir e usar $n
em iterações separadas, isso é útil. O valor do elemento ternário da matriz é avaliado com o $n
valor da iteração anterior e , em seguida, o indexador reatribui$n
para a iteração atual.
Então o ForEach-Object
loops acabam gerando tudo o que deveria (um monte de erros que ignoramos), mas como uma série de novas strings.
Portanto, tudo é colocado entre parênteses e precedido por unário -join
para fornecer a sequência de saída.