#!/usr/local/bin/gawk -f # # Magic square (Calculation and check it by "Magic square condition") # # This program was inspired by the discussion in BBMS. # # May 12, 1990 # Add the sequential check May 13, 1990 # Translate the messages into English. July 10, 1996 # # by F. Poyo # BEGIN { print "Hit [Return key] for the calculations of magic square.\n"; printf "For explanations, type \"Help\" here:"; getline key; print "\033[2J" if(( substr(key,1,1) == "H" )|| ( substr(key,1,1) == "h" )) { printf "\033[33mUsage...\033[m\n" print " " printf " \033[36mDefault usage..\033[m\n" print " " print " gawk -f magic.awk" print " " printf " \033[36mGet seed matrix from file.\033[m\n"; print " " print " gawk -f magic.awk magic.dat" print " ~~~~~~~~~<--¹File name would be" print " vary." printf " \033[36mHow to make seed matrix (magic.dat).\033[m\n" print " " print " From row 1 and row N, place vectors 123...N and" print " N...321 in turn." print " " print " * There is a difference in the methods for the cases N=4m and N=4m+2" print " " print " E.g. the seed matrices for N=4 and N=6 are\n" printf "\033[35m[Hit Return key]\033[m"; getline key print " " print " 1234 123456" print " 4321 654321" print " 4321 654321" print " 1234 123456" print " 654321" print " 123456" print " " print "In the case of N=4m, the matrix made by the above" print "method satisfies \"Magic square condition.\"" print "In the case of N=4m+2, since the matrix does not satisfy" print "\"Magic square condition\", interchange the pairs (1,6)," print "(2,5) and (3,4) in ad hoc manner." print " " print "In this program, the interchangings of pairs are algorithmically" print "implemented. Only this part is my (F.Poyo's) contribution to" print "the algorithm." print " " printf "\033[35m[Hit Return key]\033[m"; getline key print " " print " 153426" print " 654321" print " 624351" print " 124356" print " 653421" print " 123456" print " " print "Now we have a seed matrix which satisfy \"Magic square" print "condition.\" Put this data into magic.dat" print " " print " This method was introduced by " print " " print " |From: m.matsumoto@tainsbbms (Hikaru Matsumoto)|" print " |Message-ID: <20014@tainsbbs> |" print " |Date: 1990/05/09 09:39:50 |" print " " print " The original reference is unknown." print " " exit; } if(ARGC > 1) { # Get seed matrix from a file for even order magic square i = 1; while((getline m) > 0) { N = split(m,MM); for(j=1;j<=N;j++) { A[i,j]=MM[j]; } i++; } print "\033[2JOrder:",N } else { printf "\033[5;10HWhat is the order of the magic square? :" getline N; print "\033[2JThe order:",N; if((N % 2) == 0) { #” Calculate the seed matrix of even order magic square. for( i = 1 ; i <= (N/2) ; i++ ) { for( j = 1 ; j <= N ; j++ ) { if((i % 2) == 1) { A[i,j] = j; A[N-i+1,j] = j; } else { A[i,j] = N-j+1; A[N-i+1,j] = N-j+1; } } } if(((N-2) % 4) == 0) { #” In the case of N=4m+2. swapcolm(N/2 - 1,N/2); swapcolm(N/2 ,N/2); swapcolm(N/2 + 1,N/2); k = 1; for( i = 1 ; i <= N/2 ; i++ ) { if( (i % 2) == 1) { chk[k] = i; k++; chk[k] = N - i + 1; k++; } } kmax = k; for( i = 1 ; i <= (N/2 - 1) ; i++ ) { ok = 0; for(k = 1;k < kmax; k++) { if(((i != chk[k]) && ((N - i + 1) != chk[k])) && (chk[k] != 0)) { if(A[i,chk[k]] == A[N - i + 1,chk[k]]) { ok = 1; break; } } } if ( ok == 1) { swapcolm(chk[k],i); chk[k] = 0; } else { print "Sorry but I can not make the seed matrix." exit; } } } } } if( (N % 2) == 0 ) { #” Calculation of even order magic square printf "----------Seed matrix (Order:%d) ----------\n",N ; for(i=1;i<=N;i++) { for(j=1;j<=N;j++) printf "%-3d ",A[i,j] ; printf "\n" ; } for(i=1;i<=N;i++) { for(j=1;j<=N;j++) { M[i,j] = A[i,j] + N * (A[j,i] - 1); } } } else { # Calculation of odd order magic square. for(i = 1 ; i <= N ; i++) for(j = 1 ; j <= N ; j++) { M[i,j] = 0; } i = int(N / 2) + 1; j = N; M[i,j] = 1; for( n = 2 ; n <= N*N ; n++ ) { pre_i = i ; pre_j = j ; i++ ; j++ ; if(( i == (N+1) ) && ( j == (N+1) )) { i = N; j = N - 1; } if( i > N ) i = 1 ; if( j > N ) j = 1 ; if(M[i,j] != 0) { i = pre_i ; j = pre_j - 1 ; } M[i,j] = n; } } #” Display SUM = 0 for(i=1;i<=N*N;i++) { SUM += i; } SUM /= N; printf "----------Magic square (Order:%d, The sum:%d) ----------\n",N,SUM ; for(i=1;i<=N;i++) { for(j=1;j<=N;j++) { printf "%-3d ",M[i,j] ; } printf "\n" ; } printf "\n" ; # Check the calculation by "Magic square condition". for(i=1;i<=(N*N);i++) { NN[i] = i; } for(i=1;i<=N;i++) { for(j=1;j<=N;j++) { if((M[i,j] != 0) && (NN[M[i,j]] == M[i,j])) { NN[M[i,j]] = 0; } else { printf "%d appears twice at least.\n",M[i,j]; print "Since the elements are not sequential natural numbers," print "it's not a magic square." exit; } } } printf "Check 1:OK ... Elements are sequential natural numbers(1 ... %4d)\n", N*N SS = 0; SSS = 0; for(i=1;i<=N;i++) { S = 0; for(j=1;j<=N;j++) S += M[i,j]; if( SUM != S ) { print "... but it's not a magic square,"; print " there is an error in the sum of the elements for row vectors."; exit ; } S = 0; for(j=1;j<=N;j++) S += M[j,i]; if( SUM != S ) { print "... but it's not a magic square,"; print " there is an error in the sum of the elements for column vectors."; exit ; } SS += M[i,i]; SSS += M[i,N-i+1]; } printf "Check 2:OK ... The sum of the elements for all the row and column vectors is %d.\n", S if( SUM != SS ) { print "... but it's not a magic square,"; printf " the sum of the elements for diagonal vector (toward right bottom) is %d.\n",SS; exit ; } if( SUM != SSS ) { print "... but it's not a magic square,"; printf " the sum of the elements for diagonal vector (toward left bottom) is %d.\n",SSS; exit ; } printf "Check 3:OK ... The sum of the elements for all the diagonal vectors is %d.\n", S print "Congratulations! it's a magic square." } function swapcolm(line,column,dummy) { dummy = A[line,column]; A[line,column] = A[line,N-column+1]; A[line,N-column+1] = dummy; }