Saturday, April 19, 2014

Windows Scripting. Lesson 5. Magic Square

A magic square is one where the total of rows, columns and diagonals is the same.

Take a 3x3 magic square.

image

The Rules are pretty simple. The rule is called top-left rule.

1. Start with 1. Put it in the centre of the 1st row. So 1 is in (1,2) Row 1, Col 2.

2. Goto top left. In this case top is row 0, so top comes to the 3rd row. Left is row 1. So the next number is (3,1).

3. Continue with top left. Top of 3 is 2, left of 1 is 3rd column. So we are in (2,3).

4. Now the top left from 2,3 is 1,2. This place is occupied, you have a 1 there. So you need to go back to original location (2,3). Then come a place down but same column. So from 2,3 we come to 3,3. Put a 4 here. Continue this way.

5. In this case the totals of rows, col and diagonal is 15. Why 15?

6. We use the natural numbers 1 to 9. Sum of 1 to 9 is n(n+1)/2. In this example we have 9x10/2=45. We have 3 rows. So we get 45/3 or 15.

sub Print(str)
    wscript.echo str
end sub

' Main Program starts from here
dim x(3,3)
dim y
for a=1 to 3
    for b=1 to 3
        x(a,b)=0
    next
next

x(1,2)=1
a=1
b=2
for y=2 to 9
    olda=a
    oldb=b
    a=a-1
    b=b-1
    if a=0 then
        a=3
    end if
    if b=0 then
        b=3
    end if
    if x(a,b)>0 then
        a=olda
        b=oldb
        a=a+1
    end if
    x(a,b)=y
next
for a=1 to 3
    for b=1 to 3
        str=str & chr(9) & x(a,b)
    next
    wscript.echo str
    str=" "
next

- print procedure makes the printing easy.

- dim, defines an array. In this case it is an array 3 rows x 3 cols. Each value in the array is defined as 0. 1 is put then in the first row and second column.

- for loop rotates eight times for the eight numbers. a and b are the locations needed. We try top left, and if it is occupied (>0), then we go back to the original location and come one col down.

- the for loop then prints the 3 coloumns. Each row is formatted is by adding a tab (chr(9). When you compile and run this program, (magic3.vbs)

C:\scripts>magic3 //nologo
        6       1       8
        7       5       3
        2       9       4

C:\scripts>

 

Can we make a generic version of this program.  Where we can print for any odd number. Since vbscript does not allow to define an array with a variable, I have defined a large array (20,20) and allow to print a magic square. The beauty is you can pass the number as a parameter. If the parameter is even, then we add 1 and make it a odd number. The program is very similar to the previous program.

sub Print(str)
    wscript.echo str
end sub

sz=int(wscript.arguments(0))
if sz mod 2 = 0 then
    print "Argument Should be Odd"
    print "Changing to odd"
    sz=sz+1
end if
'sz=3
dim x(20,20)
dim y
for a=1 to sz
    for b=1 to sz
        x(a,b)=0
    next
next

x(1,(sz+1)/2)=1
a=1
b=(sz+1)/2
for y=2 to (sz * sz)
    olda=a
    oldb=b
    a=a-1
    b=b-1
    if a=0 then
        a=sz
    end if
    if b=0 then
        b=sz
    end if
    if x(a,b)>0 then
        a=olda
        b=oldb
        a=a+1
    end if
    x(a,b)=y
next
for a=1 to sz
    for b=1 to sz
        str=str & chr(9) & x(a,b)
    next
    wscript.echo str
    str=" "
next

Sample output.

C:\scripts>magicgen 5 //nologo
        15      8       1       24      17
        16      14      7       5       23
        22      20      13      6       4
        3       21      19      12      10
        9       2       25      18      11

C:\scripts>magicgen 7 //nologo
        28      19      10      1       48      39      30
        29      27      18      9       7       47      38
        37      35      26      17      8       6       46
        45      36      34      25      16      14      5
        4       44      42      33      24      15      13
        12      3       43      41      32      23      21
        20      11      2       49      40      31      22

An exercise for you. Can you use the n(n+1)/2 formula as mentioned earlier and print one line at the end of the program.

Sum of Rows/Col is _______

Like this

C:\scripts>magicgen 5 //nologo
        15      8       1       24      17
        16      14      7       5       23
        22      20      13      6       4
        3       21      19      12      10
        9       2       25      18      11
Sum of rows/col is      65

No comments: