Is there a way to store a list when programming a TI-83+? - ti-basic

Out of curiosity, I'm beginning to learn how to program my TI-83+ calculator. Part of my latest program involves storing numbers in a list. How can I add items to a list on a TI-83+ and how can I loop over them/access them?

Well, if you want to add something to the end, you need the length of the list. Let's say your using L1 as a list and variable A as the value you are trying to add to the list.
Here's what you would do:
:A->L1(1+dim(L1))
Here's how that works. The dim command has 1 parameter. That parameter is a list. When you use the dim command, it returns the length of the list in the parameters. When you want to refer to a specific place in a list, you use the syntax: list_name(location). So This line of code takes the value of variable A and stores it in the location of L1 which is 1 more than the length of L1, therefore appending variable A to the end of L1.
If you want to access a value in list, again use the syntax: list_name(location). On the other hand, if you don't know the location of the value you are looking for, or you are cycling through the list and doing something with each value, you can use a for statement.
Like this:
:FOR(A, 0, dim(L1))
::L1(A)->B
::"do whatever you want with the value of L1(A) here"
:END
Or like this:
:FOR(A, 0, dim(L1))
::if(L1(A) == "insert value being searched for here"):THEN
:::A->B
:::dim(L1)+1->A
::END
:END
The for loop works like this: at the beginning of the loop, 0 is stored to variable A. Then the loop continues until variable A is greater than dim(L1). After each time the loop resets, the value of variable A is increased by 1.
In the first example, the program loops through each value of L1 and does whatever you want to do with each value.
In the second example, the program loops through each value of L1. When the value of L1 matches the value you are looking for, the location of the value is stored in variable B to be used for whatever you want later. Then, the value of variable A is set to 1 more than the length of L1. Since the value of variable A is greater than dim(L1), the for loop is terminated.

