Dicas para jogar golfe na Retina

10

Que dicas gerais você tem para jogar golfe em Retina ? Estou procurando idéias que possam ser aplicadas para codificar problemas de golfe em geral que sejam pelo menos um pouco específicos da Retina (por exemplo, "remover comentários" não é uma resposta). Poste uma dica por resposta.

Para referência, o compilador online está aqui .

@ Sp3000 apontou que também há dicas para o Regex Golf . As respostas aqui devem se concentrar especificamente nos recursos do Retina e não nas dicas gerais de golfe regex.

Trauma Digital
fonte
2
Related: Dicas para regex golf
Sp3000 9/16
Hmmm, eu adiei postar isso porque o Retina ainda está em desenvolvimento e eu estava com medo de que a maioria das respostas acabasse sendo dicas simples de regex, não muito específicas para o Retina. Mas podemos também dar uma chance, eu acho ... :)
Martin Ender
@ MartinBüttner Você e alguns outros me deram muitas dicas e sugestões desde que comecei a olhar para a Retina, então acho que provavelmente é hora de isso. Eu adicionei um esclarecimento de que as dicas gerais sobre regex devem ir para a pergunta vinculada.
Digital Trauma
11
@ MartinBüttner Aqui é um lugar tão bom quanto qualquer um para perguntar - eu estive pensando por um tempo - por curiosidade, qual é a inspiração para o nome "Retina"? Presumo que a parte "Re" seja para Expressão Regular, mas e a "tina"?
Digital Trauma
3
@DigitalTrauma Eu estava tentando criar uma palavra legal que funcionasse como um acrônimo, mas falhou. A palavra "retina" estava bem próxima de algumas das tentativas, e gostei da palavra. Eu nunca consegui reconfigurá-lo em um acrônimo e, desde então, desisti disso. Então sim, o "re" é uma espécie de "expressões regulares" e talvez o "n" de ".NET", mas, no final das contas, é apenas uma palavra que soou legal.
Martin Ender

Respostas:

3

Combine loops, se possível

Em cálculos não triviais, muitas vezes você se encontra usando vários loops para processar dados:

+`stage1
+`stage2
+`stage3

Portanto, isso é executado stage1até a saída convergir, depois stage2até a saída convergir e depois stage3até a saída convergir.

No entanto, sempre vale a pena examinar as etapas em detalhes. Às vezes é possível executar o loop de maneira intercalada stage1, stage2, stage3, stage1, stage2, stage3, ...(isso depende muito do que os estágios realmente fazem, mas às vezes eles fazem mudanças completamente ortogonais ou funcionam bem como um pipeline). Nesse caso, você pode salvar bytes envolvendo-os em um único loop:

{`stage1
stage2
}`stage3

Se stage1for o primeiro estágio ou stage3o último estágio do programa, você também pode omitir esses parênteses (o que significa que isso já pode salvar bytes para um loop de dois estágios).

Um uso recente dessa técnica pode ser visto nesta resposta .

Martin Ender
fonte
2

Dividindo cordas em pedaços de igual comprimento n

Como na maioria dos idiomas "normais" do TMTOWTDI (há mais de uma maneira de fazer isso). Estou assumindo aqui que a entrada não contém feeds de linha e que "dividir" significa dividi-la em linhas. Mas existem dois objetivos bem diferentes: se o comprimento da corda não for um múltiplo do tamanho do pedaço, você deseja manter o pedaço incompleto à direita ou deseja descartá-lo?

Mantendo um pedaço incompleto à direita

Em geral, existem três maneiras de dividir a Retina. Estou apresentando as três abordagens aqui, porque elas podem fazer uma diferença maior quando você tenta adaptá-las a um problema relacionado. Você pode usar uma substituição e anexar um avanço de linha a cada correspondência:

.{n}
$&¶

São 8 bytes (ou um pouco menos, se n = 2ou n = 3porque você pode usar ..ou ...respectivamente). Porém, isso tem um problema: acrescenta um avanço de linha adicional se o comprimento da string for um múltiplo do comprimento do pedaço.

Você também pode usar um estágio dividido e fazer uso do fato de que as capturas são mantidas na divisão:

S_`(.{n})

A _opção remove as linhas vazias que de outra forma resultariam da cobertura de toda a sequência com correspondências. São 9 bytes, mas não adiciona um avanço de linha à direita. Por n = 38 bytes e n = 27 bytes. Observe que você pode salvar um byte no geral, se as linhas vazias não importarem (por exemplo, porque você processará apenas linhas não vazias e se livrará dos feeds de linha posteriormente): você poderá remover o _.

A terceira opção é usar uma correspondência. Com a !opção, podemos imprimir todas as correspondências. No entanto, para incluir o pedaço à direita, precisamos permitir um comprimento de correspondência variável:

M!`.{1,n}

Isso também tem 9 bytes e também não inclui um avanço de linha à direita. Isso também se torna 8 bytes para n = 3fazer ..?.?. No entanto, note que ele reduz para 6 bytes n = 2porque agora precisamos apenas ..?. Observe também que Mpode ser descartado se este for o último estágio do seu programa, economizando um byte em qualquer caso.

Descartando um pedaço incompleto à direita

Isso fica muito longo se você tentar fazer isso com uma substituição, porque você precisará substituir o bloco à direita por nada (se existir) e também por uma divisão. Para que possamos ignorá-los com segurança. Curiosamente, para a abordagem de partida, é o oposto: fica mais curto:

M!`.{n}

São 7 bytes, ou menos n = 2, para n = 3. Novamente, observe que você pode omitir Mse este é o último estágio do código.

Se você deseja um feed de linha à direita aqui, pode obtê-lo anexando |$à regex.

Bônus: pedaços sobrepostos

Lembre-se de que Mtem a &opção que retorna correspondências sobrepostas (o que normalmente não é possível com a expressão regular). Isso permite que você obtenha todos os pedaços sobrepostos (substrings) de uma sequência de um determinado comprimento:

M!&`.{n}
Martin Ender
fonte
De alguma forma, é possível dividir uma string exatamente ao meio com comprimento variável? Então 123456se torna 123\n456e 1234567890se torna 12345\n67890?
Kevin Cruijssen 25/10
11
@KevinCruijssen Acho que não adicionei nenhum recurso específico para isso. Você provavelmente precisará usar grupos de balanceamento: tio.run/##K0otycxLNPyvquGe8D/YIEHD3sZWQ09TW1PD3hbI1jW0A3JUNP//… Se você não se importar com um avanço de linha à direita, poderá omitir o ?=.
Martin Ender
Consegui concluir o desafio onde achava que precisava dele de maneira diferente, mas os grupos de equilíbrio são realmente muito úteis! Eu sabia que tinha que ser algo nesse sentido, mas minhas habilidades em regex / Retina não são boas o suficiente. Obrigado por responder! :)
Kevin Cruijssen 26/10