Dicas para jogar golfe em Brachylog

19

O Brachylog é uma linguagem que está começando a ganhar destaque recentemente no código-golfe (e acabou de receber uma grande atualização com uma sintaxe de terser). Assim como o Prolog, ele tem a vantagem de poder resolver um problema (normalmente via força bruta) apenas a partir de uma descrição suficientemente precisa da aparência de um problema, um recurso que significa que, no tipo certo de desafio, ele é frequentemente comparável ao principais idiomas de golfe (e é conhecido por derrotar Jelly de tempos em tempos).

Que dicas você tem para jogar golfe (por exemplo, escrever os programas mais curtos possíveis) no Brachylog? Principalmente, procura conselhos específicos do Brachylog, em vez de conselhos aplicáveis ​​a uma ampla variedade de idiomas. (Dicas sobre golfe em idiomas declarativos em geral podem ser apropriadas aqui, dependendo da quantidade de aplicativos que eles terão em outros idiomas além do Brachylog, embora consulte também Dicas para jogar golfe no Prolog .)

Comunidade
fonte

Respostas:

4

Explorar predicados aninhados para criar novas variáveis

O Brachylog possui muitos casos especiais de sintaxe para tornar suas duas variáveis ​​especiais ?(parâmetro de entrada / esquerda) e .(parâmetro de saída / direita), terser a ser usado. Isso significa que, se você não precisa acessar o seu predicado ?e ., mas precisa usar variáveis, geralmente pode salvar bytes através da criação de um predicado aninhado para usar o seu ? e ..

Como um exemplo simples, considere um programa parecido com este:

… A … ∧A … B … B …

Essa é uma forma bastante comum para um programa mais longo; Afinal, existem muitas lacunas que podem conter qualquer coisa. Suponha que não haja necessidade ?ou .dentro do centro de três lacunas. Então poderíamos reescrevê-lo assim:

… { … & … . … } …

Aqui, o predicado aninhado ?está cumprindo a função de Ae .está cumprindo a função de B. Podemos observar que esse é um byte menor que o código original; mudar AABBpara {?.}não tem alteração em termos de bytes, mas isso nos permitiu simplificar ∧?a abreviação &.

Um truque relacionado é mudar

∧. … ?∧

para

~{ … }

(que é um byte menor), embora seja quase sempre mais barato fazer com que o chamador troque os argumentos (a menos que o predicado seja chamado de pelo menos três locais diferentes no programa, o que é raro no Brachylog).


fonte
3

Dividir predicados de comprimento 2 dentro de metapredicados

Isso é melhor explicado pelo exemplo. Para remover o primeiro e o último elementos de uma lista, decapitamos e cortamos:

bk

Se quisermos executar esta operação em todos os elementos de uma lista, podemos usar uma operação de mapa:

{bk}ᵐ

No entanto, é um byte mais curto para dividir o predicado em dois e mapear cada parte separadamente:

bᵐkᵐ

O mesmo truque pode ser usado com alguns metapredicados:

{bk}ᵐ  →  bᵐkᵐ
{bk}ˢ  →  bˢkˢ
{bk}ᶠ  →  bᶠkˢ
~{bk}  →  ~k~b

Observe que, para alguns metapredicados, como , não há uma maneira geral de dividi-lo em duas partes, mas, no entanto, pode ser possível encontrar uma decomposição que funcione para a tarefa específica em que você está trabalhando.


fonte
3

Transmitindo a lista vazia para a sequência vazia

Às vezes, ao trabalhar com strings, o algoritmo que usamos pode unificar o que queremos com a lista vazia [], quando preferimos querer a string vazia "".

Podemos converter a lista vazia para a string vazia usando ,Ẹ, que anexa a string vazia à sua variável esquerda (essa é uma exploração da maneira como ,é implementada).

Isso também tem o benefício de não fazer nada se a variável esquerda for uma string. Então, se o seu programa é

{  
   some predicate that should always output a string, 
   but actually outputs [] instead of "" in specific cases
}

Então

{
  some predicate that should always output a string, 
  but actually outputs [] instead of "" in specific cases
},Ẹ

funcionará da maneira que você quiser.

Fatalizar
fonte
2

Elemento único é executado em uma lista

Considere este trecho:

ḅ∋≠

Se a entrada for uma lista ou sequência, a saída será unificada com uma sublist / substring de comprimento 1 que não faz parte de uma execução mais longa de elementos iguais. Ele divide a lista em blocos de elementos iguais e encontra um bloco cujos elementos são todos diferentes. Para obter os próprios elementos em vez de listas de singleton, siga haté o final. Eu usei essa construção aqui com oa encontrar um personagem que ocorre apenas uma vez na cadeia de entrada.

Zgarb
fonte