Dicas para jogar golfe no INTERCAL


10

Que dicas gerais você tem para jogar golfe no INTERCAL ? Estou procurando idéias que possam ser aplicadas aos desafios do código de golfe e que também sejam pelo menos um pouco específicas do INTERCAL (por exemplo, "remover comentários" não é uma resposta útil).

Sei que idiomas exóticos podem ser realmente úteis para ganhar concursos de golfe, mas não vejo muito código INTERCAL por aqui. Você tem algum conselho que possa ajudar as pessoas a obter tamanhos de código competitivos com o INTERCAL? Esse idioma poderia ser competitivo?

INTERCAL é tão subutilizado que nem sequer tem uma etiqueta. Tão triste...


A maioria dos idiomas não tem ou precisa de suas próprias tags aqui, pois os desafios específicos ao idioma geralmente são desencorajados.
Alex A.

9
Um indício de que isso pode não ser a melhor linguagem de golfe, a partir de sua página da Wikipedia:Despite the language's intentionally obtuse and wordy syntax,
isaacg

Respostas:


2

A remoção de espaço em branco / "ruído" pode ir além do que você imagina

INTERCAL é uma linguagem que não insere espaço em branco. Porém, diferentemente da maioria das linguagens sem espaço em branco, a insensibilidade vai muito além do que você poderia esperar.

Por exemplo, DO NOTsão dois tokens, mas podem ser gravados DONOTsem que o analisador se queixe (em praticamente qualquer implementação amplamente usada). (É claro que você também pode escrever DON'T, mas não é um terser. Porém, pode ser mais fácil ler, PLEASEN'Tprovavelmente é mais difícil de ler do PLEASE NOTque.) Na verdade, há algum debate sobre se o espaço em branco faz alguma coisa; pelo menos um analisador INTERCAL permite mesmo dentro de constantes numéricas (não que isso seja muito útil ao jogar golfe). Uma coisa a ter em mente é que o espaço em branco separando DO READ OUTdá o que pode confundir alguns analisadores INTERCAL mais velhos, devido ao embutidoDOREADOUTDO(embora seus autores geralmente considerem isso um bug e, atualmente, geralmente funcione em um programa válido, não é aconselhável colocar um código como esse nas proximidades de um erro de sintaxe, pois pode ser muito mais difícil desambiguar).

Lembre-se também de que você pode exceder os caracteres para economizar espaço. No ASCII, você só pode fazer isso com '.!, mas esse é um truque muito útil. (Quando você não está usando matrizes, não há possibilidade de uma ambiguidade esparsa, mesmo quando todos os seus caracteres de agrupamento são os mesmos; portanto, para entradas de golfe, é recomendável manter apenas a 'menos que um subscrito de matriz exija genuinamente a "). representado em um byte usando a ?abreviação (C-INTERCAL) ou Latin-1 para ¥(CLC-INTERCAL), em vez dos três que o INTERCAL-72 precisa.


2

Concentre-se em fazer o máximo de trabalho possível em uma declaração

Os identificadores de instrução da INTERCAL são bastante detalhados; DOHá dois caracteres de ruído em cada instrução, o próprio nome da instrução também tende a ser bastante longo, e você deve inserir um de PLEASEvez em quando para manter o analisador feliz. (O melhor que você pode fazer é uma proporção de quatro DOpara um PLEASE, o que significa que você está usando 14 caracteres em identificadores para cada 5 comandos.) Por outro lado, a sintaxe da expressão é bastante concisa (ridícula, mas concisa). Isso significa que geralmente vale a pena ajustar parte do seu programa em uma única expressão, mesmo que o uso de várias instruções seja uma maneira mais "natural" de fazer as coisas.

Por exemplo, se você deseja atribuir #1a .1e #2a .2, em vez de fazê-lo da maneira óbvia do INTERCAL-72:

DO.1<-#1DO.2<-#2

vale a pena considerar sobrecarregar uma variável aleatória para permitir que você atribua as duas ao mesmo tempo:

DO:1<-#1$#2

