From: James Edward Gray II on 15 Jan 2007 16:15 On Jan 14, 2007, at 1:46 PM, Tom Ayerst wrote: > My answers assumes an odd numbered spirals (I inferred it from "The > number zero represents the center of the spiral"). But the quiz example is an even spiral. ;) James Edward Gray II
From: Bob Showalter on 15 Jan 2007 18:24 Here's the solution I came up with before submitting this idea: # spiral.rb # RubyQuiz #109 # Bob Showalter class Integer def odd? self % 2 == 1 end end class Spiral # order must be > 0 def initialize(order) raise ArgumentError, "order must be > 0" unless order.to_i > 0 @order = order end # writes the spiral to stdout def output puts "\n" 0.upto(@order - 1) do |r| row_for(@order, r) puts "\n\n" end end private # emits row r for spiral of order p def row_for(p, r) if p <= 1 cell(0) elsif p.odd? if r == p - 1 row(p) else row_for(p - 1, r) col(p, r) end else if r == 0 row(p) else col(p, r) row_for(p - 1, r - 1) end end end # emits the full row (top or bottom) for spiral of order p def row(p) x = p * (p - 1) y = x + p - 1 x.upto(y) {|i| cell(p.odd? ? x - i + y : i) } end # emits the single column cell for row r of spiral of order p def col(p, r) x = p * (p - 1) r = p - r - 1 if p.odd? cell(x - r) end # emits a single cell def cell(i) printf ' %3d ', i end end n = (ARGV.first || 3).to_i Spiral.new(n).output
From: Matthew Moss on 15 Jan 2007 19:00 My second attempt/solution... Slightly different in that it does a counter-clockwise spiral, but basically follows a similar idea as my previous solution, though I think this looks nicer. N = ARGV[0].to_i FW = (N ** 2 - 1).to_s.size + 2 def fmt(x) " " * (FW - x.to_s.size) + x.to_s end def o(n, r, c) x = (n - 1) ** 2 if c == 0 then x + r elsif r == n - 1 then x + r + c else e(n - 1, r, c - 1) end end def e(n, r, c) x = (n ** 2) - 1 if r == 0 then x - c elsif c == n - 1 then x - c - r else o(n - 1, r - 1, c) end end def spiral(n) (0...n).map do |r| if (n % 2).zero? # even (0...n).map { |c| fmt(e(n, r, c)) } else (0...n).map { |c| fmt(o(n, r, c)) } end.join end.join("\n") end puts spiral(N)
From: Matthew Moss on 15 Jan 2007 19:10 On 1/15/07, Matthew Moss <matthew.moss.coder(a)gmail.com> wrote: > My second attempt/solution... Slightly different in that it does a > counter-clockwise spiral, but basically follows a similar idea as my > previous solution, though I think this looks nicer. Looking at the website, it seems like Eric I and I came up with similar solutions, but I'll say he wins, because his solution looks better, arrived first, and uses rjust. =)
From: Tom Ayerst on 16 Jan 2007 17:26
This one works for even and odd spirals (obvious really) class SpiralMaker def make_spiral(square_size) # allow for even numbered squares by missing off the last row and column size = square_size if (square_size.modulo(2) == 0) square_size = square_size+1 end #step along row (1..size).each do |y| # step down columns (1..size).each do |x| # are we in top left or bottom right half of spiral? if (y+x <= square_size) # top left - calculate value sn = square_size - (2 * (min(x,y) - 1)) val = (sn*sn) - (3*sn) + 2 - y + x else # bottom right - calculate value sn = square_size - (2 * (square_size - max(x,y))) val = (sn*sn) - sn + y - x end # Print value STDOUT.printf "%03d ", val end # Next line STDOUT.print "\n" end end def min(a,b) (a <= b) ? a : b end def max(a,b) (a >= b) ? a : b end end maker = SpiralMaker.new maker.make_spiral 3 > |