Correct usage of subroutine in commodore basic 4.0? - arrays

I have a subroutine which fills an array with "."s
In my main program I am trying to call this subroutine and then print the array; however, it doesn't seem to be working. I think I am incorrectly calling the subroutine?
This is my code:
subroutine:
1070 dim a$(x,x)
1080 for aa = 0 to x
1090 for bb = 0 to x
2000 a$(x,x)="."
2010 next
2020 next
main code:
10 input "please enter a number"; x
20 gosub 1070
30 for i = 1 to x
40 for j = 1 to x
50 print a$(i,j);
60 next
70 print
80 next
Nothing happens when run; but when I run it all in one program (not calling gosub) it works?
Any help?

In line #2000, I believe you want a$(aa,bb)=".", otherwise you're just hammering the same location with the initialization.
Also, and probably more important to your question, every GOSUB needs a RETURN to get back to the main line of execution. In your case, that's probably line 2030.

Related

How to replace all occurences of elements of a two dimensional array in do loops in fortran

I've got stdin like that (elements are always > 10)
75 33 44 51
51 87 33 77
77 51 91 45
17 29 30 40
I would like to substitute 1 for one of the elements in each row (randomly - according to a random 1 =< n =< 4) and 0 for the others in the row, but so as to change equal elements throughout, i.e., 51 in the 1st, 2nd, and 3rd rows, 33 in in the 1st and 2nd rows, and 77 in the 2nd and 3rd rows but so that I don't get two 1s in a row. Assuming that n=4 for the 1st and 2nd row, and n=3 for the 3rd and 4th one, I should end up with
0 0 0 1
1 0 0 0
0 1 0 0
0 0 1 0
which is different from just putting n's in, i.e., I don't want
0 0 0 1
0 0 0 1
0 0 1 0
0 0 1 0
What I actually want is to change all occurrences of equal elements according to the values of their elements throughout. E.g., replacement 51 -> 1 should change 51 in the 1st, 2nd, and 3rd row to 1 as soon as 51 in the 1st row is changed to 1, but not their names. Their names c(i,j) in the array should, however, respond with their new value when called. Then, random n's should be overruled by already existing 0's and 1's in each next row, but should stay when a row is not so affected via links to the previous rows as the 4th row.
I didn't put in any Fortran specifics because I want to avoid the discussion being led astray. Constructive suggestions would be greatly appreciated.
You need to read about the WHERE construct. If I understand your description, this toy program should work for you.
program foo
implicit none
integer c(3,4), i, n
real u
c = transpose(reshape([75,33,44,51,51,87,33,77,77,51,91,45],[4,3]))
call prn ! Print original matrix
do i = 1, 3
call random_number(u)
n = 1 + floor(4*u)
print '(A,I0)', 'n = ', n
where(c(i,:) /= c(i,n)) c(i,:) = 0
where(c == c(i,n)) c = 1
call prn ! Print altered matrix
end do
contains
subroutine prn
integer i
do i = 1, 3
write(*,'(4(I0,1X))') c(i,:)
end do
print *
end subroutine prn
end program foo

Importing the result of a MATLAB numeric array into a new MATLAB script

Consider that I have a code that returns a double array. When run, the result returned at the command window a result looks like this:
mpc.gen=
1 100 344 34 5
2 433 223 45 2
3 333 432 12 3
4 213 233 12 3
What I want to do is create a MATLAB script which would contain this array. In other words in this new MATLAB script I would have the following array, constructed like this:
mpc.gen= [ 1 100 344 34 5 ;
2 433 223 45 2 ;
3 333 432 12 3 ;
4 213 233 12 3 ;
] ;
Just calling the function would save the variable in the new script, however that is not what I need since I need to use this script for a simulation at a special power tool called MATPOWER. The array needs to be in the form shown at the new script.
The actual array is much bigger in size however I use this here for simplicity. Is there any way I can do this automatically, and not just pass the data from the command window to the new script one by one manually? Any help would be greatly appreciated. Thank you in advance for your time!
What you want to use is mat2str. It converts a matrix to a string representation that, when evaluated, results in the identical matrix.
For example:
>> result = [1 100 344 34 5;
2 433 223 45 2;
3 333 432 12 3;
4 213 233 12 3];
>> mat2str(result)
ans =
[1 100 344 34 5;2 433 223 45 2;3 333 432 12 3;4 213 233 12 3]
You could write this to a file like so:
f = fopen('test_script.m', 'w');
fprintf(f,'mpc.gen = %s\n', mat2str(result));
fclose(f);
The formatting is not identical to your example, but if the tool does proper MATLAB parsing, it shouldn't be a problem.
Is it intentional that mpc is a struct? (you are using dot in the name.) In the following, I use underscore instead, but it can certainly be adopted, if it is intentional.
This is what functions are for. So instead of making a script, you should create a new function. If I were to do what you want to do, I would have 2 functions and 1 script. Whereas the script looks like this
mpc_bus = function1;
function2(mpc_bus);
where function1 is the code that returns mpc.bus and function2 is the one where you want to work with mpc.gen, and the top would be something like this
function [] = function2(mpc_gen)
Alternatively: If you of some reason does not like functions, you can make the first code save the variable using save(*filename*.mat) and then you can load the file again in the script using dat=load(*filename*.mat); and mpc_gen = dat.mpc_bus;

How to identify breaks within an array of MATLAB?