( :1/!1$.2'introduzido em algum lugar no início do programa; observe que essa notação pós-INTERCAL-72 bastante, então você precisará usar um INTERCAL moderno para que isso funcione). Isso é apenas um pouco mais longo, mesmo que você leve em consideração a configuração e se torne mais curto se precisar, ou se pode combinar, atribuir simultaneamente a .1e .2mais de uma vez.

Não é apenas calcular comandos onde esse truque funciona. Se você precisar esconder uma variável duas vezes, não faça o seguinte:

DOSTASH.1DOSTASH.1

mas assim:

DOSTASH.1+.1

(A +notação funciona para a maioria dos comandos em que conceitualmente faria sentido.)


2

Use um único RESUME para todos os estilos INTERCAL-72, se houver

Se você precisar escrever o equivalente a uma instrução "if", o método normal usando o código INTERCAL-72 é NEXTduas vezes e, em seguida, faça um cálculo RESUME. (No código moderno, geralmente um computador COME FROMé melhor, mas essa dica pressupõe que seu código prefira NEXT). Você quase certamente precisa pagar os bytes pelo primeiro NEXT, pois ele salta de um ramo do "se" para o outro. Compartilhar a segunda NEXTtambém não é trivial, a menos que você tenha muitas instruções "se" que vão para o mesmo lugar ao ver a #1. No entanto, RESUMEpode estar em qualquer lugar do programa (porque o controle o deixará instantaneamente em qualquer lugar).

Existem duas maneiras de lidar com isso. Se você tiver muitas instruções "se", RESUMEprovavelmente isso garante um número de linha de um dígito, para que sua segunda NEXTinstrução possa ser a mais curta possível. Se possível, tente transformá-lo em um computador RESUMEque ocorreria naturalmente em seu código (é certo que isso é difícil, pois é raro aparecer no "fluxo normal" do código em vez de ser NEXTeditado para ele); então, o único custo é o número da linha. Você precisará usar uma única variável booleana para todos esses NEXTs; o consenso universal aqui é usar .5, principalmente porque é a variável que a biblioteca padrão usa para valores de retorno booleanos.

Como alternativa, é possível fazer uso de um recurso não documentado (tecnicamente não documentado, porque eu inseri uma dica na documentação INTERCAL quando notei) da biblioteca padrão. Como um local central para um RESUMEé tão útil, a biblioteca padrão usa um internamente. Os números de linha em INTERCAL são globais (com namespacing convenções, mas que pode ser quebrado se você sabe o que está fazendo), para que possa NEXTdireto para a parte interna da biblioteca padrão, se você quiser, e em particular, pode NEXTa sua localização central, RESUME . Isso é suficientemente popular no código INTERCAL existente que as substituições de bibliotecas padrão tendem a implementá-lo para evitar a quebra de programas existentes.

A linha em questão é (literal ou efetivamente, dependendo da implementação):

(1001) DO RESUME .5

O principal motivo para não usar isso é o número da linha longa; se você precisar criar um monte de estruturas do tipo INTERCAL-72, será melhor usar o seu próprio para fornecer um número menor.

Claro, você pode combinar as técnicas, escrevendo algo como

(9)DO(1001)NEXT

que é apenas marginalmente mais longo do que

(9)DORESUME.5

e tem o benefício que os booleanos se tornam #2e #3(que é mais difícil de ler, mas normalmente mais fácil de gerar). Na verdade, pode até valer a pena colocar o código extra para lidar #0e #1se você vai se esforçar muito (mas calculado COME FROMprovavelmente funcionará melhor nesse caso, a menos que seus requisitos sejam muito estranhos).


2

INTERCAL não especifica precedência, mas também não erro em precedência ambígua

Uma expressão como

#1$#2~#3

é ambíguo e pode significar

'#1$#2'~#3

ou

#1$'#2~#3'

A especificação INTERCAL deixa intencionalmente claro o que se entende e, em geral, não existe um padrão (embora C-INTERCAL e CLC-INTERCAL se esforcem para se igualar nos casos mais simples). Dito isto, o original não está incorreto ; é ambíguo e eu não recomendaria usá-lo no código de produção (mas não recomendaria o uso do próprio INTERCAL no código de produção), mas terá algum significado na maioria dos compiladores.

Em outras palavras, pode valer a pena remover os caracteres de agrupamento e esperar que seu programa ainda funcione. A maioria dos intérpretes analisa qualquer expressão ambígua de forma consistente; portanto, para cada par de caracteres de agrupamento, há uma chance de 1 em 2 que é desnecessário; isso pode resultar em algumas economias. (Infelizmente, analisadores INTERCAL tendem a ser suficientemente confuso que ninguém é inteiramente certo o que as regras realmente são , mas pode normalmente ser determinada pela experiência. Nos casos mais simples, os operadores tendem a todos têm a mesma precedência e ter uma associatividade consistente.)


2

No C-INTERCAL, considere abreviar o código usando CREATE

A CREATEinstrução permite que você crie uma nova sintaxe. Isso é particularmente útil no golfe porque permite que você dê nomes mais curtos às declarações. Você também pode usá-lo para "definir uma função" efetivamente através da criação de um novo operador (que possui a enorme vantagem de permitir que você chame a função no meio de uma expressão).

O custo de configuração aqui é bastante alto, mas se houver uma construção que você usa muito, inventar uma sintaxe mais curta, provavelmente será uma boa idéia.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.