Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
package Math::MagicSquare::Generator; use strict; use Carp; use vars qw($VERSION); $VERSION = '0.01'; sub _sum { my $sum = 0; $sum += $_ for @_; return $sum } sub new { my ($class, %opt) = @_; $opt{size} ||= 5; $opt{start} ||= 1; $opt{step} ||= 1; croak "Size needs to be a positive, odd integer" unless $opt{size} > 0 and $opt{size} % 2 and $opt{size} == int($opt{size}); my $self = [ map { [ (undef) x $opt{size} ] } 1..$opt{size} ]; my $value = $opt{start}; my $halv = int(@$self / 2); for my $start_x (-$halv..$halv) { my $x = $start_x - 1; my $y = $x + @$self + 1; for (1 .. @$self) { $x = $x - @$self if ++$x > $#$self; $y = $y - @$self if --$y > $#$self; $self->[$y][$x] = $value; $value += $opt{step}; } } return bless $self, $class; } sub hflip { my ($self) = @_; my $clone; push @$clone, [ reverse @$_ ] for @$self; return bless $clone, ref $self; } sub vflip { my ($self) = @_; my $clone; push @$clone, [ @$_ ] for reverse @$self; return bless $clone, ref $self; } sub sum { my ($self) = @_; return _sum( @{ $self->[0] } ); } sub check { my ($self) = @_; my $sum = $self->sum; # Horizontals for (@$self[1..$#$self]) { return undef if @$_ > @$self; # undef if not square return undef if _sum(@$_) != $sum; } # Verticals for my $x (0..$#$self) { return undef if _sum(map $self->[$_][$x], 0..$#$self) != $sum; } # Diagonals return undef if _sum(map $self->[$_][$_], 0..$#$self) != + $sum; return undef if _sum(map $self->[$#$self - $_][$_], 0..$#$self) != + $sum; # Duplicates my %seen; $seen{$_}++ for map @$_, @$self; return undef if _sum(values %seen) != keys %seen; # Passed all tests! return $sum; } sub as_string { my ($self) = @_; my $max = 0; length > $max and $max = length for map @$_, @$self; return map { join(' ', map {' 'x($max - length) . $_} @$_) . "\n" +} @$self; } sub as_html { my ($self) = @_; return "<table>\n" . join("\n", map { '<tr><td>' . join('</td><td>', @$_) . '</td></tr>' } @$s +elf) . "\n</table>\n"; } sub as_csv { my ($self) = @_; return join("\n", map { join ',', @$_ } @$self) . "\n"; } 1; __END__ =head1 NAME Math::MagicSquare::Generator - Magic Square Generator =head1 SYNOPSIS use Math::MagicSquare::Generator my $square = Math::MagicSquare::Generator->new(size => 5, step => 3, start=> 6); for ($square, $square->vflip, $square->hflip) { print $_->as_string; print "-----\n"; } $square->[0][0] = -15; # Break magic :) print $square->check ? "Magic square\n" : "Just a square\n"; print '<html><body>'; print Math::MagicSquare::Generator->new->hflip->vflip->as_html; print '</body></html>'; =head1 DESCRIPTION This module creates magic squares. A magic square is a square in which all numbers are different and the sums of all rows, all columns and the two diagonals are equal. Math::MagicSquare::Generator cannot create panmagic squares, or square +s that have an even size. (A panmagic square is magic square where the "wrapped" diagonals are also equal.) =head1 EXAMPLE 3 16 9 22 15 This square is the output of 20 8 21 14 2 print Math::MagicSquare::Generator->new->as_string +; 7 25 13 1 19 24 12 5 18 6 11 4 17 10 23 The sums of the rows are 65. The sums of the columns are 65. The sums of the diagonals are 65. =head1 METHODS =over 10 =item new The constructor that generates the square immediately. It creates an object using the given named arguments. Valid arguments are C<size>, C<step> and C<start>. C<size> has to be positive, odd and integer. =item check A checker - returns the common sum if the square is magic, or undef if it's not. Because the sum can never be 0, you can use this as a boolea +n value. (Well, the sum in a 1x1 square can be 0, if the single number i +s 0.) You can use this method to check if the square has been tampered w +ith. =item sum Returns the common sum of the rows, columns and diagonals. =item vflip, hflip These methods return a vertically or horizontally flipped clone of the square. The clone is a Math::MagicSquare::Generator, so stacking these methods is possible. =item as_string, as_html, as_csv DWYM - return the square as a formatted string, piece of html or in CSV format. =back =head1 THIS MODULE AND Math::MagicSquare Math::MagicSquare is a module that checks if a square is magical. It takes a list in its C<new> method, so you'll have to dereference the generated square: use Math::MagicSquare; use Math::MagicSquare::Generator; my $square = Math::MagicSquare::Generator->new; print Math::MagicSquare->new( @$square )->check, "\n"; # 2 Its C<check> will always return 2 for squares generated using this module (or 3 if it's a 1x1 square. =head1 KNOWN BUGS None yet. =head1 AUTHOR Juerd <juerd@juerd.nl> =cut

In reply to Math::MagicSquare::Generator by Juerd

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others pondering the Monastery: (4)
    As of 2014-11-22 21:50 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      My preferred Perl binaries come from:














      Results (125 votes), past polls