--Apple-Mail-1--496755143 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset -ASCII; format竟wed Begin forwarded message: > From: Hirotsugu Asari <asari / mac.com> > Date: May 19, 2007 6:57:27 PM CDT > To: submission / rubyquiz.com > Subject: Please Forward: Ruby Quiz Submission > > Here's my solution and the tests. > --Apple-Mail-1--496755143 Content-Transfer-Encoding: 7bit Content-Type: text/x-ruby-script; x-unix-mode44; x-mac-creatorT784D74; name gic_square.rb Content-Disposition: attachment; filename gic_square.rb #!/usr/bin/env ruby -wKU # Ruby Quiz #124 # Magic Square -- build an NxN magic square require 'matrix' class Matrix def magic? return false if ! self.square? size elf.row_size # compute the sum of each row, each column and the diagonals magic_sum 1..size**2).inject{ |s,i| s + } / size begin # checks rows and columns self.row_vectors.each { |v| if v.to_a.inject { |s,i| s + } ! agic_sum raise RuntimeError, "row #{v} doesn't add up to #{magic_sum}" end } self.column_vectors.each { |v| if v.to_a.inject { |s,i| s + } ! agic_sum raise RuntimeError, "column #{v} doesn't add up to #{magic_sum}" end } # check diagonals if (0..size-1).inject(0) {|s,i| s + elf[i,i] } ! agic_sum raise RuntimeError, "the main diagonal doesn't add up to #{magic_sum}" end # finally.... check the other main diagonal if (0..size-1).inject(0) {|s,i| s + elf[i, -1-i] } ! agic_sum raise RuntimeError, "the other diagonal doesn't add up to #{magic_sum}" end rescue return false end # it passed all checks return true end def to_s_pretty if ! self.square? return self.to_s end array elf.to_a max_length rray.flatten.sort.last.to_s.length # the length of the largest number to fit in s " until array.empty? do row rray.shift s + +" + "-" * ((max_length+2)*row.length + row.length-1) + "+\n" s + | " + row.map{ |i| i.to_s.rjust(max_length) }.join(" | ") + " |\n" end s + +" + "-" * ((max_length+2)*row.length + row.length-1) + "+" end # See <http://mathworld.wolfram.com/MagicSquare.html> def Matrix.new_magic_square(n0 n .to_i if n 2 raise ArgumentError, "2x2 magic square does not exist" elsif n < 1 raise ArgumentError, "Cannot create a magic square of size #{n}" end if n % 2 ! return Matrix.new_odd_magic_square(n) elsif n % 4 0 return Matrix.new_doubly_even_magic_square(n) else return Matrix.new_singly_even_magic_square(n) end end private def Matrix.new_odd_magic_square(n) if ! n.integer? || n%2 ! raise RuntimeError, "Internal error on line #{__LINE__}" end # generate the NxN magic square by the Siamese method a ] 0.upto(n-1) { |i| a[i] } m n-1)/2 # put 1 in a[0][m], then 2 goes to a[-1][m+1], 3 to a[-2][m+2], ... x y 1.upto(n**2) { |i| if (a[x][y]).nil? a[x][y] else # this cell is already filled, so we move to the cell below; we had # already moved to the upper right cell, so we must offset that move, too x + y - a[x%n][y%n] end x x-1)%n # move up y y+1)%n # then right } Matrix.rows(a) end def Matrix.new_doubly_even_magic_square(n) if ! n.integer? || n%4 ! raise RuntimeError, "Internal error on line #{__LINE__}" end # first fill the cells in order a 1.upto(n) do |i| first i-1)*n+1 # first element a << (first..(first+n-1)).to_a end # then replace the entries 0.upto(n-1) do |i| 0.upto(n-1) do |j| if (i-j)%4 0 || (i+j)%4 3 a[i][j] **2+1-a[i][j] end end end Matrix.rows(a) end def Matrix.new_singly_even_magic_square(n) if ! n.integer? || n%4 ! raise RuntimeError, "Internal error on line #{__LINE__}" end # first generate the magic square of size n/2 m n-2)/4 matrix atrix.new_odd_magic_square(2*m+1).to_a lux # identifier for "L,U,X" for each 4x4 squares # m+1 rows of L's 1.upto(m+1) do |i| lux << (1..(2*m+1)).to_a.map{"L"} end # 1 row of U's lux << (1..(2*m+1)).to_a.map{"U"} # m-1 rows of X's 1.upto(m-1) do |i| lux << (1..(2*m+1)).to_a.map{"X"} end # swap an L and a U as required by the method lux[m][m] " lux[m+1][m] " # finally, fill up the cells a ] 0.upto(n-1) do |i| a[i] 0.upto(n-1) do |j| k /2 l /2 case when lux[k][l] "L" # 4 1 # 2 3 if i%2 0 if j%2 0 a[i][j] atrix[k][l]-1)*4+4 else a[i][j] atrix[k][l]-1)*4+1 end else if j%2 0 a[i][j] atrix[k][l]-1)*4+2 else a[i][j] atrix[k][l]-1)*4+3 end end # end of case "L" when lux[k][l] "U" # 1 4 # 2 3 if i%2 0 if j%2 0 a[i][j] atrix[k][l]-1)*4+1 else a[i][j] atrix[k][l]-1)*4+4 end else if j%2 0 a[i][j] atrix[k][l]-1)*4+2 else a[i][j] atrix[k][l]-1)*4+3 end end # end of case "U" when lux[k][l] "X" # 1 4 # 3 2 if i%2 0 if j%2 0 a[i][j] atrix[k][l]-1)*4+1 else a[i][j] atrix[k][l]-1)*4+4 end else if j%2 0 a[i][j] atrix[k][l]-1)*4+3 else a[i][j] atrix[k][l]-1)*4+2 end end # end of case "X" else raise RuntimeError, "Internal error on line #{__LINE__}" end end end return Matrix.rows(a) end end --Apple-Mail-1--496755143 Content-Transfer-Encoding: 7bit Content-Type: text/x-ruby-script; x-unix-mode44; x-mac-creatorT784D74; name4_test.rb Content-Disposition: attachment; filename4_test.rb #!/usr/bin/env ruby -wKU require "test/unit" require "magic_square.rb" class MagicSquareTest < Test::Unit::TestCase def test_magicness # here's a magic square of size 5 m atrix[ [15, 8, 1,24,17], [16,14, 7, 5,23], [22,20,13, 6, 4], [ 3,21,19,12,10], [ 9, 2,25,18,11] ] assert m.magic? # here's another m atrix[ [19,21, 3,10,12], [25, 2, 9,11,18], [ 1, 8,15,17,24], [ 7,14,16,23, 5], [13,20,22, 4, 6] ] assert m.magic? # one of size 9 m atrix[ [45,34,23,12, 1,80,69,58,47], [46,44,33,22,11, 9,79,68,57], [56,54,43,32,21,10, 8,78,67], [66,55,53,42,31,20,18, 7,77], [76,65,63,52,41,30,19,17, 6], [ 5,75,64,62,51,40,29,27,16], [15, 4,74,72,61,50,39,28,26], [25,14, 3,73,71,60,49,38,36], [35,24,13, 2,81,70,59,48,37] ] assert m.magic? end def test_exceptions assert_raise ArgumentError do m atrix.new_magic_square(2) end assert_raise ArgumentError do m atrix.new_magic_square(-1) end end def test_generator assert_equal Matrix.new_magic_square(1), Matrix[[1]] 3.upto(100) do |n| s rocess.times m atrix.new_magic_square(n) t rocess.times # puts sprintf("size: %10d generated in utime: %8.2f\tstime: %8.2f", n, t.utime-s.utime, t.stime-s.stime) assert m.magic? u rocess.times # puts sprintf("size: %10d tested in utime: %8.2f\tstime: %8.2f", n, u.utime-t.utime, u.stime-t.stime) end end end --Apple-Mail-1--496755143 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset -ASCII; delspサ 竟 セ セ ノ コッッョョッヘモョ セ ョ セ セ ヤ テイト ヘツ ミ ョ セ セ 、 ゜゜ョ セ ァ゜ァ セ セ ヘョ゜゜ィチメヌヨローンゥョ゜゜ セ セ 、 ゜゜ョ ケ セ ォュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュォ セ エキ オク カケ クー ア アイ イウ ウエ エオ セ ォュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュォ セ オキ カク キケ ケ アア イイ ウウ エエ エカ セ ォュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュォ セ カキ キク ク アー イア ウイ エウ オエ オカ セ ォュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュォ セ キキ キ アク イー ウア エイ オウ オオ カカ セ ォュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュォ セ カ アキ アケ ウー エア オイ カウ カオ キカ セ ォュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュォ セ アカ イキ イケ エー オア カイ カエ キオ オ セ ォュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュォ セ イカ イク ウケ オー カア キイ キエ エ アオ セ ォュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュォ セ ウカ ウク エケ カー キア キウ ウ アエ イオ セ ォュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュォ セ ウキ エク オケ キー クア イ アウ イエ ウオ セ ォュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュォ セ セ ーーョーアキ セ ーーョーアー セ ーーョーーキ セ セ 、 イケク ウーーサ セ セ ゜゜ョ 、 セ ッッ セ セ セ セ ーアョオアウ セ ーアョーーカ セ ーーョオーオ セ セ ーアョウエエ セ ーーョクウカ セ ーーョオーカ ュュチュヘュアュュエケカキオオアエウュュ