OkIDaN
02-08-2005, 12:06 AM
Beauty Of Programming I
================
by OkIDaN
This is just a monologue on beauty of programming. I had this idea to start the series for a while, now here it is. Im not sure next parts will come. But anyway...
What inspired me to write this? A simple program that does a simple job, prints a spiral of numbers. Like:
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Here is the code that does that:
uses crt;
const
n=11;
var
a:array [1..n*n] of integer;
b:array [1..n,1..n] of integer;
n1,k,i,j,d,s:integer;
begin
clrscr;
for i:=1 to n*n do
a[i]:=i;
for j:=1 to n do
for i:=1 to n do
b[j,i]:=0;
n1:=n;
i:=0;
j:=1;
d:=1;
k:=0;
while k<sqr(n) do
begin
for s:=1 to n1 do
begin
i:=i+d;
k:=k+1;
b[j,i]:=a[k];
end;
n1:=n1-1;
for s:=1 to n1 do
begin
j:=j+d;
k:=k+1;
b[j,i]:=a[k];
end;
d:=-d;
end;
for i:=1 to n do
begin
for j:=1 to n do
write(b[i,j]:5);
writeln;writeln;
end;
end.
This program was written by my good friend Rajab back in school time. He always was a better programmer than me, and probably now too. Just take a look at the code and try to understand it. Its pretty easy to understand pascal for a programmer with even a little bit of experience. Just try to understand the code, I know it can seem hard to understand, all the incrementation and variable assignations can cause some hard attention to understand the whole code. But take your time.
I kept this program inside my folders for years just as a nostalgie of those school times when I started with pascal, and since then never looked at it. But when I was browsing these files while ago, I was astonished, surprised, amazed with the beauty and clearness this code shines with. Look at the technique, so creatively found and so easily implemented. Im still like woah at this little piece of code.
It creates a 2 dimensional array 'var b:array [1..n,1..n] of integer;' to store the numbers there, and starts to manipulate it so easily and so boldly. I will annotate the main loop:
while k<sqr(n) do
begin
for s:=1 to n1 do
begin
i:=i+d;
k:=k+1;
b[j,i]:=a[k];
end;
n1:=n1-1;
for s:=1 to n1 do
begin
j:=j+d;
k:=k+1;
b[j,i]:=a[k];
end;
d:=-d;
end;
This is the heart of the program. What do we got so far till the code? An array 'a' of 121 elements, where a[n]=n in all cases; 2d array b, where b[j,i]=0 in all cases initially (one of the weaknesses of pascal, you cant assign to an undefined, not created variable);and some other variables that we will use during the main part of the code.
while k<sqr(n) do
begin
...
end;
This is how loops are declared in pascal. If you want to do more than one operation you have to state the begin and end points. This loop will continue until k = or > than 121, thus while k<121. Anyway:
for s:=1 to n1 do
begin
i:=i+d;
k:=k+1;
b[j,i]:=a[k];
end;
This loop will proceed for "n1 times", thus 11 times. Lets walk through the code watching the variables change:
i:=0+1=1
k=0+1=1
b[1,1]=a[1]=1
-next loop
i:=1+1=2
k:=1+1=2
b[1,2]=a[2]=2
This continues till:
b[1,11]=a[11]=11
I think some of you are still not getting it, just look. Remind a chess board, of 8 horizontal lines which are marked from 1 to 8, and 8 vertical lines which are marked from a to h. Now b[j,i] is a coordinate in chess board where j is horizontal line, and i is vertical line. There is only one difference, horizontal lines are reversed. In place of 8 - the upper line in chess board now it is 1, in place of 7, it is 2. And the size of the board here isnt 8x8 but 11x11. And all of the fields in the board are storing a value, like chess fields store pawns, rooks, etc. This is a simple example of 2d array.
In the upper code we assigned data (numbers) to all of the fileds in first (j=1) horizontal line. Now we are going on to second line...Hah! Gotcha! How do you think we will assign the next number to lets say b[2,1], what will the number be there? Surely not 12, because it is a spiral, and the field that has to store number 12 isnt b[2,1] but is b[2,11]! And then b[3, 11] will be 13, etc. This means we are going to flip to go down the last vertical (h in chess, 11 in here) and assign values to its fields. I hope Im clear enough, i just love this code so much. So, here is how we do it:
n1:=n1-1;
for s:=1 to n1 do
begin
j:=j+d;
k:=k+1;
b[j,i]:=a[k];
end;
Uhmm, what is that n1:=n1-1; line there? I wonder what could that mean...OH! I got it, in the first loop we had to assign values to 11 fields to the right, so we had to take 11 steps. That is why the loop continued only 11 times. Now it will continue 10 times. Because we have already assigned the upper right field (b[1,11]), now we have to go only 10 fields down. Lets follow the code:
j:=1+1=2;
k:=11+1=12;
b[2,11]=12;
Heh, now you seem to start understand what it is all about, right? I remains 11 while j increases.
j:=2+1=3;
k:=12+1;
b[3,11]=13;
And so on, until the lower right field is set:
b[11,11]=21;
Now come the line that is the heartbeat of the program, this is the line that made me go whooah again and again:
d:=-d;
This is the line that came from the fingertips of a mans so creative so taleented. It just decreases the program size by approximately two other loops, saves space, makes the program run faster, makes it clear, beautiful and just great! This is a simple variable assignation, but so creative and so in place.
What was d? d was always 1, now it is -1. And the heart loop sees that k is still not 121, but some 21 and goes onto next loop. Lets follow everything from the start again:
for s:=1 to n1 do
begin
i:=i+d;
k:=k+1;
b[j,i]:=a[k];
end;
Loop will continue 10 times, as we still have 10 empty fields in this horizontal, yes we are going on assigning values to the bottom horizontal, we are just following the spiral:
i:=11+(-1)=10;
k:=21+1=22;
b[11,10]=22;
Now look at this beauty, we are going left on the bottom horizontal just like in spiral. Beauty of programming and creativity of talented mind make me crazy everytime. This loop will continue till:
i:=2+(-1)=1;
k:=30+1=31;
b[11,1]=31;
This last one assing to the left-bottom field of our 2d board the next number in incrementation trying to form a spiral. Now lets look at the next part one more time:
n1:=n1-1;
for s:=1 to n1 do
begin
j:=j+d;
k:=k+1;
b[j,i]:=a[k];
end;
d:=-d;
n1 becomes 9 as there is one less space now to be written in current horizontal/vertical. The deincrementation of n1 is not accidentally place right between the loops, not before or after any of them. Coz the only deincrementation happens when going either down or up vertically from the previous horizontal assignations. It happens so because the starting point of the spiral was a horizontal move, and we filled horizontal line. Just think about it. So:
j:=11+(-1)=10
k:=32;
b[10,1]:=32;
Now are are going upward on the first vertical line (a in chess).
j:=10-1=9;
k:=33;
b[9,1]:=33;
This goes on till:
b[2,1]=40;
2,1 because if you remember we have our b[1,1] board written and we wouldnt like to overwrite it, coz it can **** up everything.
Now again,
d:=-d;
This changes d into +1 again, Now its time to go right and then down, which need +1 incrementation, wheras when the program will start going back after one more loop left and then up it will use -1 again.
That is mainly what I wanted to tell you about the beauty and creativity of my friends code that was written 3-4 years ago in my high school.
Now, I couldnt sit tight, coz I love programming and always love to test my skills upon basic programming which needs a lot of thinking and creativity. I decided to rewrite Rajab's code...in perl...and not with 2d array...but with 1 dimensional normal array. Yeah, it took me a few hours to write a small program. 90% of time I was just staring at the monitor and thinking. And it is smaller than the 2nd one. Though, taking in mind that pascal needs all variable declarations before their assignments I would fairly say that mine and my friends program are nearly the same size. So, here it is:
my @spiral;
my $n=0;
my $i=1;
my $loop=9;
my $l=1;
while ($l <= 81){
$x=$n+$loop*$i; #$x=9
while ($n != $x){
$n=$n+$i;
$spiral[$n]=$l;
$l++;
}
if ($i>0){$i=$i+8;}else{$i=$i-8;}
$loop--;
last if ($l > 81);
$x=$n+$loop*$i; #$x=81; $n=9;
while ($n != $x){
$n=$n+$i;
$spiral[$n]=$l;
$l++;
}
if ($i>0){$i=$i-10;}else{$i=$i+10;}
#$n=81; $i=-1; $x=72 - next loop ^
}
$i=1; $n=1;
while ($i <= 81){
print "$spiral[$i]\t";
if ($n == 9){
print "\n\n";
$n=0;
}
$i++; $n++;
}
Now I leave this one to your own brain, I think it will be harder to understand variable manipulations here. Coz in the end it needs more variables to support the code than the one with 2d array.
Here are web-links to programs stated here:
http://okidan.binaryshadow.org/spiral.pas.txt - the pascal source code
http://okidan.binaryshadow.org/spiral.exe - the pascal executable, I think will work in all windows.
http://okidan.binaryshadow.org/spiral.pl.txt - the perl source code
Hoped you liked my monologue, and I hope to continue the Beauty of programming series in the meantime. You can get this paper from http://okidan.binaryshadow.org/beauty1.txt as well. Visit my website for my perl programs and other stuff: http://www.freewebs.com/okidan/
I devote the first part of the series to my friend Radjab, havent seen him so long.
================
by OkIDaN
This is just a monologue on beauty of programming. I had this idea to start the series for a while, now here it is. Im not sure next parts will come. But anyway...
What inspired me to write this? A simple program that does a simple job, prints a spiral of numbers. Like:
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Here is the code that does that:
uses crt;
const
n=11;
var
a:array [1..n*n] of integer;
b:array [1..n,1..n] of integer;
n1,k,i,j,d,s:integer;
begin
clrscr;
for i:=1 to n*n do
a[i]:=i;
for j:=1 to n do
for i:=1 to n do
b[j,i]:=0;
n1:=n;
i:=0;
j:=1;
d:=1;
k:=0;
while k<sqr(n) do
begin
for s:=1 to n1 do
begin
i:=i+d;
k:=k+1;
b[j,i]:=a[k];
end;
n1:=n1-1;
for s:=1 to n1 do
begin
j:=j+d;
k:=k+1;
b[j,i]:=a[k];
end;
d:=-d;
end;
for i:=1 to n do
begin
for j:=1 to n do
write(b[i,j]:5);
writeln;writeln;
end;
end.
This program was written by my good friend Rajab back in school time. He always was a better programmer than me, and probably now too. Just take a look at the code and try to understand it. Its pretty easy to understand pascal for a programmer with even a little bit of experience. Just try to understand the code, I know it can seem hard to understand, all the incrementation and variable assignations can cause some hard attention to understand the whole code. But take your time.
I kept this program inside my folders for years just as a nostalgie of those school times when I started with pascal, and since then never looked at it. But when I was browsing these files while ago, I was astonished, surprised, amazed with the beauty and clearness this code shines with. Look at the technique, so creatively found and so easily implemented. Im still like woah at this little piece of code.
It creates a 2 dimensional array 'var b:array [1..n,1..n] of integer;' to store the numbers there, and starts to manipulate it so easily and so boldly. I will annotate the main loop:
while k<sqr(n) do
begin
for s:=1 to n1 do
begin
i:=i+d;
k:=k+1;
b[j,i]:=a[k];
end;
n1:=n1-1;
for s:=1 to n1 do
begin
j:=j+d;
k:=k+1;
b[j,i]:=a[k];
end;
d:=-d;
end;
This is the heart of the program. What do we got so far till the code? An array 'a' of 121 elements, where a[n]=n in all cases; 2d array b, where b[j,i]=0 in all cases initially (one of the weaknesses of pascal, you cant assign to an undefined, not created variable);and some other variables that we will use during the main part of the code.
while k<sqr(n) do
begin
...
end;
This is how loops are declared in pascal. If you want to do more than one operation you have to state the begin and end points. This loop will continue until k = or > than 121, thus while k<121. Anyway:
for s:=1 to n1 do
begin
i:=i+d;
k:=k+1;
b[j,i]:=a[k];
end;
This loop will proceed for "n1 times", thus 11 times. Lets walk through the code watching the variables change:
i:=0+1=1
k=0+1=1
b[1,1]=a[1]=1
-next loop
i:=1+1=2
k:=1+1=2
b[1,2]=a[2]=2
This continues till:
b[1,11]=a[11]=11
I think some of you are still not getting it, just look. Remind a chess board, of 8 horizontal lines which are marked from 1 to 8, and 8 vertical lines which are marked from a to h. Now b[j,i] is a coordinate in chess board where j is horizontal line, and i is vertical line. There is only one difference, horizontal lines are reversed. In place of 8 - the upper line in chess board now it is 1, in place of 7, it is 2. And the size of the board here isnt 8x8 but 11x11. And all of the fields in the board are storing a value, like chess fields store pawns, rooks, etc. This is a simple example of 2d array.
In the upper code we assigned data (numbers) to all of the fileds in first (j=1) horizontal line. Now we are going on to second line...Hah! Gotcha! How do you think we will assign the next number to lets say b[2,1], what will the number be there? Surely not 12, because it is a spiral, and the field that has to store number 12 isnt b[2,1] but is b[2,11]! And then b[3, 11] will be 13, etc. This means we are going to flip to go down the last vertical (h in chess, 11 in here) and assign values to its fields. I hope Im clear enough, i just love this code so much. So, here is how we do it:
n1:=n1-1;
for s:=1 to n1 do
begin
j:=j+d;
k:=k+1;
b[j,i]:=a[k];
end;
Uhmm, what is that n1:=n1-1; line there? I wonder what could that mean...OH! I got it, in the first loop we had to assign values to 11 fields to the right, so we had to take 11 steps. That is why the loop continued only 11 times. Now it will continue 10 times. Because we have already assigned the upper right field (b[1,11]), now we have to go only 10 fields down. Lets follow the code:
j:=1+1=2;
k:=11+1=12;
b[2,11]=12;
Heh, now you seem to start understand what it is all about, right? I remains 11 while j increases.
j:=2+1=3;
k:=12+1;
b[3,11]=13;
And so on, until the lower right field is set:
b[11,11]=21;
Now come the line that is the heartbeat of the program, this is the line that made me go whooah again and again:
d:=-d;
This is the line that came from the fingertips of a mans so creative so taleented. It just decreases the program size by approximately two other loops, saves space, makes the program run faster, makes it clear, beautiful and just great! This is a simple variable assignation, but so creative and so in place.
What was d? d was always 1, now it is -1. And the heart loop sees that k is still not 121, but some 21 and goes onto next loop. Lets follow everything from the start again:
for s:=1 to n1 do
begin
i:=i+d;
k:=k+1;
b[j,i]:=a[k];
end;
Loop will continue 10 times, as we still have 10 empty fields in this horizontal, yes we are going on assigning values to the bottom horizontal, we are just following the spiral:
i:=11+(-1)=10;
k:=21+1=22;
b[11,10]=22;
Now look at this beauty, we are going left on the bottom horizontal just like in spiral. Beauty of programming and creativity of talented mind make me crazy everytime. This loop will continue till:
i:=2+(-1)=1;
k:=30+1=31;
b[11,1]=31;
This last one assing to the left-bottom field of our 2d board the next number in incrementation trying to form a spiral. Now lets look at the next part one more time:
n1:=n1-1;
for s:=1 to n1 do
begin
j:=j+d;
k:=k+1;
b[j,i]:=a[k];
end;
d:=-d;
n1 becomes 9 as there is one less space now to be written in current horizontal/vertical. The deincrementation of n1 is not accidentally place right between the loops, not before or after any of them. Coz the only deincrementation happens when going either down or up vertically from the previous horizontal assignations. It happens so because the starting point of the spiral was a horizontal move, and we filled horizontal line. Just think about it. So:
j:=11+(-1)=10
k:=32;
b[10,1]:=32;
Now are are going upward on the first vertical line (a in chess).
j:=10-1=9;
k:=33;
b[9,1]:=33;
This goes on till:
b[2,1]=40;
2,1 because if you remember we have our b[1,1] board written and we wouldnt like to overwrite it, coz it can **** up everything.
Now again,
d:=-d;
This changes d into +1 again, Now its time to go right and then down, which need +1 incrementation, wheras when the program will start going back after one more loop left and then up it will use -1 again.
That is mainly what I wanted to tell you about the beauty and creativity of my friends code that was written 3-4 years ago in my high school.
Now, I couldnt sit tight, coz I love programming and always love to test my skills upon basic programming which needs a lot of thinking and creativity. I decided to rewrite Rajab's code...in perl...and not with 2d array...but with 1 dimensional normal array. Yeah, it took me a few hours to write a small program. 90% of time I was just staring at the monitor and thinking. And it is smaller than the 2nd one. Though, taking in mind that pascal needs all variable declarations before their assignments I would fairly say that mine and my friends program are nearly the same size. So, here it is:
my @spiral;
my $n=0;
my $i=1;
my $loop=9;
my $l=1;
while ($l <= 81){
$x=$n+$loop*$i; #$x=9
while ($n != $x){
$n=$n+$i;
$spiral[$n]=$l;
$l++;
}
if ($i>0){$i=$i+8;}else{$i=$i-8;}
$loop--;
last if ($l > 81);
$x=$n+$loop*$i; #$x=81; $n=9;
while ($n != $x){
$n=$n+$i;
$spiral[$n]=$l;
$l++;
}
if ($i>0){$i=$i-10;}else{$i=$i+10;}
#$n=81; $i=-1; $x=72 - next loop ^
}
$i=1; $n=1;
while ($i <= 81){
print "$spiral[$i]\t";
if ($n == 9){
print "\n\n";
$n=0;
}
$i++; $n++;
}
Now I leave this one to your own brain, I think it will be harder to understand variable manipulations here. Coz in the end it needs more variables to support the code than the one with 2d array.
Here are web-links to programs stated here:
http://okidan.binaryshadow.org/spiral.pas.txt - the pascal source code
http://okidan.binaryshadow.org/spiral.exe - the pascal executable, I think will work in all windows.
http://okidan.binaryshadow.org/spiral.pl.txt - the perl source code
Hoped you liked my monologue, and I hope to continue the Beauty of programming series in the meantime. You can get this paper from http://okidan.binaryshadow.org/beauty1.txt as well. Visit my website for my perl programs and other stuff: http://www.freewebs.com/okidan/
I devote the first part of the series to my friend Radjab, havent seen him so long.