Consejos para jugar golf en TI-BASIC


26

¿Qué consejos generales tiene para jugar al golf en TI-BASIC para las calculadoras de la serie TI-83/84 +? Estoy buscando ideas que se puedan aplicar a problemas de código de golf y que también sean al menos algo específicas para TI-BASIC (por ejemplo, "eliminar comentarios" no es una respuesta).

Por favor, publique un consejo por respuesta.


66
¡Incluya siempre a qué versión se refiere!
flawr

Respuestas:


22

Su calculadora es bastante inteligente para inferir el final de las líneas para usted y, por lo tanto, puede omitir bastantes caracteres.

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

For(los bucles tienen una sintaxis como esta For(variable, start, end, increment), pero puede omitir el incremento y usará 1:

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

y puede omitir paréntesis finales (al final de las líneas) en todos los ámbitos:

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

Probado en mi calculadora TI-84 Silver Edition

Si crees que esta es más de una idea (inferir finales), las dividiré


55
.... esto está mal 😭
Beta Decay

2
Además, intente reescribir el código para utilizar el menor número de paréntesis de cierre. Solo en la última expresión de cada línea, obtienes los paréntesis de forma gratuita, así que mueve las declaraciones más anidadas al final. Es decir, not(iPart(B))+(A=5puede ser (A=5)+not(iPart(B.
lirtosiast

44
Esto se aplica a todo lo que necesita cierre, no solo paréntesis (es decir {lists}, "strings"y [[matrices]]). Las expresiones se cerrarán automáticamente cuando llegue a una nueva línea, dos puntos (un sustituto de la nueva línea; sin embargo, no se aplica a las cadenas, ya que pueden contener dos puntos) o la flecha de asignación variable ( , escrita con el botón STO ▶ ` ) Una característica tan extraña del lenguaje.
MI Wright

14

Utilizar Ans

Si solo usará una expresión en la línea siguiente, ¡no la almacene en una variable! La variable especial Ans es un token de un byte que almacena el valor de la última expresión evaluada. Así:

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

puede ser

Xsin(A)
Disp Ans+tanh(Ans

ahorrando dos bytes.


9

Use una tabla de búsqueda codificada en números de punto flotante

Un consejo un poco avanzado:

Las tablas de búsqueda pequeñas son útiles para el golf de código: muy a menudo necesitamos una función que asigne, por ejemplo, 0 a 1, 1 a 2, 2 a 1, y todo lo demás a 0. Sin embargo, los arreglos TI-BASIC no son adecuados para este propósito: por un lado, están basados ​​en uno, y por otro, un valor no se puede extraer hasta que la matriz se almacene en Ans una variable de lista o no.

En mi respuesta aquí , guardo una pequeña tabla de búsqueda en una constante mágica en la base 11. Simplemente enumere los valores que desea usar,

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

convertir a una forma útil

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

escriba en su base deseada (base 11)

.106003A097

y convertir a base 10

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

¡El enfoque de matriz más corto es 8 bytes más largo!

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

TI-BASIC solo almacena flotantes a 14 dígitos decimales, por lo que puede almacenar hasta 44 bits pero solo 14 dígitos decimales.

Esta técnica a menudo se puede mejorar aún más mediante el uso de la búsqueda de fuerza bruta para encontrar una constante mágica en lugar de una codificación de base-N. Todavía estoy en el proceso de jugar golf la respuesta anterior, pero el legendario golfista TI-BASIC Weregoose usó este método para generar las diferencias entre los números coprimos con 30 (es decir, una lista repetida de 6, 4, 2, 4, 2, 4, 6, 2) en el wiki / foro TI-BASIC Desarrollador con este fragmento:

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

La constante mágica 576 se encontró usando Mathematica, pero si no posee una copia, use un script en su idioma favorito.


5

Poner expresiones repetidas ecuaciones variables.

EX:

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

Puede ser:

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

Nota: es difícil encontrar un buen uso para esto, pero eso no significa que deba olvidar las variables de ecuación: P

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

-c4ooo de Omnimaga


En este ejemplo, podría ahorrar más agregando na la primera expresión, junto con la Remainder(función.
Conor O'Brien

5

Omitir inicialización variable innecesaria

El consenso actual es permitir que todo el código se ejecute en un intérprete nuevo. Podemos aprovechar esto: todas las variables reales no inicializadas comienzan 0en TI-BASIC y Xmincomienzan como el valor posiblemente útil -10. Entonces, si alguna vez necesita tomar un total acumulado en un programa que no recibe información de Ans, o realmente necesita un -10byte menos, este consejo puede ayudarlo.


Xmax es 10 e Ymin e Ymax se comportan de manera similar, ¿verdad? También hay otros parámetros de gráficos que tienen otros valores, creo.
Fabian Röling

5

Menor generación de listas

Si necesita una lista {1,2,...,N}, donde N es, digamos, 42, la forma obvia de crearla es

seq(X,X,1,42. 

Sin embargo, un byte más pequeño que eso es un hack limpio usando el binomcdf(comando (distribución binomial acumulativa).

cumSum(binomcdf(41,0

Esto solo funciona cuando N es una constante, porque el ahorro proviene de reemplazar N-1 con su valor en el código.

Hay dos casos que permiten un código aún más corto.

Si ya tiene una lista L1de dimensión N:

cumSum(1 or L1

Si no te importa el orden:

randIntNoRep(1,N     ;random permutation of numbers from 1 to N

2
Garantizado para ser un byte más pequeño (y estúpidamente más lento) que seq(X,X,1,Nincluso cuando Nno es constante cumSum(1 or rand(N.
Misha Lavrov

4

Eliminar declaraciones de finalización para bloques If al final de un programa

Guarda dos bytes: uno para el Fin y otro para el salto de línea. También le permite usar el Disp implícito en la última línea, a menudo guardando un byte adicional.

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

Puede ser:

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

Cabe señalar que este consejo no funciona para bloques de bucle. +1 por el buen consejo
Tau

4

Conoce tus modismos

Aquí hay algunos fragmentos que uso comúnmente en el código de golf:

  • Convertir a valor de verdad (0/1): not(not(Ans oAns and 1 . Cuál usar depende de los paréntesis necesarios.
  • Agregue uno a un valor de verdad: int(e^(Ans . Guarda un paréntesis abierto1+(Ans . Muy útil, porque TI-BASIC tiene matrices basadas en uno.
  • Mapear {0,1}a {1,-1}: cos(πAns. Ahorra un byte 1-2Ans.

  • Función de signo de un número: tanh(ᴇ9Ans
  • Redondo hacia el infinito positivo: -int(-Ans
  • Número de dígitos en un entero positivo: 1+int(log(Ans
  • Número complejo para enumerar {Re,Im}:imag(Ans{i,1

  • Convierta la cadena a la lista: seq(inString("...",sub(Ans,X,1)),X,1,length(Ans(donde... está la cadena de búsqueda)
  • Cortar el primer elemento de una lista: ΔList(cumSum(Ans
  • Cortar el último elemento de una lista: ΔList(cumSum(Ans)-Ans
  • Comprobar si todos los elementos de la lista L1 son únicos:SortA(L1:min(ΔList(L1
  • Busque el número X en una lista (devuelve la primera aparición): 1+sum(not(cumSum(Ans=X
  • Modo de una lista cuando existe un solo modo, y la lista tiene como máximo 10 elementos: (feo, pero corto): median(Ans,10^(seq(sum(Ans=Ans(X)),X,1,dim(Ans

Realmente no entiendo por qué tanh(ᴇ9Ansfunciona.
SuperJedi224

1
@ SuperJedi224 Bueno, tanh (0 es cero, y los límites al infinito a la izquierda y a la derecha son -1 y 1. Se acerca exponencialmente a esos valores, más allá de + -17 o más, está dentro del error de redondeo de + -1. Si los valores absolutos ya son superiores a 17ish, solo usamos tanh (solo.
lirtosiast el

3

Si te encuentras usando

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

Luego, puede usar (para guardar un byte):

DelVar G;other lines of code

Esto se debe a que cuando elimina una variable ( G), se convierte en su valor predeterminado, en este caso 0,. Luego, podría poner otra línea después de la DelVardeclaración, sin una nueva línea . Tenga cuidado al colocar declaraciones de control cruciales directamente después de unDelVar declaración.

(Probado en TI-84)


Esto rara vez es útil; las variables se inicializan a 0 de forma predeterminada, y puede cero Y haciendo un ZStandard.
lirtosiast

@ThomasKwa Me ha sido útil en muchos casos, especialmente. cuando se requiere un reinicio en la mitad de la ejecución.
Conor O'Brien el

2
En el código de golf? ¿Cuando? Si me muestra el programa, creo que podré optimizar el DelVar.
lirtosiast

@ThomasKwa No xode golf per se , más bien, programación en espacio en disco bajo (TI-83). No tengo el programa en este momento. Te responderé sobre eso.
Conor O'Brien

1
Después de unos minutos de reflexión, puedo pensar en un par de escenarios en los que DelVar puede ser más corto, como después de las declaraciones If de una sola línea.
lirtosiast

3

¿Qué lista de variables usar?

Cuando use listas, evite las listas predeterminadas L₁a L₆favor de listas con nombres de una letra: a ᶫAtravés ᶫZ(donde está la pequeña L).

Cualquiera de los dos cuesta dos bytes para hacer referencia (aunque L₁es un token único, es un token de dos bytes), pero al almacenar valores en una lista, puede soltar el símbolo y guardar un byte:

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

puede ser

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

La calculadora verifica el tipo de datos de la expresión al decidir dónde se almacena el resultado.

Del mismo modo, Input Ao Prompt Ase almacenará aᶫA si el usuario ingresa una lista en lugar de un número.

Se pueden usar varios otros comandos sin el , aunque la mayoría de ellos rara vez se usan en el golf. Por ejemplo, Matr►list(permite que se elimine en sus argumentos tercero, cuarto y superior.

La regla general es que, si el comando toma un nombre de variable de lista y no una expresión de lista , y si no hay una sintaxis alternativa que pueda colocar un tipo diferente de variable allí, entonces el comando podría funcionar con izquierda desactivada.

Esto no funciona con la modificación de una sola entrada de una lista: 1→ᶫA(3no se puede cambiar a1→A(3 .

Por supuesto, la mejor variable de lista para usar es siempre Ans.


¿Esperar lo? " Input A" almacena ᶫAsi el usuario ingresa a una lista ". Eso significa que muchos de mis programas son bastante fáciles de romper. Entonces es bueno que no tenga tantos Inputprogramas de todos modos, en su mayoría tengo herramientas pequeñas sin verificación de errores o juegos completos que usan en GetKeylugar de Input.
Fabian Röling

1
Si está realmente interesado en poner a prueba sus programas contra el usuario, siempre puede almacenar un valor aleatorio Ay verificar si ha cambiado después Input A.
Misha Lavrov

2

Conozca sus costos de asignación variable

Si usa un Btiempo de expresión de bytes N, ¿debería asignarlo a una variable?

Anscuesta 1+Nbytes para usar (uno para el salto de línea y uno para cada vez que se usa, así que use Ans cuando (B-1)*(N-1)>2. Solo puede haber uno Anspor línea, así que pruebe todos los valores paraAns eso podrían ser útiles.

Las variables reales (p X. Ej. ) Cuestan 3+Nbytes, así que úselas cuando(B-1)*(N-1)>4 .

Enumere los 3+2Nbytes de costo de las variables , así que úselos cuando(B-2)*(N-1)>5 .

Las variables de ecuación son las menos útiles: necesitan 4+2Nbytes. Úsalos cuando (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

Cuando una función se evalúa como una lista, almacénela en una lista en lugar de en una variable de ecuación como u; Esto ahorra un byte.

Tenga en cuenta que la presencia o ausencia de paréntesis cercanos a menudo puede hacer que el almacenamiento de expresiones sea ventajoso si se reorganizan.

Ahora me contradeciré y diré que uno debería escribir código en una línea tanto como sea posible. ¿Por qué? Por lo general, cuando hay una expresión repetida larga en una línea, se puede simplificar.


1

int (rand sobre randInt (

X + int (Yrand es igual o menos bytes que randInt (X, Y como randInt es un token de 2 bytes. Algunos beneficios potenciales:

X + se puede omitir cuando el límite inferior es 0, ahorrando dos bytes

X + es necesario antes de randInt (de todos modos en ciertas situaciones, por ejemplo, al azar de una función de paso como {2,5,8,11}

X + int (Yrand (N puede usarse como randInt (X, Y, N para generar una lista de N números aleatorios

Inicialización de pantalla gráfica

Para usar funciones como Línea (fácilmente con coordenadas de píxeles, es necesario inicializar los ejes de la pantalla de gráficos en píxeles cuadrados y eliminar los ejes:

AxesOff
84→Xmin
72→Ymax
ZInteger

Abrazadera

min(U,max(L,N

Donde N es el número o algoritmo y U y L son límites superior e inferior

Es N en la lista

max(N={X,Y,Z

Más listas de matemáticas

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

Salida

Disp y Text (ambos se pueden encadenar, por lo que Disp A, B mostrará A y B en líneas separadas y Text (28,40, A, B imprimirá A junto a B en una línea

Tecnología desde el bucle de movimiento óptimo

Muchas de estas optimizaciones son parte de la tecnología utilizada para mover un personaje por la pantalla en la menor cantidad de bytes

http://tibasicdev.wikidot.com/movement

Listas de tamaño de token

http://tibasicdev.wikidot.com/tokens

Para ayuda puntuando

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.