Dicas para jogar golfe no TI-BASIC

26

Que dicas você tem para jogar golfe no TI-BASIC para as calculadoras da série TI-83/84 +? Estou procurando idéias que possam ser aplicadas a problemas de código-golfe e que também sejam pelo menos um pouco específicas para o TI-BASIC (por exemplo, "remover comentários" não é uma resposta).

Poste uma dica por resposta.

lirtosiast
fonte
6
Sempre inclua a versão a que você está se referindo!
flawr

Respostas:

22

Sua calculadora é bastante inteligente em deduzir o final das linhas para você e, portanto, você pode omitir alguns caracteres.

:Disp "HELLO WORLD    //is the same as...
:Disp "HELLO WORLD"

For(os loops têm uma sintaxe como esta - For(variable, start, end, increment), mas você pode omitir o incremento e ele usará 1:

:For(A,1,5     //is the same as...
:For(A,1,5,1)

e você pode omitir parênteses finais (no final das linhas) em todo o quadro:

:Output(1,1,A
:int(A
:round(A
etc.

Testado na minha calculadora TI-84 Silver Edition

Se você acha que isso é mais do que uma ideia (inferir finais), então eu as separarei

Stretch Maniac
fonte
5
... isso está errado 😭 #
Decay Beta
2
Além disso, tente reescrever o código para usar o menor número de parênteses de fechamento. Somente na última expressão de cada linha, você obtém os parênteses gratuitamente, então mova as instruções mais aninhadas para o final. Ou seja, not(iPart(B))+(A=5pode ser (A=5)+not(iPart(B.
lirtosiast
4
Isso se aplica a tudo que precisa ser fechado, não apenas entre parênteses (ou seja {lists}, "strings"e [[matrices]]). As expressões serão fechadas automaticamente quando você alcançar uma nova linha, dois pontos (um substituto para a nova linha; no entanto, não se aplica a cadeias de caracteres, pois elas podem conter dois pontos) ou a seta de atribuição de variável ( digitada com o botão STO ▶ ` ) Uma característica tão estranha da linguagem.
MI Wright
14

Usar Ans

Se você usar apenas uma expressão na próxima linha, não a armazene em uma variável! A variável Ans especial é um token de um byte que armazena o valor da última expressão avaliada. Portanto:

Xsin(A)->R
Disp R+tanh(R

pode ser

Xsin(A)
Disp Ans+tanh(Ans

economizando dois bytes.

lirtosiast
fonte
9

Use uma tabela de pesquisa codificada em números de ponto flutuante

Uma dica um pouco avançada:

Pequenas tabelas de pesquisa são úteis para o código de golfe: muitas vezes precisamos de uma função que mapeie, por exemplo, 0 a 1, 1 a 2, 2 a 1 e tudo mais a 0. No entanto, as matrizes TI-BASIC não são adequadas para esse propósito: por um lado, eles são baseados em um e, por outro, um valor não pode ser extraído até que a matriz seja armazenada Ansou uma variável de lista.

Na minha resposta aqui , armazeno uma pequena tabela de pesquisa em uma constante mágica na base 11. Simplesmente liste os valores que você deseja usar,

{0,-1,5,-1,-1,2,9,-1,8,6}

converter para um formulário útil

{1,0,6,0,0,3,10,0,9,7}

escreva na sua base desejada (base 11)

.106003A097

e converter para a base 10

-1+int(11fPart(11^Ans.0954191904

A abordagem de matriz mais curta tem 8 bytes a mais!

{1,0,6,0,0,3,10,0,9,7}-1:Ans(X+1

O TI-BASIC armazena apenas flutuadores com 14 dígitos decimais, para que você possa armazenar até 44 bits, mas apenas 14 dígitos decimais.

Essa técnica geralmente pode ser aprimorada ainda mais usando a pesquisa de força bruta para encontrar uma constante mágica em vez da codificação base-N. Ainda estou no processo de jogar a resposta acima, mas o jogador de TI TI-BASIC Weregoose usou esse método para gerar as diferenças entre os números de coprime com 30 (ou seja, uma lista repetida 6, 4, 2, 4, 2, 4, 6, 2) no wiki / fórum TI-BASIC Desenvolvedor com este trecho:

2+2iPart(3fPart(576e^(fPart(I/8

A constante mágica 576 foi encontrada usando o Mathematica, mas se você não possui uma cópia, use um script no seu idioma favorito.

lirtosiast
fonte
5

Coloque variáveis ​​de equação de expressões repetidas.

EX:

Remainder(randInt(1,9),1
Remainder(randInt(1,9),5
Remainder(randInt(1,9),10

Pode ser:

"randInt(1,9→u
Remainder(u,1
Remainder(u,5
Remainder(u,10

Nota: é difícil encontrar um bom uso para isso, mas isso não significa que você deva esquecer as variáveis ​​da equação: P

Fonte: http://tibasicdev.wikidot.com/selfmodify

-c4ooo de Omnimaga

user1812
fonte
Neste exemplo, você pode economizar mais adicionando nà primeira expressão, junto com a Remainder(função
Conor O'Brien
5

Ignorar inicialização desnecessária de variáveis

O consenso atual é permitir que todo o código seja executado em um novo intérprete. Podemos tirar vantagem disso - todas as variáveis ​​reais não inicializadas começam 0em TI-BASIC e Xmincomeçam como o valor possivelmente útil -10. Portanto, se você precisar fazer um total em execução em um programa que não recebe informações do Ans ou precisar de um -10byte a menos, essa dica pode ajudá-lo.

lirtosiast
fonte
Xmax é 10 e Ymin e Ymax se comportam da mesma forma, certo? Também existem outros parâmetros gráficos que têm outros valores, eu acho.
Fabian Röling
5

Geração de lista menor

Se você precisar de uma lista {1,2,...,N}, onde N é, digamos, 42, a maneira óbvia de criá-la é

seq(X,X,1,42. 

No entanto, um byte menor que isso é um hack puro, usando o binomcdf(comando (distribuição binomial cumulativa).

cumSum(binomcdf(41,0

Isso funciona apenas quando N é uma constante, porque a economia advém da substituição de N-1 pelo seu valor no código.

Existem dois casos que permitem código ainda mais curto.

Se você já possui uma lista L1da dimensão N:

cumSum(1 or L1

Se você não se importa com a ordem:

randIntNoRep(1,N     ;random permutation of numbers from 1 to N
lirtosiast
fonte
2
É garantido que seja um byte menor (e estupidamente mais lento) do que seq(X,X,1,Nmesmo quando Nnão é constante cumSum(1 or rand(N.
Misha Lavrov
4

Eliminar instruções End para blocos If no final de um programa

Salva dois bytes: um para o final e outro para a quebra de linha. Ele também permite que você use o Disp implícito na última linha, geralmente salvando um byte adicional.

[code]
If A>5
Then
Output(1,1,Ans²+Ans+A
Disp 3ln(A
End
//end of program

Pode ser:

[code]
If A>5
Then
Output(1,1,Ans²+Ans+A
3ln(A
//end of program
lirtosiast
fonte
Note-se que esta dica não funciona para blocos de loop. +1 para a boa dica
Tau
4

Conheça seus idiomas

Aqui estão alguns trechos que eu costumo usar no código golf:

  • Converta em valor da verdade (0/1):, not(not(Ansou Ans and 1. Qual deles usar depende dos parênteses necessários.
  • Adicione um a um valor de verdade: int(e^(Ans. Salva um ponto aberto 1+(Ans. Muito útil, porque o TI-BASIC possui matrizes de uma base.
  • Roteiro {0,1}para {1,-1}: cos(πAns. Salva um byte 1-2Ans.

  • Função de sinal de um número: tanh(ᴇ9Ans
  • Rodada para o infinito positivo: -int(-Ans
  • Número de dígitos em um número inteiro positivo: 1+int(log(Ans
  • Número complexo a ser listado {Re,Im}:imag(Ans{i,1

  • Converter string em lista: seq(inString("...",sub(Ans,X,1)),X,1,length(Ans(onde ...está a string de pesquisa)
  • Corte o primeiro elemento de uma lista: ΔList(cumSum(Ans
  • Corte o último elemento de uma lista: ΔList(cumSum(Ans)-Ans
  • Verifique se todos os elementos da lista L1são exclusivos:SortA(L1:min(ΔList(L1
  • Procure o número X em uma lista (retorna a primeira ocorrência): 1+sum(not(cumSum(Ans=X
  • Modo de uma lista quando existe um único modo, e a lista possui no máximo 10 elementos: (feia, mas curta): median(Ans,10^(seq(sum(Ans=Ans(X)),X,1,dim(Ans
lirtosiast
fonte
Eu realmente não entendo por que tanh(ᴇ9Ansesse funciona.
SuperJedi224
1
@ SuperJedi224 Bem, tanh (0 é zero, e os limites para o infinito, à esquerda e à direita, são -1 e 1. Ele fica exponencialmente próximo a esses valores, então + -17 ou mais está dentro do erro de arredondamento de + -1. Se os valores absolutos já são maiores que 17 anos, usamos apenas tanh (sozinho.
lirtosiast
3

Se você estiver usando

0→G ;or any other variable
;other lines of code

Em seguida, você pode usar (para salvar um byte):

DelVar G;other lines of code

Isso ocorre porque quando você exclui uma variável ( G), ela se torna seu valor padrão, neste caso 0,. Em seguida, você pode colocar outra linha após a DelVardeclaração, sem uma nova linha . Tenha cuidado ao colocar instruções de controle cruciais diretamente após uma DelVardeclaração.

(Testado na TI-84)

Conor O'Brien
fonte
Isso raramente é útil; variáveis ​​são inicializadas em 0 por padrão e você pode zerar Y executando um ZStandard.
lirtosiast
@ThomasKwa Tem sido útil para mim em muitos casos, esp. quando uma redefinição é necessária no meio da execução.
Conor O'Brien
2
No código de golfe? Quando? Se você me mostrar o programa, acho que poderei otimizar o DelVar.
lirtosiast
@ThomasKwa Não xode golfe por si só , mas sim programação com pouco espaço em disco (TI-83). Eu não tenho o programa agora. Eu vou voltar para você sobre isso.
Conor O'Brien
1
Após alguns minutos de reflexão, consigo pensar em alguns cenários em que o DelVar pode ser o mais curto, como após as declarações If de linha única.
lirtosiast
3

Quais variáveis ​​de lista usar?

Ao usar listas, evitar as listas padrão L₁através L₆em favor de listas de nomeados com nomes de uma letra: ᶫAatravés ᶫZ(onde é o pequeno L).

Qualquer um custa dois bytes para referência (embora L₁seja um único token, é um token de dois bytes), mas ao armazenar valores em uma lista, você pode soltar o símbolo, salvando um byte:

{1,2,3,4,5→ᶫA

pode ser

{1,2,3,4,5→A

A calculadora verifica o tipo de dados da expressão ao decidir onde o resultado será armazenado.

Da mesma forma, Input Aou Prompt Aarmazenará paraᶫA se o usuário inserir uma lista em vez de um número.

Vários outros comandos podem ser usados ​​sem o , embora a maioria deles raramente seja usada no golfe. Por exemplo, Matr►list(permite que o item seja removido em seus terceiro, quarto e superior argumento.

A regra geral é que, se o comando usar um nome de variável de lista e não uma expressão de lista , e se não houver uma sintaxe alternativa que possa colocar um tipo diferente de variável, o comando poderá funcionar com o deixado de fora.

Isso não funciona com a modificação de uma única entrada de uma lista: 1→ᶫA(3não pode ser alterado para1→A(3 .

Obviamente, a melhor variável de lista a ser usada é sempre Ans.

Misha Lavrov
fonte
Espere o que? " Input A" armazena para ᶫAse o usuário entrar em uma lista. "Isso significa que muitos dos meus programas são muito fáceis de quebrar. Então é bom que eu não tenha tantos Inputprogramas de qualquer maneira, eu geralmente tenho pequenas ferramentas sem verificação de erro ou jogos completos que usam GetKeyem vez de Input.
Fabian Röling
1
Se você está realmente interessado em fazer a prova de seus programas contra isso, sempre pode armazenar um valor aleatório Ae verificar se ele foi alterado posteriormente Input A.
Misha Lavrov
2

Conheça seus custos variáveis ​​de atribuição

Se você usa tempos de Bexpressão com bytes N, deve atribuí-lo a uma variável?

Anscusta 1+Nbytes a serem usados ​​(um para a quebra de linha e um para cada vez que é usado, use Ans quando (B-1)*(N-1)>2. Pode haver apenas um Anspor linha; portanto, tente todos os valores Ansque possam ser úteis.

Variáveis ​​reais (por exemplo X) custam 3+Nbytes, então use-as quando (B-1)*(N-1)>4.

Liste os 3+2Nbytes de custo das variáveis , portanto, use-os quando (B-2)*(N-1)>5.

As variáveis ​​de equação são as menos úteis: elas precisam de 4+2Nbytes. Use-os quando (B-2)*(N-1)>6.

Min. bytes in an expression to save
 N \ var. | Ans | Real | List | Eqn
------------------------------------
 2           4     5      8      9
 3           3     4      5      6
 4           2     3      4      5

Quando uma função é avaliada em uma lista, armazene-a em uma lista em vez de em uma variável de equação como u; isso economiza um byte.

Lembre-se de que a presença ou ausência de parênteses próximos muitas vezes pode fazer com que as expressões de armazenamento sejam vantajosas se elas forem reorganizadas.

Agora vou me contradizer e dizer que se deve escrever o código em uma linha o máximo possível. Por quê? Geralmente, quando há uma expressão longa e repetida em uma linha, ela pode ser simplificada.

lirtosiast
fonte
1

int (rand sobre randInt (

X + int (Yrand é igual ou menos bytes que randInt (X, Y como randInt é um token de 2 bytes. Alguns benefícios potenciais:

X + pode ser deixado de fora quando o limite inferior é 0, economizando dois bytes

X + é necessário antes do randInt (de qualquer maneira em determinadas situações, por exemplo, aleatório a partir de uma função de etapa como {2,5,8,11}

X + int (Yrand (N pode ser usado apenas como randInt (X, Y, N para gerar uma lista de N números aleatórios

Inicialização da tela de gráfico

Para usar funções como Linha (facilmente com coordenadas de pixel, é necessário inicializar os eixos da tela do gráfico em pixels quadrados e remover os eixos:

AxesOff
84→Xmin
72→Ymax
ZInteger

Braçadeira

min(U,max(L,N

Onde N é o número ou algoritmo e U e L são limites superior e inferior

É N na lista

max(N={X,Y,Z

Mais Lista de matemática

L1*L2→L3

instead of

for(A,1,dim(L1
L1(A)*L2(A→L3(A
End

This also works for things like this:
not(L1
L1 and L2

Saída

Disp e Text (ambos podem ser encadeados, então Disp A, B exibirá A e B em linhas separadas e Texto (28,40, A, B imprimirá A ao lado de B em uma linha

Tecnologia do loop de movimento ideal

Muitas dessas otimizações fazem parte da tecnologia usada para mover um personagem pela tela no menor número de bytes

http://tibasicdev.wikidot.com/movement

Listas de tamanho de token

http://tibasicdev.wikidot.com/tokens

Para obter ajuda na pontuação

TiKevin83
fonte