Algorithmic Optimization

This page is pretty good describing the process of finding better algorithms.

http://tibasicdev.wikidot.com/algorithmic-optimization

Optimization

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/pages:algorithmic-optimization


Optimization: Conditionals

Use If conditionals when you only want to execute the one command on the next line.

:If A=1
:Then
:C+2→C
:End

can be

:If A=1
:C+2→C

Because conditionals are generally slow, you should replace them with piecewise expressions if you are just changing a variable. You take the variable and add or subtract the expression, multiplying it by the value that you are adding to the variable. Using piecewise expressions can sometimes be slower than If conditionals to avoid storing zero into the variable if the expression is false.

:If A=3
:B+2→B

can be

:B+2(A=3→B

You don't need to put the value in front of the expression when it is one.

:B+1(A=2→B

can be

:B+(A=2→B

You can take piecewise expressions a step further by combining multiple If conditionals that deal with the same variable and put them into one piecewise expression.

:If A=3
:B+5→B
:If A=6
:B-3→B

can be

:B+5(A=3)-3(A=6→B

If you are adding and subtracting the same value from the variable in the piecewise expression, you can factor the common value from each expression. This works best when you are adding and subtracting a big number.

:B+11(A=1)-11(A=2→B

can be

:B+11((A=1)-(A=2→B

You can sometimes reorder a list of If conditionals so that the last possible outcome doesn't even need an If conditional. This mainly works when the program is going to do a certain action and there are no other alternative actions that can occur.

:If not(A
:Goto A
:If A>0
:Goto B
:If A<0
:Goto C

can be

:If A<0
:Goto C
:If A
:Goto B
:Goto A

If-Then-End conditionals should be used when you want to execute multiple commands.

:If A=1
:C+1→C
:If A=1
:D+1→D

can be

:If A=1
:Then
:C+1→C
:D+1→D
:End

If you have two or more If conditionals that have a common expression, you should take the common expression out and make it into an If-Then-End conditional and nest the If conditionals inside it.

:If A=1 and B=1
:C+2→C
:If A=1 and B=2
:D+1→D

can be

:If A=1
:Then
:C+2(B=1→C
:D+(B=2→D
:End

If you are displaying lots of text based on If conditionals, you should put the text together and then just use the sub command to get the appropriate part of the text. This will display the text if none of the conditions are true, so this may not always be desired.

:If A=3
:Disp "Hello
:If A=4
:Disp "World

can be

:Disp sub("HelloWorld",1+5(A=4),5

The If-Then-Else-End conditionals should be used if you want to execute multiple commands when an expression is true or false. Instead of putting two If-Then-End conditionals that have math opposite expressions, If-Then-Else-End conditionals are faster because you don't need to do two checks; only one of the conditionals can be true at one time.

:If B
:"Hello→Str1
:If not(B
:"Goodbye→Str1

can be

:If B
:Then
:"Hello→Str1
:Else
:"Goodbye→Str1
:End

When using an If-Then-Else conditional and only one command is executed if the expression is true or false, use an If conditional between the two commands instead. You might also have to change the order of the commands, depending upon the commands.

:If B
:Then
:"Hello→Str1
:Else
:"Goodbye→Str1
:End

can be

:"Goodbye→Str1
:If B
:"Hello→Str1

When a line is either drawn or erased depending on a condition, you can put that condition as the optional fifth argument for the Line command.

:If B:Then
:Line(1,2,3,4
:Else
:Line(1,2,3,4,0
:End

can be

:Line(1,2,3,4,B

When you have a If-Then or If-Then-Else conditional that has a Goto command as one of the nested commands, you can sometimes remove the conditional and replace it with multiple If conditionals. Doing this prevents a memory leak from happening.

:If A
:Then
:Disp "Hello
:Goto A
:Else
:Disp "Goodbye
:B+2→B
:End

can be

:If A
:Disp "Hello
:If A
:Goto A
:Disp "Goodbye
:B+2→B

If you have If:Then:End statements with an "End" at the end of the program, the End can be removed.

:If randInt(0,1
:Then
:Disp "Heads
:Else
:Disp "Tails

However, if the last line returns a value, it will show up on the home screen after the program ends.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-conditions


Optimization: Deleting Variables

Instead of setting number variables to zero (to delete them), use the DelVar command. DelVar works with all of the variables, and the calculator automatically sets the variable to zero the next time it's used. However, DelVar is also slightly - so for repeated resetting, it is often faster store 0 to the variable.

:0→A
can be
:DelVar A

The DelVar command doesn't need a line break or colon following the variable name. This allows you to make chains of variables.

:DelVar A
:DelVar B
can be
:DelVar ADelVar B

Besides making chains of variables, the DelVar command also allows you to take the command from the next line and put it immediately after the last DelVar command.

:DelVar A
:Disp "Hello
can be
:DelVar ADisp "Hello

The only exception is with the Lbl command. Don't put the Lbl command immediately after a DelVar with this optimization, or else the label will be ignored. For instance, the following code exits with ERR:LABEL:

:DelVar ALbl 0
:Goto 0

Even though the ClrList command exists for clearing lists, DelVar should be used instead.

:ClrList L1
can be
:DelVar L1

There is a drawback to using Delvar for Lists. If you use Delvar L1 instead of ClrList L1, L1 will disappear from the list editor. This can easily be remedied outside of the program, but inexperienced calculator users who execute your program and then need to view the list that was used by your program may not know how to do this.
Furthermore, ClrList L1 is 1 byte smaller than Delvar L1.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-deleting


Optimization: Exiting Programs

Although the Return and Stop commands can both be used for exiting programs, Return should be used instead of Stop. While Return stops only the current program and allows the parent program to continue running, Stop causes all of the programs to stop and then returns the user to the homescreen (unless called from an Assembly program).

:ClrHome
:Disp "Hello
:Stop
can be
:ClrHome
:Disp "Hello
:Return

You don't have to use Return or Stop if you can organize the program so that it just naturally quits. If the calculator reaches the end of a program, it will automatically stop executing.

:ClrHome
:Disp "Hello
:Return
can be
:ClrHome
:Disp "Hello

When you have a display command that displays text as the last line of the program, you can remove the command and just put the text. This text will be displayed instead of the "Done" message that is normally displayed after a program finishes executing.

:ClrHome
:Disp "Hello
can be
:ClrHome:"Hello

Even though you don't display any text as the last command, you may still want to get rid of the "Done" message. You can do this by putting a single double-quote as the last line of the program.

:ClrHome
can be
:ClrHome:"

If you modify the Ans variable on the last line of the program, Ans's new value will be displayed instead of the "Done" message.

:ClrHome
:For(A,1,5
:B+A→B
:End
can be
:ClrHome
:For(A,1,5
:B+A→B
:End
:B

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-exiting


Optimization: Logic and Relational Operators

Because the calculator treats every nonzero value as true and zero as false, you don't need to compare if a variable's value is nonzero. Instead, you can just put the variable by itself.

:If C≠0
can be
:If C

Instead of comparing a variable to zero, use the not logical operator. Because not returns the opposite value of the variable, true will become false and false will become true.

:While A=0
can be
:While not(A

When making expressions that combine the and and or operators where the and operator comes first, you don't need to include parentheses around the and operator. The and operator has a higher precedence than or, so it is evaluated first. This can become complicated with complex expressions, so you might want to leave some of the parentheses for clarity.

:If (A=1 and B=2) or (A=2 and B=1)
can be
:If A=1 and B=2 or A=2 and B=1

If you are comparing two unary expressions (expressions with no comparison operator) with the and operator, you don't need the and operator. For and to be true, both values must be nonzero. So, multiplying them will produce the same effect because if either one of the values is zero, the product of both values will also be zero.

:If A and B
can be
:If AB

A similar technique can be applied to expressions with comparison operators, except some restrictions are required.
With unary expressions, to test if A and B is true you multiply them. With equations, you can multiply the left sides of each together and you can do the same for the right sides. However, a value being 0 could return a different result than anticipated, so it is best to use this technique when the values are not 0.

:If A=B and C=D
can be
:If AC=BD

As and is similar to multiplying, the or operator is similar to addition. Adding two values together yields a non-zero result if one of the conditions is true. When you are comparing equations using the or operator, you can add the two together (This is not used for unary expressions because the plus symbol and or symbols are both one-byte tokens). For this the only restriction is that all values must have the same sign (or be 0), or you can circumvent this by using abs. This is necessary because if two variables have the same value except one is negative, this expression could return false.

:If A=B or C=D
can be
:If A+C=B+D

The most unused logical operator is xor (exclusive or). The xor operator is useful when comparing two expressions and checking if one but not both are true. In fact, xor is specifically designed for this purpose.

:If A=2 and B≠2 or A≠2 and B=2
can be
:If A=2 xor B=2

Many times a compound expression can be shortened by combining expressions that have the same meaning or replacing expressions that can be written another way. Think about what the expression means and then think about how to make a shorter equivalent expression. There are many ways of writing an expression, so there are usually ways to rewrite it.

:If A>B or A<B
can be
:If A≠B

If you have the not operator around an expression, you can usually change the logical operator to the math opposite. This allows you to remove the not operator.

:If not(B=C and A=D
can be
:If B≠C or A≠D

DeMorgan's Law can be used for expressions in which the not operator is around two separate unary expressions joined by the and or or operators. It allows you to remove the second not operator and then change the and to or and vice versa.

:If not(A) and not(B
can be
:If not(A or B

Min is useful when you are comparing one variable or value to several other variables to see if they are all equal to the variable or value. To use min you just create an expression with the min function and put the common variable or value inside it followed by an equal sign and a left curly brace. You then list out the variables that you are comparing the variable or value to, separating each one with a comma.

:If A=10 and B=10 and C=10
can be
:If min(10={A,B,C

Max is useful when you are comparing one variable or value to several other variables to see if at least one is equal to the variable or value. You do the same thing as the min function, just replacing min with max.

:If A=10 or B=10 or C=10
can be
:If max(10={A,B,C

You can put a comparison operator inside the min or max functions to compare when several values or variables are equal to one variable and several values or variables are equal to another variable. This works especially well with three or more variables.

:If A=X and B=U or A=Y and B=V
can be
:If max(A={X,Y} and B={U,V

Abs is useful when you are comparing a variable to two even or odd values using the or operator. You subtract the larger value from the smaller value, divide the result by two, and then put it on the left side of the equal sign. Next, you subtract the larger value by the result on the left side of the equal sign, and then take the variable being tested and subtract it by that value. You then put the abs function around the result and place the expression on the right side of the equal sign.

:If A=45 or A=105
can be
:If 30=abs(A-75

X=n1 or X=n2 should become abs(n1-mean({n1,n2}))=abs(X-mean({n1,n2})) (simplified) if n1 and n2 are positive integers and n1+n2 is even. If there are three terms, then see if you can simplify two of them according to this rule. If you can't, then a string of or's will be faster than the max(X={n1,n2,… approach. If there are four terms or more, then use max().

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-logic


Optimization: Loops and Branching

When using loops you want to make them as compact as possible. This starts with moving invariant code outside the loops. You only want loops to contain expressions whose values change within the loops. If something only happens once, it should be outside the loop.

:For(X,1,5
:5→Y
:Disp X
:End
can be
:5→Y
:For(X,1,5
:Disp X
:End

You also want to minimize the calculations inside loops. This not only includes cutting down on the number of storages, but how often variables are used and what they are used for. This can increase the size, however.

:For(X,1,10
:A+length(Str1→A
:End
can be
:length(Str1→B
:For(X,1,10
:A+B→A
:End

Another way to minimize calculations inside loops is to use constant increments. This makes the loop faster, but it also makes it larger.

:For(X,0,10
:Disp 10X
:End
can be
:For(X,0,100,10
:Disp X
:End

You should combine two or more loops that are in close proximity if they use the same number of iterations and don't affect each other. Combining loops may take some ingenuity.

:For(X,1,10
:B+X→B
:End
:For(Y,1,10
:A+A/Y→A
:End
can be
:For(X,1,10
:B+X→B
:A+A/X→A
:End

Loop unrolling reduces the number of times you check the condition in a loop, with two or more of the same statements being executed for each iteration. If the loop is small enough, you can even unroll the whole loop. This will usually increase the size but also make it faster.

:5→dim(L1
:For(X,1,5
:2A→L1(X
:End
can be
:5→dim(L1
:2A→L1(1
:2A→L1(2
:2A→L1(3
:2A→L1(4
:2A→L1(5

For( loops are best used when you know how many times the loop will be executed. Because the fourth argument is optional (one is the default), you should always try to leave it off.

:For(X,1,8,1
:End
can be
:For(X,1,8
:End

You can sometimes rewrite For( loops and the commands inside them so you can remove the fourth argument.

:For(X,8,0,-1
:Disp X
:End
can be
:For(X,0,8
:Disp 8-X
:End

If you have an If conditional around the outside of a For( loop, you should see if there is a way to combine it with the For( loop using Boolean logic.

:If A>10:Then
:For(X,1,50
:End:End
can be
:For(X,1,50(A>10
:End

One of the common uses of For( loops is to slow programs down. Instead of For( loops, you should use rand(# or If dim(rand(#. Both of these create lists of random numbers, with a larger number meaning a larger delay; the second one preserves the Ans variable as well.

:For(X,1,75
:End
can be
:rand(25

This method generally works well for small delays, but it is better to use For( loops for large delays. This is because the rand(# technique is limited by the RAM storage availability, and has a maximum delay of 999 (being a list variable).

:rand(200
can be
:For(X,1,600
:End

Repeat loops will loop until the expression is true, and While loops will loop while the expression is true. Repeat loops are tested at the end of the loop which means they will be executed at least once. This allows you to not always have to set the variables in the expressions, which is the case with While loops. If the expression in a While loop is false before it is tested, the loop will be skipped over. This is sometimes desired if the expression fits that format.

:DelVar A
:While not(A
:getKey→A
:End
can be
:Repeat A
:getKey→A
:End

If you need a loop that loops forever (i.e., an infinite loop), use Repeat 0 or While 1 instead of Goto/Lbl.

:Lbl A
:Disp "Hello
:Goto A
can be
:Repeat 0
:Disp "Hello
:End

Goto/Lbl loops should be used sparingly. When Goto is encountered, it notes the Lbl and proceeds to search for it from top to bottom in the code. This can really be slow if the Lbl is deep within the program. It also has the tendency to make your code harder to follow and maintain. And, if you use a Goto to exit a loop or a conditional that uses an End command, it can lead to memory leaks (causing your program to crash).

:Repeat 0
:getKey→B
:If B
:Goto A
:End
:Lbl A
can be
:Repeat B
:getKey→B
:End

When all a For( loop does is store expressions to a list, you can replace it with a seq( (sequence) command. The sequence command can also be used with other variables.

:5→dim(L1
:For(X,1,5
:2A→L1(X
:End
can be
:seq(2A,X,1,5→L1

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-loops


Optimization: Math Operations and Keys

Multiplication signs are unnecessary and should be removed because the calculator does implicit multiplication. You should remember that implicit multiplication doesn't bind tighter than regular multiplication.

:5*A→B
can be
:5A→B

You don't need to put parentheses around a single variable or number by itself when doing multiplication or division.

:3/(A)
can be
:3/A

Multiplication and division have the same importance based on the order of operations (the rules that determine what order things are evaluated in), so they will be evaluated from left to right if both appear in an expression. If multiplication appears before division, you can remove the parentheses around an expression.

:A+(BA)/5→C
can be
:A+BA/5→C

Although multiplication and division have the same importance in order of operations, multiplication is in fact faster than division when doing math operations. So, you should multiply instead of dividing, especially if doing the multiplication is smaller than doing the division.

:(X+1)/2
:(B+C)/D
can be
:.5(X+1
:Dֿ¹(B+C

When adding a negative number to a positive number, switch the two numbers around and change the addition to subtraction. This allows you to get rid of the negative sign.

:-A+B→C
can be
:B-A→C

You can often times rewrite math expressions using the built-in keys and characters. When you have a number that has two or more zeros, it may be smaller to write it using the the little E character (which is designed for scientific notation). This character will multiply the number on its left (1 if no number is given) times 10 to the number given on the right.

:50000
can be
:5E4

If you want to use a variable to set the exponent of a number, you would have to use 10^X because the calculator doesn't allow ᴇX. This can be replaced with the 10^( key. This also applies to the e^( key, the 2 key, and the 3 character.

:10^A+e²-5²+9³
can be
:10^(A)-52+93+e^(2

If you have a fraction that has one as the numerator, you can replace it with multiplying the denominator by the ֿ¹ key.

:1/16
can be
:16ֿ¹

When you have a fraction that has an expression in the numerator that has parentheses around it and a variable in the denominator, you can sometimes eliminate the fraction by multiplying the variable by the ֿ¹ key and multiplying it by the expression from the numerator.

:If (A+B)/C
can be
:If Cֿ¹(A+B

If you raise a variable or value to some fractional power with one in the numerator, you can just take the denominator of the fractional power and then multiply it by the xroot character and the variable or value.

:A^(1/B
can be
:Bx√A

Always do all the operations you can ahead of time. This eliminates some of the operations that the calculator has to do.

:33+A(8/2→B
can be
:33+4A→B

Write and calculate expressions in one step instead of several steps.

:2BC→D
:3A→E
:D+E→F
can be
:2BC+3A→F

One of the basic math rules is that multiplying one times any variable is equal to the variable. So, you don't need to put the one in front of the variable.

:1A+3→B
can be
:A+3→B

When adding two variables of the same type together, you should add up the number of times the variable appears and multiply that value by the variable.

:A+3A→B
can be
:4A→B

Rewriting division with multiplication is useful when multiplying is smaller. You take the denominator and then change it to the equivalent for multiplication.

:(X+1)/10
can be
:.1(X+1

The distributive identity should be used when you have three or more variables that share a common number or variable. You take that common number or variable out and distribute it to all of the variables.

:CA+CB+C²→D
can be
:C(A+B+C→D

The multiplicative inverse identity is used when you have an expression where the same variable or value is in the numerator and denominator. You can remove the variable or value because it is canceled out.

:2A/(2BA
can be
:1/B

When you have a fraction that has a fraction as its denominator, you can sometimes use the division inverse identity. If the numerator of the first fraction is one, you can flip the second fraction causing the first fraction to disappear.

:1/(4/A
can be
:A/4

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-math


Optimization: Putting Ans Into Practice

The Ans variable (last answer) is a temporary variable that can hold any variable. Ans is changed when there is an expression or variable storage or when pausing with the Pause command. It is mostly useful when you are just manipulating one variable. To use Ans just put an expression on a line by itself; it will automatically be stored to Ans. You can then change the expressions on the next line where the variable was called and put Ans there instead. Ans is faster than normal variables, but slower than Finance/Window variables and constants.

:getKey→A
:B+(A=26)-(A=24→B
can be
:getKey
:B+(Ans=26)-(Ans=24→B

If you have more than one line that calls the variable, you should just keep the variable. However, for the first line that calls the variable you should change the variable to Ans.

:getKey→A
:B+(A=26)-(A=24→B
:C+(A=34)-(A=25→C
can be
:getKey→A
:B+(Ans=26)-(Ans=24→B
:C+(A=34)-(A=25→C

When there is a common expression that is on multiple lines, it is sometimes smaller to put the expression on its own line and then change the expression on the other lines to Ans.

:30+5A→B
:Disp 25A
:Disp 30+5A
can be
:30+5A→B
:Disp 25A
:Disp Ans

When you use the same text many times in close proximity, you should put that text on its own line and replace it with Ans wherever it occurs.

:Disp "Hello
:Disp "Hello
:Disp "Hello
can be
:"Hello
:Disp Ans,Ans,Ans

For complex calculations, there are often multiple parts that are the same. You should take out the most common part and put it on its own line. If there are several common parts, you should take out the part that will result in the greatest size reduction. You then replace that part, wherever it occurs, with Ans.

:2A/(BC)+(BC)2→A
can be
:BC
:2A/Ans+Ans2→A

When dealing with text there are often situations where the same text is repeated multiple times. Rather than writing out the long string of text, it is sometimes possible to rewrite it using Ans. Put the common part of the text on its own line and on the next line concatenate (add together) with Ans however many times is needed to make the string.

:"                     →Str1 //20 spaces
can be
:"      //5 spaces
Ans+Ans+Ans+Ans→Str1

If you use the sub( command to get the appropriate part of some text based on certain conditions, you can sometimes get rid of the sub( command and just use Ans. You would put each piece of text on its own line, and then put the condition before it.

:Input sub("GiveTake",1+4(A=1),4)+" candy?",Str1
can be
:"Give
If A=1:"Take
Input Ans+" candy?", Str1

With Repeat loops, you can sometimes put Ans in the condition instead of the variable. Even if Ans were 0 at the beginning of the loop, the code will work, since a Repeat loop will always cycle once before the condition is checked.

:Repeat A
:getKey→A
:End
can be
:Repeat Ans
:getKey→A
:End

When the condition in a Repeat loop has a common part that is repeated multiple times, you should put the common part at the end of the loop and replace the common part in the condition with Ans.

:Repeat A=2 and B=1 or A=2 and B=3
:getKey
:A+(Ans=26)-(Ans=24→A
:End
can be
:Repeat Ans and B=1 or Ans and B=3
:getKey
:A+(Ans=26)-(Ans=24→A
:A=2
:End

Many times in If-Then-Else conditionals the same expression or string of text appears in both the true and false parts. You should put this expression or string of text before the If-Then-Else conditional and then replace it in the conditional with Ans.

:If B
:Then
:Disp "Hello
:2Bnot(A→C
:Else
:Disp "Hello
:3→D
:End
can be
:"Hello
:If B
:Then
:Disp Ans
:2Bnot(A→C
:Else
:Disp Ans
:3→D
:End

When you have two or more strings of text that share a common part, you should take that common part out. You then can replace it with Ans and concatenate Ans to the strings.

:Disp "Hello World
:Disp "Goodbye World
can be
:"World
:Disp "Hello "+Ans
:Disp "Goodbye "+Ans

When you have two If conditionals that have math opposite conditions and they display text, it is sometimes possible to remove one of the conditionals and use Ans. Take the text from the first condition and put it on its own line. Then put the second conditional and the text on the next line. You then put the display Ans on the last line.

:If A≤B
:Disp "Higher
:If A>B
:Disp "Lower
can be
:"High
:If A>B
:"Low
:If A≠B
:Disp Ans+"er

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-ans


Optimization: Storing Variables

Although it is common to initialize variables for planned use, you should avoid initializing variables that you don't need or that are initialized further down in the program. The reason is because storing to variables really slows a program down (especially inside loops) and there is no point in initializing a variable twice.

:2→A
:If B
:Then
:2→A
:Else
:-2→A
:End
can be
:If B
:Then
:2→A
:Else
:-2→A
:End

When a number is used many times in a program, you should store it to a variable and then just call the variable instead of writing it out every time. This also applies to text that should be put in a string.

:Disp "Hello
:Disp "Hello
:Disp "Hello
can be
:"Hello→Str1
Disp Str1,Str1,Str1

You can also put common variables or expressions in a string variable and then use the expr( command to reference them. This can be used in conjunction with other variable commands. This also gives you more variables to use.

:Disp 5int(B/7
:Disp 5int(B/7
can be
:"5int(B/7→Str1
:Disp expr(Str1
:Disp expr(Str1

You should reuse variables that have no specific function or that don't need to be saved.

:For(X,1,100
:End
:For(Y,1,50
:End
can be
:For(X,1,100
:End
:For(X,1,50
:End

When storing the same large number in two or more variables, you should store the large number in the first variable and then store the first variable into the rest of the variables.

:7112→A
:7112→B
:7112→C
can be
:7112→A
:A→B
:A→C

When calculating several repetitive trigonometric or other math functions in a program, it is sometimes faster to just store the values in a list and recall the values when needed.

:For(A,0,10
:Text(6A+1,1,10cos(A
:End
can be
:10cos(seq(A,A,0,10→L1
:For(A,0,10
:Text(6A+1,1,L1(A
:End

Matrices are faster than lists, so you should use them in speed sensitive situations, especially if you have 2 lists to store coordinates:

:Pxl-Off(L1(I),L2(I
can be
:Pxl-Off([A](1,I),[A](2,I

While this is much larger, it is also faster.

<< Displaying Text Table of Contents Math Operations >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-variables


Optimization: The Graph Screen

Although the screen is 95 pixels wide and 63 pixels tall, the bottom row and far right column of pixels are unusable. So, most people set the graphscreen dimensions to 94 and 62. This itself should be replaced with storing 1 into deltaX and deltaY.

:0→Xmin:94→Xmax
:0→Ymin:62→Ymax
can be
:0→Xmin:1→ΔX
:0→Ymin:1→ΔY
can be even better
:ZStandard
:84→Xmin
:72→Ymax
:ZInteger

The Text command can display both variables and text at the same time on the same line. This allows you to sometimes remove multiple Text commands and just use the first one.

:Text(5,5,A
:Text(5,9,"/
:Text(5,13,B
can be
:Text(5,5,A,"/",B

The Pxl-On command is faster than Pt-On, and it should be used whenever possible. Pt-On is also affected by the screen dimensions, while Pxl-On is not.

:Pt-On(5,5
can be
:Pxl-On(5,5

The Line command has an optional fifth argument that controls whether the line will be drawn (the argument should be one) or erased (the argument should be zero). The default is one, and it should be left off when possible.

:Line(5,5,10,5,1
can be
:Line(5,5,10,5

When turning multiple pixels in a straight line on or off, use a For loop instead of using the individual pixel commands.

:Pxl-On(5,5
:Pxl-On(5,6
:Pxl-On(5,7
:Pxl-On(5,8
can be
:For(X,5,8
:Pxl-On(5,X
:End

When you are changing the same pixels from on to off or vice versa in a loop, use the Pxl-Change command instead of the individual pixel commands.

:For(X,5,8
:Pxl-On(5,X
:End
:For(X,5,8
:Pxl-Off(5,X
:End
can be
:For(N,1,2
:For(X,5,8
:Pxl-Change(5,X
:End
:End

When you have multiple pixels in a straight line that you turn on or off, you can sometimes replace the Pxl-On commands with Line commands.

:Pxl-On(5,5
:Pxl-On(5,6
:Pxl-On(5,7
:Pxl-On(5,8
can be
:Line(5,5,5,8

The Pt-On and Pt-Off commands have an optional third argument that should never be used when one is desired because one is the default.

:Pt-On(5,5,1
can be
:Pt-On(5,5

The optional third argument for Pt-On and Pt-Off should be used when you want to turn on or off a 3x3 outline of a box (the argument should be two) or a 3x3 cross (the argument should be three). This can be used instead of the individual commands.

:Pt-On(A,B-1
:Pt-On(A,B
:Pt-On(A,B+1
:Pt-On(A-1,B
:Pt-On(A+1,B
can be
:Pt-On(A,B,3

When wanting to clear large spaces of the graph screen, you should use the Line or Text commands instead of the pixel commands, when possible. Both of these commands are faster than the pixel commands.

:Pxl-Off(5,5
:Pxl-Off(5,6
:Pxl-Off(5,7
:Pxl-Off(5,8
can be
:Line(5,5,5,8,0

The Circle( command has an alternate syntax. When a complex list such as {i} is added as the 4th argument, "fast circle" mode will be turned on, which uses the symmetries of a circle to save on trig calculations, and draws a circle in only 30% of the time it would normally take. Since the Circle( command is speed-challenged at best, you should always use this optimization when drawing circles.

:Circle(0,0,5
can be
:Circle(0,0,5,{i

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-graph


Optimization: User Input

The Input command has an optional display message argument that can be either text or a string. This display message can be used to tell the user what type of value to enter or to show what the variable is for. The Input command should be used instead of using a Disp command in conjunction with the Prompt command.

:Disp "Guess
:Prompt A
can be
:Input "Guess?",A

If you have two Input commands that have display messages that are positioned between a conditional, you can often remove one of the Input commands and then use the sub command to display the appropriate display message. This allows you to get rid of the conditional. You can also take out the common part of the display message and add it to the substring part of the display message.

:If A=1
:Then
:Input "Take candy?",Str1
:Else
:Input "Give candy?",Str1
:End
can be
:Input sub("GiveTake",1+4(A=1),4)+" candy?",Str1

The Prompt command can be used with more than one variable. If you have a list of prompt commands, you should put all of the variables on the first Prompt command, separating each variable with a comma. This allows you to get rid of the rest of the Prompt commands.

:Prompt A
:Prompt B
:Prompt C
can be
:Prompt A,B,C

The Prompt command should be used instead of the Input command when you have the display message show what the variable being stored to is. And if there are multiple Input commands, you can reduce them to just one Prompt command.

:Input "A=?",A
:Input "B=?",B
:Input "C=?",C
can be
:Prompt A,B,C

When doing calculations and user input, you should move the calculations before the user input. The delay before the user input is not important because people simply can't type fast enough to notice it.

:Input "NAME:",Str1
:3B/7→L1(1
:2A+5B→C
can be
:3B/7→L1(1
:2A+5B→C
:Input "NAME:",Str1

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-input


Optimizations: Displaying Text

If you have a string of numbers that you are displaying, you don't need to put quotes around the numbers. You should only use quotes if you want to keep any leading zeros.

:Disp "2345
can be
:Disp 2345

Use the Disp command instead of the Output command when displaying text on the first line of the homescreen. You can just add spaces to the text to move it to the correct location.

:Output(1,2,"Hello
can be
:Disp " Hello

When displaying the same text or variable on three or more lines, use a For loop. A For loop can also be used when the display is changing by a constant increment.

:Output(3,3,1
:Output(4,3,2
:Output(5,3,3
can be
:For(X,3,5
:Output(X,3,X-2
:End

When the text in an Output command is more than sixteen characters, it will wrap around to the next line. When you have two or more Output commands that display text on different lines, you can sometimes put the text together and add blank spaces between it to make it go to the next line in the desired location.

:Output(1,6,"Hello World
:Output(2,2,"Version 1.0
can be
:Output(1,6,"Hello World Version 1.0

Using the Disp command, you can display text and variables at the same time by putting a comma between each one. Because this can hinder readability, this should only be done when just displaying variables.

:Disp A
:Disp B
can be
:Disp A,B

When you have a list of Disp commands that you pause, you can take the text or variable from the last Disp command and place it after the Pause command as its optional argument, allowing you to remove the last Disp command.

:Disp "A=
:Disp A
:Pause
can be
:Disp "A=
:Pause A

You can often remove Disp commands by storing to a string only the text differing with values of a variable, and then displaying the text added to the similar statements with one Disp command. This can be useful when you have two conditionals that are opposites that display similar text.

:If A≥10
:Disp "You Win
:If A<10
:Disp "You Lose
can be
:"Win
:If A<10
:"Lose
:Disp "You"+Ans

When you have two or more Disp statements inside an If-Then conditional, you can combine the Disp statements to change the If-Then conditional to an If conditional.

:If A>B
:Then
:Disp "A is greater
:Disp "than B
:End
can be
:If A>B
:Disp "A is greater","than B

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-text


The newList() Command

newlist.png

Command Summary

Returns a list filled with zeroes.

Command Syntax

newList(length)

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The newList() command returns a list of a specific length that is filled entirely with zeroes.

:newList(3)
           {0  0  0}
:newList(5)
           {0  0  0  0  0}
:newList(0)
           {}

This can be easily expanded to returning a list filled with any value: to return a list filled with a value x, just add x to the result of newList(). This works for strings as well, since "Hello"+0 simplifies to "Hello".

Advanced Uses

newList() can be used for making a comparison between a single value and a list. Normally, something like {1,2,3,4}=2 simply returns "false", since 2 is not a list and {1,2,3,4} is. To do a comparison element-by-element, use newList() to turn the single value into a list: in this case, 2+newList(4). Comparing {1,2,3,4} to 2+newList(4) will return {false, true, false, false} (you might use when() to get a single value out of this list).

This works to extend other operations to a number and a list, as well, though comparisons are the most useful application of this technique, since most operations already work this way.

Optimization

In many cases, an expression with newList() can be used to optimize a seq() command. First, observe that the simple

:seq(k,k,1,n)

which will return the list {1,2,3,…,n}, can be replaced by
:cumSum(1+newList(n))

The result is about twice as fast.

This is useful because many seq() expressions can be expressed using something like seq(k,k,1,n). For example:

:seq(k^2,k,1,n)

can be

:seq(k,k,1,n)^2

which is

:cumSum(1+newList(n))^2

This rearrangement is not always possible, but when it is, it gives a significant improvement in speed, with no real difference in size.

Here is a more complicated example (which is a sequence of probabilities with the binomial distribution). Notice the use of the | (with) operator.

:seq(nCr(n,k) p^k (1-p)^(n-k),k,1,n)

can be

:nCr(n,a) p^a (1-p)^(n-a)|a=cumSum(1+newList(n))

Error Conditions

260 - Domain error happens when the length is not an integer ≥0.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:newlist

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License