How does 'While' loop and 'for' loop build in programming languages? - loops

suddenly a question goes over my mind which is how the WHILE loop and FOR loop has been built into programming languages
and can we make something like it and write it the same way we write the loops?
I tried to make this code in dart language but it doesn't work and doesn't seem to be like the normal FOR loop
dynamic forLoop(condition, body){
if(condition){
body();
forLoop(condition, body);
}
}
void main(){
forLoop( (Something.i<5), (){print(Something.i); Something.i++;} );
}

I saw a similar question for Python for loop.
I tried the same approach using dis module for while loop.
def f():
n = 0
while n < 2:
print("body")
n += 1
return None
dis.dis(f)
2 0 LOAD_CONST 1 (0)
2 STORE_FAST 0 (n)
3 4 LOAD_FAST 0 (n)
6 LOAD_CONST 2 (2)
8 COMPARE_OP 0 (<)
10 POP_JUMP_IF_FALSE 18 (to 36)
4 >> 12 LOAD_GLOBAL 0 (print)
14 LOAD_CONST 3 ('body')
16 CALL_FUNCTION 1
18 POP_TOP
5 20 LOAD_FAST 0 (n)
22 LOAD_CONST 4 (1)
24 INPLACE_ADD
26 STORE_FAST 0 (n)
3 28 LOAD_FAST 0 (n)
30 LOAD_CONST 2 (2)
32 COMPARE_OP 0 (<)
34 POP_JUMP_IF_TRUE 6 (to 12)
6 >> 36 LOAD_CONST 0 (None)
38 RETURN_VALUE
You can find details about Python Bytecode Instructions in the dis module.

Related

AWK array seems to empty itself?

