Suggerimenti per giocare a golf in TI-BASIC


26

Quali consigli generali hai per giocare a golf in TI-BASIC per i calcolatori della serie TI-83/84 +? Sto cercando idee che possano essere applicate a problemi di code-golf e che siano anche in qualche modo specifiche per TI-BASIC (ad es. "Rimuovere commenti" non è una risposta).

Si prega di inviare un suggerimento per risposta.


6
Ti preghiamo di includere sempre a quale versione ti riferisci!
flawr

Risposte:


22

La tua calcolatrice è abbastanza intelligente nel dedurre la fine delle righe per te, e quindi puoi omettere un bel po 'di caratteri.

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

For(i loop hanno una sintassi come questa - For(variable, start, end, increment), ma puoi omettere l'incremento e userà 1:

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

e puoi omettere le parentesi finali (alla fine delle righe) su tutta la linea:

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

Testato sulla mia calcolatrice TI-84 Silver Edition

Se pensi che questa sia più di un'idea (inferendo conclusioni), allora le dividerò


5
.... questo è solo sbagliato 😭
Decadimento beta

2
Inoltre, prova a riscrivere il codice in modo da utilizzare il minor numero di parentesi chiuse. Solo sull'ultima espressione di ogni riga, ottieni le parentesi gratis, quindi sposta le istruzioni più nidificate alla fine. Cioè, not(iPart(B))+(A=5può essere (A=5)+not(iPart(B.
lirtosiast,

4
Questo vale per tutto ciò che deve essere chiuso, non solo tra parentesi (vale a dire {lists}, "strings"e [[matrices]]). Le espressioni verranno automaticamente chiuse quando si raggiunge una nuova riga, due punti (un punto di riferimento per la nuova riga; non si applica alle stringhe, tuttavia, poiché possono contenere due punti) o alla freccia di assegnazione variabile ( , digitata con il pulsante STO ▶ ` ). Una caratteristica così strana del linguaggio.
MI Wright,

14

Uso Ans

Se utilizzerai solo un'espressione nella riga successiva, non memorizzarla in una variabile! La variabile Ans speciale è un token a un byte che memorizza il valore dell'ultima espressione valutata. Così:

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

può essere

Xsin(A)
Disp Ans+tanh(Ans

risparmiando due byte.


9

Utilizzare una tabella di ricerca codificata in numeri a virgola mobile

Un consiglio leggermente avanzato:

Le piccole tabelle di ricerca sono utili per il golf del codice: è molto spesso necessario una funzione che associ, ad esempio, da 0 a 1, da 1 a 2, da 2 a 1 e tutto il resto a 0. Tuttavia, gli array TI-BASIC non sono adatti a questo scopo: da un lato, sono basati su uno e, dall'altro, non è possibile estrarre un valore finché l'array non viene archiviato Anso una variabile di elenco.

Nella mia risposta qui , memorizzo una piccola tabella di ricerca in una costante magica nella base 11. Elenca semplicemente i valori che desideri utilizzare,

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

convertire in un modulo utile

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

scrivi nella base desiderata (base 11)

.106003A097

e converti in base 10

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

L'approccio di array più breve è di 8 byte in più!

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

TI-BASIC memorizza solo float con 14 cifre decimali, quindi è possibile memorizzare fino a 44 bit ma solo 14 cifre decimali.

Questa tecnica può spesso essere ulteriormente migliorata utilizzando la ricerca della forza bruta per trovare una costante magica anziché la codifica N-base. Sono ancora in procinto di giocare a golf con la risposta sopra, ma il golfista di lingua TI-BASIC Weregoose ha usato questo metodo per generare le differenze tra i numeri coprime con 30 (ovvero un elenco ripetuto di 6, 4, 2, 4, 2, 4, 6, 2) sul wiki / forum TI-BASIC Sviluppatore con questo frammento:

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

La costante magica 576 è stata trovata usando Mathematica, ma se non possiedi una copia usa una sceneggiatura nella tua lingua preferita.


5

Inserisci variabili di equazione per espressioni ripetute.

EX:

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

Può essere:

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

Nota: è difficile trovare un buon uso per questo, ma ciò non significa che dovresti dimenticare le variabili di equazione: P

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

-c4ooo di Omnimaga


In questo esempio, potresti risparmiare di più aggiungendo nalla prima espressione, insieme alla Remainder(funzione.
Conor O'Brien,

5

Salta l'inizializzazione variabile non necessaria

Il consenso attuale è quello di consentire l'esecuzione di tutto il codice su un nuovo interprete. Possiamo trarne vantaggio: tutte le variabili reali non inizializzate iniziano 0in TI-BASIC e Xmininiziano come il valore forse utile -10. Quindi, se mai hai bisogno di prendere un totale parziale in un programma che non riceve input da Ans, o hai davvero bisogno di un -10byte in meno, questo suggerimento può aiutarti.


Xmax è 10 e Ymin e Ymax si comportano in modo simile, giusto? Inoltre, ci sono altri parametri grafici che hanno altri valori, penso.
Fabian Röling,

5

Generazione di elenchi più piccoli

Se hai bisogno di un elenco {1,2,...,N}, dove N è, diciamo, 42, il modo più ovvio per crearlo è

seq(X,X,1,42. 

Tuttavia, un byte più piccolo di quello è un trucco accurato che utilizza il binomcdf(comando (distribuzione binomiale cumulativa).

cumSum(binomcdf(41,0

Funziona solo quando N è una costante, poiché il risparmio deriva dalla sostituzione di N-1 con il suo valore nel codice.

Esistono due casi che consentono un codice ancora più breve.

Se hai già un elenco L1di dimensioni N:

cumSum(1 or L1

Se non ti interessa l'ordine:

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

2
Garantito essere più piccolo di un byte (e stupidamente più lento) rispetto a seq(X,X,1,Nquando Nnon è costante cumSum(1 or rand(N.
Misha Lavrov,

4

Elimina le istruzioni End per i blocchi If alla fine di un programma

Salva due byte: uno per l'End e uno per l'interruzione di linea. Inoltre, consente di utilizzare Disp implicito sull'ultima riga, salvando spesso un byte aggiuntivo.

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

Può essere:

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

Va notato che questo suggerimento non funziona per i blocchi di loop. +1 per la buona mancia però
Tau

4

Conosci i tuoi modi di dire

Ecco alcuni frammenti che utilizzo comunemente nel code golf:

  • Converti in valore di verità (0/1):, not(not(Ansoppure Ans and 1. Quale usare dipende dalle parentesi necessarie.
  • Aggiungere uno a un valore di verità: int(e^(Ans. Salva un open-paren over 1+(Ans. Molto utile, perché TI-BASIC ha array a una base.
  • Mappa {0,1}a {1,-1}: cos(πAns. Salva un byte sopra 1-2Ans.

  • Firma la funzione di un numero: tanh(ᴇ9Ans
  • Rotondo verso l'infinito positivo: -int(-Ans
  • Numero di cifre in un numero intero positivo: 1+int(log(Ans
  • Numero complesso da elencare {Re,Im}:imag(Ans{i,1

  • Converti stringa in elenco: seq(inString("...",sub(Ans,X,1)),X,1,length(Ans(dov'è ...la stringa di ricerca)
  • Taglia il primo elemento di un elenco: ΔList(cumSum(Ans
  • Taglia l'ultimo elemento di un elenco: ΔList(cumSum(Ans)-Ans
  • Controlla se tutti gli elementi dell'elenco L1sono unici:SortA(L1:min(ΔList(L1
  • Cerca il numero X in un elenco (restituisce la prima occorrenza): 1+sum(not(cumSum(Ans=X
  • Modalità di un elenco quando esiste una modalità singola e l'elenco ha al massimo 10 elementi: (brutto, ma breve): median(Ans,10^(seq(sum(Ans=Ans(X)),X,1,dim(Ans

Davvero non capisco perché tanh(ᴇ9Ansfunziona.
SuperJedi224,

1
@ SuperJedi224 Beh, tanh (0 è zero e i limiti all'infinito a sinistra e a destra sono -1 e 1. Si espone in modo esponenziale vicino a quei valori, quindi oltre + -17 o giù di lì è all'interno dell'errore di arrotondamento di + -1. Se i valori assoluti sono già maggiori di 17ish, usiamo solo tanh (da solo.
lirtosiast

3

Se ti ritrovi a utilizzare

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

Quindi, è possibile utilizzare (per salvare un byte):

DelVar G;other lines of code

Questo perché quando si elimina una variabile ( G), diventa il suo valore predefinito, in questo caso 0. Quindi, è possibile inserire un'altra riga dopo la DelVardichiarazione, senza una nuova riga . Fai attenzione quando metti dichiarazioni di controllo cruciali direttamente dopo DelVarun'istruzione.

(Testato su TI-84)


Questo è raramente utile; le variabili sono inizializzate su 0 per impostazione predefinita e puoi azzerare Y eseguendo uno ZStandard.
lirtosiast

@ThomasKwa Mi è stato utile in molti casi, esp. quando è richiesto un ripristino durante l'esecuzione.
Conor O'Brien,

2
Nel codice golf? Quando? Se mi mostri il programma, penso che sarò in grado di ottimizzare DelVar.
lirtosiast

@ThomasKwa Non xode golf di per sé , ma piuttosto programmazione su spazio su disco ridotto (TI-83). Non ho il programma in questo momento. Ti richiamo al riguardo.
Conor O'Brien,

1
Dopo alcuni minuti di riflessione, riesco a pensare a un paio di scenari in cui DelVar può essere il più breve, come dopo le istruzioni If a riga singola.
lirtosiast

3

Quali variabili elenco utilizzare?

Quando si utilizzano gli elenchi, evitare gli elenchi predefiniti L₁attraverso L₆a favore delle liste denominate con nomi di una sola lettera: ᶫAattraverso ᶫZ(dove è il piccolo L).

O uno costa due byte a cui fare riferimento (sebbene L₁sia un singolo token, è un token a due byte) ma quando si memorizzano i valori in un elenco, è possibile rilasciare il simbolo, salvando un byte:

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

può essere

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

La calcolatrice controlla il tipo di dati dell'espressione quando decide dove è archiviato il risultato.

Allo stesso modo, Input Ao Prompt Averrà archiviato inᶫA se l'utente inserisce un elenco anziché un numero.

Diversi altri comandi possono essere usati senza il , anche se la maggior parte di essi sono usati raramente nel golf. Ad esempio, Matr►list(consente di essere rimosso nei suoi argomenti terzo, quarto e superiore.

La regola generale è che, se il comando accetta un nome di variabile di elenco e non un'espressione di elenco e se non esiste una sintassi alternativa che potrebbe inserire un diverso tipo di variabile, il comando potrebbe funzionare con tasto sinistro.

Questo non funziona con la modifica di una singola voce di un elenco: 1→ᶫA(3non può essere modificato in1→A(3 .

Naturalmente, la migliore variabile di lista da usare è sempre Ans.


Aspetta cosa? " Input A" memorizza ᶫAse l'utente inserisce un elenco. "Ciò significa che molti dei miei programmi sono abbastanza facili da decifrare. Quindi è bene che non abbia Inputcomunque molti programmi, per lo più ho piccoli strumenti senza controllo errori o giochi completi che usano GetKeyinvece di Input.
Fabian Röling

1
Se sei davvero appassionato di a prova di utente dei tuoi programmi rispetto a questo, puoi sempre memorizzare un valore casuale Ae verificare se è cambiato dopo Input A.
Misha Lavrov,

2

Conosci i tuoi costi di assegnazione variabili

Se usi i tempi di Bun'espressione di byte N, dovresti assegnarli a una variabile?

Anscosta 1+Nbyte da utilizzare (uno per l'interruzione di riga e uno per ogni volta che viene utilizzato, quindi utilizzare Ans quando (B-1)*(N-1)>2. È possibile utilizzarne solo uno Ansper riga, quindi provare tutti i valori per Ansquello potrebbe essere utile.

Le variabili reali (ad es. X) Costano 3+Nbyte, quindi usali quando (B-1)*(N-1)>4.

Elenca i 3+2Nbyte di costo delle variabili , quindi utilizzali quando (B-2)*(N-1)>5.

Le variabili di equazione sono le meno utili: hanno bisogno di 4+2Nbyte. Usali 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 una funzione restituisce un elenco, memorizzalo in un elenco anziché in una variabile di equazione come u; questo salva un byte.

Tieni presente che la presenza o l'assenza di parentesi strette può spesso rendere vantaggiose le espressioni di memorizzazione se vengono riorganizzate.

Ora mi contraddico e dico che si dovrebbe scrivere il codice su una riga il più possibile. Perché? Di solito quando c'è una lunga espressione ripetuta su una linea, può essere semplificata.


1

int (rand over randInt (

X + int (Yrand è uguale o inferiore a byte di randInt (X, Y come randInt è un token da 2 byte. Alcuni potenziali vantaggi:

X + può essere lasciato fuori quando il limite inferiore è 0, salvando due byte

X + è necessario prima di randInt (comunque in determinate situazioni, ad esempio casuale da una funzione di passaggio come {2,5,8,11}

X + int (Yrand (N può essere usato esattamente come randInt (X, Y, N per generare un elenco di N numeri casuali

Inizializzazione dello schermo grafico

Per utilizzare funzioni come Linea (facilmente con coordinate pixel è necessario inizializzare gli assi dello schermo del grafico in pixel quadrati e rimuovere gli assi:

AxesOff
84→Xmin
72→Ymax
ZInteger

morsetto

min(U,max(L,N

Dove N è il numero o l'algoritmo e U e L sono i limiti superiore e inferiore

È N nell'elenco

max(N={X,Y,Z

Elenco più matematica

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

Produzione

Disp e Testo (possono essere entrambi concatenati, quindi Disp A, B visualizzerà A quindi B su righe separate e Testo (28,40, A, B stamperanno A accanto a B su una riga

Tecnologia dall'anello di movimento ottimale

Molte di queste ottimizzazioni fanno parte della tecnologia utilizzata per spostare un personaggio sullo schermo nel minor numero di byte

http://tibasicdev.wikidot.com/movement

Elenchi dimensioni token

http://tibasicdev.wikidot.com/tokens

Per un punteggio di aiuto

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.