Bash Almost Magic Square
almost_magic_square() {
local -n _a="$1"
local -n _out="$2"
local -a _rowSum=(0 0 0) _colSum=(0 0 0)
local -a _m
local _i _j
for ((_i = 0; _i < 3; _i++)); do
for ((_j = 0; _j < 3; _j++)); do
_m[_i*3+_j]=${_a[_i*3+_j]}
done
done
for ((_i = 0; _i < 3; _i++)); do
for ((_j = 0; _j < 3; _j++)); do
_rowSum[_i]=$(( _rowSum[_i] + _m[_i*3+_j] ))
_colSum[_i]=$(( _colSum[_i] + _m[_j*3+_i] ))
done
done
local _maxSum=0
for ((_i = 0; _i < 3; _i++)); do
if (( _rowSum[_i] > _maxSum )); then _maxSum=${_rowSum[_i]}; fi
if (( _colSum[_i] > _maxSum )); then _maxSum=${_colSum[_i]}; fi
done
_i=0; _j=0
while (( _i < 3 && _j < 3 )); do
local _diffR=$(( _maxSum - _rowSum[_i] ))
local _diffC=$(( _maxSum - _colSum[_j] ))
local _diff=$(( _diffR < _diffC ? _diffR : _diffC ))
_m[_i*3+_j]=$(( _m[_i*3+_j] + _diff ))
_rowSum[_i]=$(( _rowSum[_i] + _diff ))
_colSum[_j]=$(( _colSum[_j] + _diff ))
if (( _rowSum[_i] == _maxSum )); then ((_i++)); fi
if (( _colSum[_j] == _maxSum )); then ((_j++)); fi
done
_out=("${_m[@]}")
}
This adjusts the matrix toward a matching target sum so the rows and columns line up more like a magic square.