I have an array in MATLAB containing elements such as
A=[12 13 14 15 30 31 32 33 58 59 60];
How can I identify breaks in values of data? For example, the above data exhibits breaks at elements 15 and 33. The elements are arranged in ascending order and have an increment of one. How can I identify the location of breaks of this pattern in an array? I have achieved this using a for and if statement (code below). Is there a better method to do so?
count=0;
for i=1:numel(A)-1
if(A(i+1)==A(i)+1)
continue;
else
count=count+1;
q(count)=i;
end
end
Good time to use diff and find those neighbouring differences that aren't equal to 1. However, this will return an array which is one less than the length of your input array because it finds pairwise differences up until the last element, so naturally there will be one less. As such, when you find the locations that aren't equal to 1, make sure you add 1 to the locations to account for this:
>> A=[12 13 14 15 30 31 32 33 58 59 60];
>> q = find(diff(A) ~= 1) + 1
q =
5 9
This tells us that locations 5 and 9 in your array is where the jump happens, and that's right for your example data.
However, if you want to find the locations before the jump happens, such as in your code, don't add 1 to the result:
>> q = find(diff(A) ~= 1)
q =
4 8

Redim'd array error in commodore 64 basic?

I am getting a redim'd array error in my commodore 64 basic project
I am not however re dimensioning my 2d array nor do I go through the line of code more than once!
Error is on line 1140
Can anyone help me out?
Thanks!
Code:
10 print "start"
20 rem: go to line 1100 in order to fill board with "."s because this is
30 rem: the board's initialization
40 gosub 1100
50 rem: looping from i to x allows for horizontal aspect of board to be printed
60 rem: x represents the width dimension of board, in this case, 8
70 for i = 1 to x
80 rem: looping from j to x allows for vertical aspect of board to be printed
90 rem: x represents the height dimension of board, in this case, 8
100 for j = 1 to x
110 rem: board initialized with "."s is printed
120 print b3$(i,j),
130 rem: end of first for loop, looping from i to x put on 130; , USED 4 TAB
140 next
150 print
160 rem: end of second for loop, looping from j to x
170 next
180 rem: checks what at the random number is equal to; places word vertically
190 rem: if rand is < 50 and places the word horizontally if rand is > 50
200 if r1 < 50 then gosub 1510
210 if r1 > 50 then print "no"
1000 rem: random num generator generates a random integer
1050 rem: between 0 and 100
1040 rem: values between 0 and 100, inclusive
1050 r1 = int(100*rnd(1))+1
1060 rem: Subroutine Fill
1070 rem: Purpose: read and data construct which fills b3$(x,x) with
1080 rem: either "."s or other random words depending on whether or not
1090 rem: the subroutine has been run before.
1100 x = 8
1110 rem: x represents the dimension for the board; in this case,8
1120 rem: took out
1130 rem: array b3 = board = specifications for width and height (8)
1140 dim b3$(x, x)
rem: i to x allows the horizontal aspect of board to be filled with "."s
1150 for i = 0 to x
1160 rem: j to x allows the vertical aspect of board to be filled with "."s
1170 for j = 0 to x
1180 rem: board filled with dots horizontally and vertically
1190 b3$(i, j) = "."
1200 rem: end of first nested for loop
1210 next
1220 rem: end of second nested for loop
1230 next
1240 return
You need an end statement before your subroutines. To make sure you don't interfere with anything else, something like:
1099 end
Otherwise, your program "completes," and then runs through all your subroutine code again just for fun.
It is because the line rem: i to x allows the horizontal aspect of board to be filled with "."s after the 1140 line doesn't have any number. To solve the problem, you can remove the line or put the number 1145 (for example) before.
Line 200 looks suspect, because line 1510 doesn't exist.
200 if r1 < 50 then gosub 1510

Outside-In 2D array algorithm

I was given a series of non-negative integers.
43 18 5 67 1 72 16 17 15 93 38 6 83 10 49 98 7 47 61 52 71 79 82 52 8
I need to store it in m * n array from the Outside-In. As follows:
m = 5
n = 5
Then, I need to calculate the sum of certain part of the 2D array. (I have done this part already).
My ideal approach to store the numbers:
1. Initialize starti,startj = 0.
2. Initialize endi = m , endj = n.
3. Store the remaining numbers in array[starti][j], where j starts from startj and ends at endj.
4. Store the remaining numbers in array[i][endj], where i starts from starti and ends at endi.
5. Store the remaining numbers in array[endi][j], where j starts from endj and ends at startj.
6. Store the remaining numbers in array[i][endj], where i starts from endi and ends at starti.
7. Decrement endi and endj by 1.
8. Increment starti and start j by 1.
9. Repeat the steps 3 - 8 until the last number is stored.
Question : Is there any better way to solve this problem ?
Additional: I have been trying come up (but failed) with a formula to find where the last element is stored before doing all these operation.
Here is one way.
First you can start out thinking recursively
Have a method which has a signature like `fill(m,n,starting_position, direction)
The recursive version will look something like
fill(m,n, starting_position, direction) {
// If m=0 or n=0 you have a base case.
// Start at starting position, and fill in the direction.
// Decrement m or n, depending on the direction
// Compute new starting position and direction
// Recursively call fill with the updated m,n, starting_pos, direction
}
Now notice that this method is tail-recursive, and so you can get rid of the recursion and replace it with a while loop, with the condition of the while loop derived from the base case.

Resources