# # MagicSquare.pm, version 2.04 13 Dec 2003 # # Copyright (c) 2003 Fabrizio Pivari Italy # fabrizio@pivari.com # # Free usage under the same Perl Licence condition. # package Math::MagicSquare; use Carp; use GD; use strict; use vars qw(@ISA @EXPORT @EXPORT_OK \$VERSION); use Exporter(); @ISA= qw(Exporter); @EXPORT=qw(); @EXPORT_OK=qw(new check print printhtml rotation reflection); \$VERSION='2.04'; sub new { my \$type = shift; my \$self = []; my \$len = scalar(@{\$_[0]}); my \$numelem = 0; for (@_) { push(@{\$self}, [@{\$_}]); \$numelem += scalar(@{\$_}); } croak "Math::MagicSquare::new(): number of rows and columns must be equal" if (\$numelem != \$len*\$len); bless \$self, \$type; } sub check { my \$self = shift; my \$i=0; my \$j=0; my \$line1=0; my \$line2=0; my \$diag1=0; my \$diag2=0; my \$SUM=0; my \$sms=1; my \$len = scalar(@{\$self}); # Magic Constant for a Magic Square 1,2,...,n my \$sum=\$len*(\$len*\$len+1)/2; # Generic Magic Constant for (\$i=0;\$i<\$len;\$i++) { \$SUM+=\$self->[\$i][0]; } if (\$SUM != \$sum) {\$sum=\$SUM;} # Check lines and columns for (\$i=0;\$i<\$len;\$i++) { \$j=0; \$line1=0; \$line2=0; for (\$j=0;\$j<\$len;\$j++) { \$line1+=\$self->[\$i][\$j]; \$line2+=\$self->[\$j][\$i]; } if (\$line1 != \$sum || \$line2 != \$sum) { # This isn't a Magic return(0); } } # Check diagonals and broken diagonals for (\$j=0;\$j<\$len;\$j++) { \$i=0; \$diag1=0; \$diag2=0; for (\$i=0;\$i<\$len;\$i++) { \$diag1+=\$self->[\$i][(\$i+\$j)%\$len]; \$diag2+=\$self->[\$len-1-\$i][(\$i+\$j)%\$len]; } if (\$j == 0) { if (\$diag1 != \$sum || \$diag2 != \$sum) { # This is a Semimagic Square return(1); } } else { if (\$diag1 != \$sum || \$diag2 != \$sum) { # This is a Magic Square return(2); } } } # This is a Panmagic Square return(3); } sub print { my \$self = shift; my \$initialtext = shift; my \$i=0; my \$j=0; my \$len = scalar(@{\$self}); print "\$initialtext\n" if \$initialtext; print @_ if scalar(@_); for (\$j=0;\$j<\$len;\$j++) { for (\$i=0;\$i<\$len;\$i++) { printf "%5d ", \$self->[\$j][\$i]; } print "\n"; } } sub printhtml { my \$self = shift; my \$i=0; my \$j=0; my \$len = scalar(@{\$self}); print qq!\n!; for (\$j=0;\$j<\$len;\$j++) { print "\n"; for (\$i=0;\$i<\$len;\$i++) { print "\n"; } print "\n"; } print "
 \$self->[\$j][\$i]