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...
Despite the language's intentionally obtuse and wordy syntax,
Respostas:
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 NOT
são dois tokens, mas podem ser gravadosDONOT
sem que o analisador se queixe (em praticamente qualquer implementação amplamente usada). (É claro que você também pode escreverDON'T
, mas não é um terser. Porém, pode ser mais fácil ler,PLEASEN'T
provavelmente é mais difícil de ler doPLEASE NOT
que.) 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 separandoDO READ OUT
dá o que pode confundir alguns analisadores INTERCAL mais velhos, devido ao embutidoDOREADOUT
DO
(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.fonte
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;
DO
Há 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 dePLEASE
vez em quando para manter o analisador feliz. (O melhor que você pode fazer é uma proporção de quatroDO
para umPLEASE
, 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
#1
a.1
e#2
a.2
, em vez de fazê-lo da maneira óbvia do INTERCAL-72:vale a pena considerar sobrecarregar uma variável aleatória para permitir que você atribua as duas ao mesmo tempo:
(
: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.1
e.2
mais 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:
mas assim:
(A
+
notação funciona para a maioria dos comandos em que conceitualmente faria sentido.)fonte
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 é
NEXT
duas vezes e, em seguida, faça um cálculoRESUME
. (No código moderno, geralmente um computadorCOME FROM
é melhor, mas essa dica pressupõe que seu código prefiraNEXT
). Você quase certamente precisa pagar os bytes pelo primeiroNEXT
, pois ele salta de um ramo do "se" para o outro. Compartilhar a segundaNEXT
també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,RESUME
pode 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",
RESUME
provavelmente isso garante um número de linha de um dígito, para que sua segundaNEXT
instrução possa ser a mais curta possível. Se possível, tente transformá-lo em um computadorRESUME
que ocorreria naturalmente em seu código (é certo que isso é difícil, pois é raro aparecer no "fluxo normal" do código em vez de serNEXT
editado para ele); então, o único custo é o número da linha. Você precisará usar uma única variável booleana para todos essesNEXT
s; 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 possaNEXT
direto para a parte interna da biblioteca padrão, se você quiser, e em particular, podeNEXT
a 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):
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
que é apenas marginalmente mais longo do que
e tem o benefício que os booleanos se tornam
#2
e#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#0
e#1
se você vai se esforçar muito (mas calculadoCOME FROM
provavelmente funcionará melhor nesse caso, a menos que seus requisitos sejam muito estranhos).fonte
INTERCAL não especifica precedência, mas também não erro em precedência ambígua
Uma expressão como
é ambíguo e pode significar
ou
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.)
fonte
No C-INTERCAL, considere abreviar o código usando
CREATE
A
CREATE
instruçã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.
fonte