An element can be added to the end of a list of unknown length like this:
0→L1(1+dim(L1
Under normal condition, attempting to set the value of an index greater than the length of the list results in ERR: INVALID DIM; however, if the index is only 1 greater than the length of the list, the value is appended to the end of the list.

You could use a list or a matrix, but I would suggest a list. You can find information on lists and their commands from this link.
Lists are also better for saving values in between program executions than just using variables, which may be changes by other programs or math.

You need first to define the size of a list like this :
3->dim(L1
(if you forget, you will have an ERR:Invalid Dim)
Press enter and you get a "10" as answer (don't worry it's normal).
You can find dim( in the [Catalog] and -> is "[STO->].
Then you could fill the list with some data like this :
2->L1(1)
3->L1(3)
Now When you print L1 you get :
{2 0 3 0}
First index is L1(1) not 0 (as usual).
You can delete the list by using DelVar :
DelVar L1
You can fill it with Fill, sort it, convert to matrix ....
Simply go to the List menu (2nd + Stat).
You can iterate on the list using a for loop (no foreach, use dim(L1) for the upper bound).
More informations in the guidebook or you could also ask your questions on this calculator questions stack
Hope this helps =)

You can do what Thibault said, fill it, sort it, convert it (Very well said, by the way). However, you can also do:
3->L1(dim(L1))
This will add 3 to the end of L1.

Related

Ruby: Add value to Variable and Clamp/limit the Variable in one line

Suppose I have several arrays in Ruby which I add/subtract values and afterwards I limit their range, like so:
array[x][y]=array[x][y]+1
array[x][y]=array[x][y].clamp (0..99)
Since I have many different arrays with rather long (index) names - and in order not to repeat those names twice in one line, I'd like to achieve something like
array[x][y]+=1.clamp (0..99)
Which is accepted by the interpreter, but doesn't work. It adds, but the value in the array does not get clamped.
Splitting it in at least two lines
array[x][y]+=1
array[x][y].clamp(0..99)
does also add, but doesn't clamp.
Is there any solution for this to fit the entire command in one line?
Many thanks!
The #clamp method doesn't take a range as a single argument for Ruby versions before 2.7, but rather two arguments representing the min and max, and #clamp does not mutate the object it's called on.
array[x][y] = (array[x][y] + 1).clamp(0, 99)
Note that because it's valid to call a method without parentheses, if parentheses are used around an argument list, there should not be any space between the method name and the parentheses. E.g. 1.clamp(0..4) rather than 1.clamp (0..4).

How to break FOR loop in simulink

In Simulink, I have a signal that is a 1-D array.
I want to get the index of the first value other than 0, but the result received is the index of the last non-zero value
I am new to Simulink, is there any way to break FOR loop?
Or what should I do in this case
Any hint will be great.
Thanks.
Rather than using a for loop iterator subsystem, use the while iterator subsystem.
From the properties you can enable the "Show iteration number port" option to give you the index to increment over the items in the array.
The while iterator also has a "cond" or condition input which you can set to exit the while loop when you get to a non-zero value.
Alternatively, use the for loop but work from the end of the array towards the front and output the last non-zero value which will be the first non-zero value if you worked in a forwards direction.
Use the length minus the index value to access the array to work backwards.

How do I prevent to operate over an empty matrix or a matrix with empty columns or row?

In the problem that I want to solve a well defined matrix has no empty rows or columns.
For example the matrix [[],[]] is not valid.
When I call the function first_column, how do I prevent to execute it if the matrix that I send as an argument is not valid as defined before?
first_column([],[],[]).
first_column([[H|T]|Tail],[H|Col],[T|Rows]):- first_column(Tail,Col,Rows).
Technically, what you're asking can be done by testing for an end-condition of a list with one element, rather than an empty list, based on the specs you gave.
first_column([[H|T]],[H],[T]).
first_column([[H|T]|Tail],[H|Col],[T|Rows]):- first_column(Tail,Col,Rows).
However, beyond your specs, I suspect that you'll also need to "transfer" your final Col,Rows to end variables, something like:
first_column([[H|T]],C,R,[H|C],[T|R]).
first_column([[H|T]|Tail],[H|C],[T|R],Col,Rows):-
first_column(Tail,C,R,Col,Rows).
The modified predicate would be called with initial conditions, like
first_column(List,[],[],Col,Rows).

how to enumerate array indices as odd and even numbers in parameters part of omnet.ini

I have this parameter as an array. The array is big, 100 cells. It is a parameter that can be initiated in omnet.ini file. The cells with even numbers should get value A and odd numbers should get value B. How can I do this in an automated manner?
Is there a way besides having all odd and even indices initiated one by one manually?
Wildcards can be useful but I do not know how to use them to separate odd and even indices.
Thanks.
You can access the actual module index with the index operator. Combining this with the conditional operator ?: you can easily define the value:
**.myModule[*].myParameter = index % 2 == 0 ? "A" : "B"
I'm not aware of any feature like this. There are a number of work-arounds you could use:
Provide two parameters and select the correct one in code
Use the volatile keyword (probably not appropriate here)
Put the entire thing in your .ini file
I'd personally implement the first approach, that way you can use the wildcard to pass both parameters ([*].myNode.parameterEven and [*].myNode.parameterUneven) and then set the correct values in your array in a for loop.
However, you could also use the volatile keyword in your NED file, see the manual for more details. However, this approach mostly works well if you have different parameters depending on which node you are assigning it to. For this case I think the first approach is better.
The last alternative is just putting the entire thing in your .ini file, which may be useful if you want to parameterize the array later.

Prolog: append a list to itself

suppose I have a list ListSum, and I want to append a new list to ListSum recursively, like
appList(ListSum):-
%%generate a list: ListTemp,
append(ListTemp,ListSum,ListSum),
appList(ListSum).
but append(ListTemp,ListSum,ListSum) didn't work in the way i wanted.
Can anyone help me out?
Cheers
You have to understand the concept of unification (or actually "matching" as implemented in Prolog). You can't bind two or more values to the same variable. Variables in Prolog once matched persisted its value until the final goal achieved, or fails somewhere. After that, if there're more possibilities then the variable is re-instantiated with another value and so on.
For example, if I query appList([]), then the append would be tested to match as:
append(ListTemp,[],[])
If ListTemp isn't empty list, this clause would fail because the semantic of append is "append the first argument with second, both are lists, resulting in the third". The recursive call to appList(ListSum) would be called as appList([]) since ListSum is matched with [] previously, resulting in infinite recursion (fortunately, if ListTemp isn't [], this won't be reached).
You must have two arguments in the clause, where one is the original list, and the other is the resulting list. The first two argument of append is then ListSum and ListTemp (depends on the append order you want), while the third is the resulting list. Done, no recursion required.
here's a non-recursive solution, not sure why you even need recursion:
appself(L,X) :- append(L,L,X).

Resources