I am trying to learn awk by solving code puzzles. I am trying to read several "grids" of integers (representing bingo boards as per https://adventofcode.com/2021/day/4) into a three-dimensional awk array. An example "grid" can look like this:
22 13 17 11 0
8 2 23 4 24
21 9 14 16 7
6 10 3 18 5
1 12 20 15 19
And there are several of these in a longer input file. After reading each line into an array rows I am attempting to organize the numbers into this multi dimensional array called boards. Here is my example code:
{
b = 0
for (i in rows) {
split(rows[i], nums, " ")
for (j in nums) {
r = i % 5
n = j - 1
boards[b][r][n] = nums[j]
print b, r, n, nums[j], boards[b][r][n]
}
if (i%5==0)
++b
}
print boards[0][1][1]
}
Notice the debug printout print b, r, n, nums[j], boards[b][r][n] which indeed outputs the correct values for boards[b][r][n] on that row:
0 0 0 22 22
0 0 1 13 13
0 0 2 17 17
Etc. This seems to verify that the multi dimensional array gets written properly. Yet on the final line of the example code, the output is instead empty. I have tried using the form boards[b, r, n] for the array as well with the exact same result. Obviously there's something I'm not quite understanding here. Any help is appreciated. Full code for reproducibility:
# === ex.txt ===
7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
22 13 17 11 0
8 2 23 4 24
21 9 14 16 7
6 10 3 18 5
1 12 20 15 19
3 15 0 2 22
9 18 13 17 5
19 8 7 25 23
20 11 10 24 4
14 21 16 12 6
14 21 17 24 4
10 16 15 9 19
18 8 23 26 20
22 11 13 6 5
2 0 12 3 7
# === solve.awk ===
BEGIN {
r = 0
}
{
if (NR == 1)
split($0, draws, "")
else if (NR != 2 && (NR-3)%6 != 5)
rows[r++] = $0
}
END {
b = 0
for (i in rows) {
split(rows[i], nums, " ")
for (j in nums) {
r = i % 5
n = j - 1
boards[b][r][n] = nums[j]
print b, r, n, nums[j], boards[b][r][n]
}
if (i%5==0)
++b
}
print boards[0][1][1]
}
I run this with awk -f solve.awk ex.txt. awk --version outputs GNU Awk 5.1.1, API: 3.1 (GNU MPFR 4.1.0-p13, GNU MP 6.2.1) as its first line. Thank you!
You are incrementing b at the end of the first iteration of your for (i in rows) loop because i == 0 ==> i%5 == 0, while you want to do it at the end of the 5th iteration. Try if (i%5 == 4) ++b.
Note that as you use GNU awk you could simplify all this. When the record separator (RS) is the empty string the records are separated by empty lines (one record per board):
$ awk -v RS='' '
NR>1 {
a[NR-2][1]; split($0, a[NR-2]);
}
END {
for(b in a) for(r in a[b])
boards[b][int((r-1)/5)][(r-1)%5] = a[b][r];
for(b in boards) for(r in boards[b]) for(n in boards[b][r])
print b, r, n, boards[b][r][n]
}' ex.txt
0 0 0 22
0 0 1 13
0 0 2 17
0 0 3 11
0 0 4 0
0 1 0 8
...

Index array columns using vectors in GNU Octave/MATLAB [duplicate]

This question already has an answer here:
Vector as column index in matrix
(1 answer)
Closed 7 years ago.
While coding in GNU Octave/MATLAB I came through this simple problem I couldn't figure out by myself: I'm trying to select some elements of a matrix by using some indexes stored in an array. Let me put it clear with an example:
Given:
A = zeros(5, 3)
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
I would like to select some elements in A matrix row-wise, by using the values in the auxiliary array B as subindices.
Ie. the following B array
B = [ 1 3 2 1 3 ]'
1
3
2
1
3
should be read as:
1 -> index '1' on first row (element [1, 1])
3 -> index '3' on second row (element [2, 3])
2 -> index '2' on third row (element [3, 2])
1 -> index '1' on fourth row (element [4, 1])
3 -> index '3' on fifth row (element [5, 3])
Therefore, if we assign value '1' to the elements selected using the aforementioned criteria, the resulting matrix would be:
1 0 0
0 0 1
0 1 0
1 0 0
0 0 1
I believe this is a simple operation and I'm convinced that there must be a way to achieve the described behaviour without having to loop across the rows in matrix A.
Thank you.
Edit: Rewrite question so that it is (hopefully) less confusing.
Your question is a bit confusing. You're saying you want to select the elements in A by using the values in the vector B as column indexes, but your example sets (not gets) new values in matrix A. I'm explaining both cases.
Consider this matrix
A = magic(5)
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
Say you want to get/set the diagonal elements of A.
Index pairs in that case are [1,1], [2,2], [3,3], [4,4] and [5,5].
To access elements as a vector, run this
A(sub2ind([5,5], (1:5)',(1:5)'))
17
5
13
21
9
To set elements run this
A(sub2ind([5,5], (1:5)',(1:5)')) = 0
0 24 1 8 15
23 0 7 14 16
4 6 0 20 22
10 12 19 0 3
11 18 25 2 0
These commands can be written as
r = 1:5
c = 1:5
A(sub2ind([max(r),max(c)], r',c'))
# to assign values
A(sub2ind([max(r),max(c)], r',c')) = 0
# and to assign different value to each index pair
A(sub2ind([max(r),max(c)], r',c')) = [20 10 50 12 99]
In your example,
r = 1:5
c = B'
A(sub2ind([max(r),max(c)], r',c')) = 1
# or simply A(sub2ind([max(r),max(B)], r',B)) = 1
1 0 0
0 0 1
0 1 0
1 0 0
0 0 1
You can read how sub2ind works here.

VTK Structured Point file

I am trying to parse a VTK file in C by extracting its point data and storing each point in a 3D array. However, the file I am working with has 9 shorts per point and I am having difficulty understanding what each number means.
I believe I understand most of the header information (please correct me if I have misunderstood):
ASCII: Type of file (ASCII or Binary)
DATASET: Type of dataset
DIMENSIONS: dims of voxels (x,y,z)
SPACING: Volume of each voxel (w,h,d)
ORIGIN: Unsure
POINT DATA: Total number of points/voxels (dimx.dimy.dimz)
I have looked at the documentation and I am still not getting an understanding on how to interpret the data. Could someone please help me understand or point me to some helpful resources
# vtk DataFile Version 3.0
vtk output
ASCII
DATASET STRUCTURED_POINTS
DIMENSIONS 256 256 130
SPACING 1 1 1.3
ORIGIN 86.6449 -133.929 116.786
POINT_DATA 8519680
SCALARS scalars short
LOOKUP_TABLE default
0 0 0 0 0 0 0 0 0
0 0 7 2 4 5 3 3 4
4 5 5 1 7 7 1 1 2
1 6 4 3 3 1 0 4 2
2 3 2 4 2 2 0 2 6
...
thanks.
You are correct regarding the meaning of fields in the header.
ORIGIN corresponds to the coordinates of the 0-0-0 corner of the grid.
An example of a DATASET STRUCTURED_POINTS can be found in the documentation.
Starting from this, here is a small file with 6 shorts per point. Each line represents a point.
# vtk DataFile Version 2.0
Volume example
ASCII
DATASET STRUCTURED_POINTS
DIMENSIONS 3 4 2
ASPECT_RATIO 1 1 1
ORIGIN 0 0 0
POINT_DATA 24
SCALARS volume_scalars char 6
LOOKUP_TABLE default
0 1 2 3 4 5
1 1 2 3 4 5
2 1 2 3 4 5
0 2 2 3 4 5
1 2 2 3 4 5
2 2 2 3 4 5
0 3 2 8 9 10
1 3 2 8 9 10
2 3 2 8 9 10
0 4 2 8 9 10
1 4 2 8 9 10
2 4 2 8 9 10
0 1 3 18 19 20
1 1 3 18 19 20
2 1 3 18 19 20
0 2 3 18 19 20
1 2 3 18 19 20
2 2 3 18 19 20
0 3 3 24 25 26
1 3 3 24 25 26
2 3 3 24 25 26
0 4 3 24 25 26
1 4 3 24 25 26
2 4 3 24 25 26
The 3 first fields may be displayed to understand the data layout : x change faster than y, which change faster than z in file.
If you wish to store the data in an array a[2][4][3][6], just read while doing a loop :
for(k=0;k<2;k++){ //z loop
for(j=0;j<4;j++){ //y loop : y change faster than z
for(i=0;i<3;i++){ //x loop : x change faster than y
for(l=0;l<6;l++){
fscanf(file,"%d",&a[k][j][i][l]);
}
}
}
}
To read the header, fscanf() may be used as well :
int sizex,sizey,sizez;
char headerpart[100];
fscanf(file,"%s",headerpart);
if(strcmp(headerpart,"DIMENSIONS")==0){
fscanf(file,"%d%d%d",&sizex,&sizey,&sizez);
}
Note than fscanf() need the pointer to the data (&sizex, not sizex). A string being a pointer to an array of char terminated by \0, "%s",headerpart works fine. It can be replaced by "%s",&headerpart[0]. The function strcmp() compares two strings, and return 0 if strings are identical.
As your grid seems large, smaller files can be obtained using the BINARY kind instead of ASCII, but watch for endianess as specified here.

Finding or arranging all combinations of given numbers [duplicate]

This question already has answers here:
Find all combinations of a given set of numbers
(9 answers)
Closed 8 years ago.
I hope all you are doing great.
I have an interesting question, which has stuck me. Its about generating combinations in a precise order.
For example i have 4 variables(can be vary) and these 4 variables has some limit to increase for example in this case 2. so i want to generate 2d matrix in a order as:
0 0 0 0
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
1 1 0 0
1 0 1 0
1 0 0 1
0 1 1 0
0 1 0 1
0 0 1 1
1 1 1 0
0 1 1 1
1 1 1 1
2 0 0 0
0 2 0 0
0 0 2 0
0 0 0 2
2 1 0 0
2 0 1 0
......
......
and so on.
the number of variables ( in this case 4 ) can be varied and also the maximum limit ( in this case 4) can be varied.
Even i have also find all possible combinations but i am not able to arrange them in this sequence.
it would be great if somebody gives an answer.
cheers!
I'm going to assume you've got n variables, each of which is allowed to range from 0 to b-1. What you want is just counting n-digit numbers in base b. For example, if n = 2 and b = 3, then the sequence you want to produce is
00
01
02
10
11
12
20
21
22
To implement this, write a loop something like the following: (warning: untested code)
def inc(v, b):
for i in range(len(v)):
v[i] = v[i] + 1
if v[i] < b:
break
v[i] = 0
def is_zero(v):
for i in range(len(v)):
if v[i] != 0:
return False
return True
v = [0, 0, 0]
b = 3
while True:
print(v)
inc(v, b)
if is_zero(v):
break
If you look carefully at how this works, you should see how to generalize it if your variables have different upper bounds.

What is the meaning of the addition at the end of this array declaration?

I'm tasked with implementing an algorithm which was supplied as Matlab (which none of us have any experience with) into our c++ application.
There is an array declared as such:
encrypted = [18 10 20 13 6 25 21 13 17;
2 26 4 29 22 9 5 29 1;
19 11 21 12 7 24 20 12 16;
% ... many rows like this ...
13 21 11 18 25 6 10 18 14]+1;
What is the semantic meaning of the +1 at the end of the array declaration?
Simply adding 1 to each entry:
>> [1 2 3; 4 5 6]
ans =
1 2 3
4 5 6
>> [1 2 3; 4 5 6] + 1
ans =
2 3 4
5 6 7
If you have MATLAB around, you could have figured that out by just trying. If you do not, I hope you have a very clear picture of what the code is doing and write a good test suite, since you won't be able to compare your new code's output to the MATLAB one.
The +1 means that all elements of the written matrix will be increased by one.
Example
out = [1 2;
3 4] + 1;
disp(out)
2 3
4 5

Resources