3
# Magic Square generator (odd-order squares only!)
5
# Author: mendel cooper
6
# reldate: 19 Jan. 2009
7
# License: Public Domain
8
# A C-program by Kwon Young Shin inspired this script.
9
# See http://user.chollian.net/~brainstm/MagicSquare.htm ...
11
# Definition: A "magic square" is a two-dimensional array
12
# of integers in which all the rows, columns,
13
# and *long* diagonals add up to the same number.
14
# Being "square," the array has the same number
15
# of rows and columns.
16
# An example of a magic square of order 3 is:
20
# All the rows, columns, and long diagonals add up to 15.
25
MAXSIZE=31 # 31 rows x 31 cols.
26
E_usage=90 # Invocation error.
32
echo "Usage: $0 square-size"
33
echo " ... where \"square-size\" is an ODD integer"
34
echo " in the range 3 - 31."
35
# Actually works for squares up to order 159,
36
#+ but large squares will not display pretty-printed in a term window.
37
# Try increasing MAXSIZE, above.
42
calculate () # Here's where the actual work gets done.
44
local row col index dimadj j k cell_val=1
47
let "dimadj = $dimension * 3"; let "dimadj /= 2" # x 1.5, then truncate.
49
for ((j=0; j < dimension; j++))
51
for ((k=0; k < dimension; k++))
52
do # Calculate indices, then convert to 1-dim. array index.
53
# Bash doesn't support multidimensional arrays. Pity.
54
let "col = $k - $j + $dimadj"; let "col %= $dimension"
55
let "row = $j * 2 - $k + $dimension"; let "row %= $dimension"
56
let "index = $row*($dimension) + $col"
57
square[$index]=cell_val; ((cell_val++))
60
} # Plain math, no visualization required.
63
print_square () # Output square, one row at a time.
66
let "d1 = $dimension - 1" # Adjust for zero-indexed array.
68
for row in $(seq 0 $d1)
71
for col in $(seq 0 $d1)
73
let "idx = $row * $dimension + $col"
74
printf "%3d " "${square[idx]}"; echo -n " "
75
done # Displays up to 13-order neatly in 80-column term window.
77
echo # Newline after each row.
82
#################################################
83
if [[ -z "$1" ]] || [[ "$1" -gt $MAXSIZE ]]
88
let "test_even = $1 % $EVEN"
89
if [ $test_even -eq 0 ]
90
then # Can't handle even-order squares.
95
print_square # echo "${square[@]}" # DEBUG
98
#################################################
103
# 1) Add a function to calculate the sum of each row, column,
104
# and *long* diagonal. The sums must match.
105
# This is the "magic constant" of that particular order square.
106
# 2) Have the print_square function auto-calculate how much space
107
# to allot between square elements for optimized display.
108
# This might require parameterizing the "printf" line.
109
# 3) Add appropriate functions for generating magic squares
110
# with an *even* number of rows/columns.
111
# This is non-trivial(!).
112
# See the URL for Kwon Young Shin, above, for help.