From: "Ball, Donald A Jr (Library)" Date: 2007-05-21T03:28:32+09:00 Subject: Re: [QUIZ] Magic Squares (#124) ------_=_NextPart_001_01C79B0C.A7182637 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable This is my solution. It only does odd magic squares, but it can generate = all eight versions (assuming there are only eight. It seemed that way to = me.) http://pastie.caboo.se/63130 - donald # Ruby Quiz 124 # Donald Ball # version 1.0 class MagicSquare SLANTS =3D [-1, 1] STARTS =3D [:top, :bottom, :left, :right] def initialize(n, slant=3DSLANTS[rand(SLANTS.length)], = start=3DSTARTS[rand(STARTS.length)]) raise ArgumentError unless n > 0 && (n % 2) =3D=3D 1 raise ArgumentError unless SLANTS.include?(slant) raise ArgumentError unless STARTS.include?(start) @n =3D n @sum =3D (@n**3 + @n) / 2 @values =3D Array.new(@n**2) if start =3D=3D :top || start =3D=3D :bottom c =3D @n / 2=20 dc =3D slant ddc =3D 0 if start =3D=3D :top r =3D 0 dr =3D -1 ddr =3D 1 else r =3D -1 dr =3D 1 ddr =3D -1 end else r =3D @n / 2 dr =3D slant ddr =3D 0 if start =3D=3D :left c =3D 0 dc =3D -1 ddc =3D 1 else c =3D -1 dc =3D 1 ddc =3D -1 end end (1..@n).each do |i| (1..@n).each do |j| self[r, c] =3D @n*(i-1) + j unless j=3D=3D@n r +=3D dr c +=3D dc else r +=3D ddr c +=3D ddc end end end end def offset(r, c) (r % @n) * @n + (c % @n) end def [](r, c) @values[offset(r, c)] end def []=3D(r, c, v) @values[offset(r, c)] =3D v end def range (0..@n-1) end def col(c) range.map {|r| @values[c + r*@n]} end def cols range.map {|c| col(c)} end def row(r) @values[r*@n, @n] end def rows range.map {|r| row(r)} end def diagonals [range.map {|i| @values[i*(@n+1)]}, range.map {|i| = @values[(@n-1)*(i+1)]}] end def valid? (rows + cols + diagonals).each do |chunk| return false unless chunk.inject {|sum, v| sum +=3D v} =3D=3D @sum end true end def to_s def ojoin(a, sep) sep + a.join(sep) + sep end l =3D (@n**2).to_s.length sep =3D "+#{'-'*(@n*(l+2) + (@n-1))}+\n" ojoin(rows.map {|row| ojoin(row.map {|v| sprintf(" %#{l}d ", v)}, = '|') + "\n"}, sep) end end if $0 =3D=3D __FILE__ puts MagicSquare.new(ARGV[0].to_i) if ARGV.length =3D=3D 1 end ------_=_NextPart_001_01C79B0C.A7182637--