There is only so much memory capacity in a graphic calculator and typing in long programs can be tedious. New models with more memory and communication cables can go some way towards solving this. However there are some simple techniques to shorten the length of a program.
There are 3 sections to this page: A:(26 items): methods which work on all models B:( 5 items): only for pre-9850 models such as 6300/7000/7700/9700 C:( 4 items): only for 9850 models and compatibles ***** NOTE ****** Unless otherwise stated: On this page ^2 means SQUARE symbol and ^-1 means RECIPROCAL symbol and not a power symbol followed by 2 or -1. For the purposes of this page I think it is clearer to use ^2 than the ctf \^2 \^-1 ******************
A1) If you use the same expression several times but its value does
not change then you can assign it to a variable at the beginning and just
use the variable later on.
e.g. :(X+3Y-2)/3->C:sin (X+3Y-2)->S:X+3Y->A:
could be replaced by
:X+3Y-2->B:B/3->C:sin B->S:B+2->A:
A2) If you want to repeat an expression but you only want to repeat it
once more and the repitition comes in the very next statement you can use
'Ans'. The last value calculated is stored in the variable 'Ans'.
e.g :(256A^X)/3+sin(256A^X)->G:
could be shortened by using
:256A^X:Ans/3+sin Ans->G
Be careful though: not all types of statements affect 'Ans'.
An expression such as :20: or :sin 30: or :X+Y: will be stored in 'Ans'.
But commands like the following do not change 'Ans':
A=1=>Goto 2, Dsz B, Isz B, Lbl 1
If an expression is assingned to a variable e.g. : sin 30->A:
then this will not change 'Ans'. i.e. assignment statements
do not change 'Ans'
A3) Whenever you use something like
:C+1->C:
then it could be possible to change this to
:Isz C:
However this does not always have the same effect, because the Isz
function is designed for looping and will miss out the next statement
if C now equals zero. If you just want to replace C+1->C, but don't want
the skipping and don't know what value C might have, then to be perfectly
safe then use a dummy command afterwards e.g. :Isz C:0:
e.g. :C+1->C:C=0=>Goto 2:"A":Lbl 2:
has the same effect as
:Isz C:"A":
Similarly for replacing :C-1->C: with :Dsz C:0:
A4) If you want to initialise all the elements of a matrix to zero then
use :0Mat A->Mat A:
A5) If you want to assign the same value to more than one memory at the
same time, then use the '~' symbol
i.e. :2->A:2->B:2->C: is the same as :2->A~C:
it only works for a continuous forward range i.e. 2->G~C would not work
A6) If you want to test several conditions before executing a command
then you can string the => symbols together like the logical AND operator
e.g. X<1=>Y<1=>Goto 2 will only jump to Lbl 2 if both conditions are true.
A7) Since the last value of a program is displayed when program finishes
you shouldn't include the last display symbol.
e.g. 1_ 2_ 3_ 4_ will display the '4' twice. so just use 1_ 2_ 3_ 4
A8) You can combine an assignment and display in the same statement
e.g. A+1->B_
A9) Zeros preceding a decimal point are unnecessary. e.g. 0.5 is .5
A10) You can use implied multiplication e.g. (A*B*C)/(D*E*F) is ABC/DEF
However if you use the fraction symbol then ABC/DEF means ((A*B*C)/D)*E*F
A11) -Frac X is shorter than Frac(-X)
A12) Frac 12/7 gives zero as calculator assumes (Frac 12)/7
If you want Frac (12/7) then use fraction symbol
to save using brackets e.g. Frac 12%7
% represents fraction symbol.
Works even in situations like Frac (X+1)%7
The same applies to Int and Intg
A13) :BFrac A%B: is a shorter way of getting (A mod B) than
:A-BInt(A/B): however :BFrac ((B^-1)*A): will not always give an exact
integer due to rounding errors. Compare the below commands:
e.g. try 7Frac((7^-1)(12))->A_
A-5_ ;this doesn't work
7Frac 12%7->A_
A-5_ ;but this does
A14) :A!<>1: can be used to test if A is not equal to 1 or 0
Providing that A is a small positive integer. Or :Abs A>1: if
you know that A is any non-negative number
A15) Consider an expression containing both Frac X and Int X
e.g 30Frac X-Int X
=31Frac X-Frac X-Int X
=31Frac X-X ;using the identity X=Int X+Frac X
So the third expression is shorter than what you started with.
A16) If you want to execute different commands depending on the
result of some condition
e.g.:C=1=>1->D:C=2=>2->D
then this can be shortened by doing the first condition anyway
and then overwriting it if necessary:
1->D:C=2=>2->D
A17) Don't press [EXE] on the last line of a stored program
A18) Replace X=0=>Goto 1: Y=0=>Goto 1 by XY=0=>Goto 1
A19) "LABEL"?->L in one command produces this output
LABEL? And the cursor waits for the value of L.
which is shorter than "LABEL":?->L in two separate commands
A20) Consider whether to use 'top-heavy' fractions, or decimals.
For example
X+12%3%4
becomes
X+12.75
saving one byte, or
X+51%4
saving two.
A21) Consider which is shorter, / or reciprocal (X^-1).
For example,
1/3
becomes
3^-1
saving one byte, but
(2X)^-1
becomes
1/2X
which also saves one byte.
A22) Try any other algebraic manipulations which seem appropriate. For
example, (X+2)(X-7) should be replaced with X^2-5X-14 to save two bytes.
A23) Using a subroutine will save bytes if it replaces repeated code
which is 5 or more bytes long, or even shorter code which is repeated
more than once.
For example,
"ABC"
"ABC" (11 bytes)
becomes
Prog 1:Prog 1 (5 bytes)
and (Prog 1)
"ABC" (5 bytes)
(Note that this only holds on old calcs, which store programs in
"slots".
The newer ones which support filenames require extra space for the file
system, plus the bytes needed to actually call the programs, so use short
filenames on these calcs.)
A24) Rearranging code blocks can sometimes shorten programs.
For example,
"ABC"
Goto 0
Lbl 1
"GHI"
Goto 2
Lbl 0
"DEF"
Goto 1
Lbl 2
becomes simply
"ABC"
"DEF"
"GHI"
saving eighteen bytes!
This is of course an extreme example, but this kind of thing can happen
accidentally while writing and rewriting programs. You should check for
poorly structured code such as this when you finish writing a program.
A25) Some numbers can be written in a shorter form. For example,
120 = 5!, saving one byte
100 = \10^2, saving one byte
1000 = \10^3, saving two bytes
..001 = \10^-3, saving one byte
..25 = 4^-1, saving one byte
..125 = 8^-1, saving two bytes
There are of course an almost infinite number of others which could also
be shortened in this way, but which are not so recognisable,
e.g. 2187 = 3^7, saving one byte, but optimisation such as this is only
for the terminally over-enthuastic! There are many cases however, where
using an approximation may work, for example, by using square root to find
the nearest square. For example, instead of 2187, would your program work
with 47^2 = 2209 (saving one byte)?
A26) Try renaming variables so that ~ assignments can be made.
(Does 0->\r~\theta work?)
A27) Try redoing all expressions to allow ~ assignments to be made.
e.g. replace
0->R
1->X~Y
... ;Some stuff which makes value of R go up and down
... ;in a way independent of the value of R.
R=0=>Goto 1
with
1->R~Y
...
...
R=1=>Goto 1
B1) If you want some of your value memories to be zero at the start of the program then use the :Mcl: statement at the beginning. This puts zero into all the value memories. B2) When using value memory arrays then A[J] is okay if J is allowed to vary but if you have a fixed number like A[5] then shorten this to the corresponding value memory e.g. A[5]=F B3) More generally than B2): Never use offset values in array memories. For example, A[X+1] becomes B[X] saving two bytes. The only exception to this is if changing the letter would take you outside the alphabet, as in A[X-1] or Z[X+1]. B4) Trailing brackets ( [ are unnecessary. e.g 1(2+3(4+5 is fine instead of 1(2+3(4+5)) , as is A[15->B instead of A[15]->B. Of course, (1+2*3 is not the same as (1+2)*3 as that bracket wasn't at the end. Not the same on 9850s: see item C1) B5) Replace sqrt(X^2+Y^2 by Pol(X,Y if you don't care for the values of I and J. B6) Instead of going up the way using variable Z like so: 1->Z:Lbl 1 ?->A[Z] Isz Z:Z<=9=>Goto 1 ;23 steps First rewrite to go down the way with 9-Z+1: 9->Z:Lbl 1 ?->A[9-Z+1] ; 9-Z+1 makes index go from 1 to 9 Dsz Z:Goto 1 ; still 23 steps then modifying further using items B3) & B4): 9->Z:Lbl 1 ?->K[-Z Dsz Z:Goto 1 ;19 steps
C1) Trailing brackets (normal, square or curly) are mostly unnecessary.
The exception is immediately before = <> < > <= >= relational signs
where brackets must be put in because on 9x50 models equations become
logical test expressions with truth value 0 or 1.
C2) If you want to convert Getkey codes for keys 1-9 into the actual
number that was pressed then the long way to do it is:
Getkey->A
A=72=>1->G:A=62=>2->G:A=52=>3->G
A=73=>4->G:A=63=>5->G:A=53=>6->G
A=74=>7->G:A=64=>8->G:A=54=>9->G
That takes 84 steps. The short way to do it is:
.1Getkey
2-Ans+31Frac Ans->G
which only takes 15 steps. Or to also detect the number 0 then use:
.1Getkey
2-Ans+31Frac Ans+2(Ans=7.1->G
Also in reverse to convert numbers 1-9 into Getkey codes use:
?->N
(N-1)/3 ;don't use reciprocal or get rounding errors
72+Ans-31Frac Ans->G
If you want to take into account the number 0 as well then use:
?->N
(N-1)/3 ;don't use reciprocal or get rounding errors
72+Ans-31Frac Ans-11(N=0->G
C3) To convert Getkey codes for letters A~Z into numbers 1~26 use:
.1Getkey
6-10Frac Ans->R
8-Int Ans+5R+R(R<3->G
C4) If you are applying the same command to all entries in a List
then you can apply it just once to the whole list. Most scientfic
calculations and logic commands can be applied to a list
e.g. (List 1=0)->List 1 will give a list of zeros and ones accordingly.
sin List 1->List 1 will take sine of every entry.
List 1(Abs List 1>1 \exp 10)->List 1 will zero all elements
which are too small.