Number Spiral (#109)

On 1/15/07, Matthew M. [email protected] 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. =)

Here is one that uses an empirical algorithm but with an array (Saw the
constraint a little late) . Uses :clock or :counter parameter to print
either spiral.

class Array
def cnext
@p ||= -1
@p += 1
@p = 0 if @p == self.length
self[@p]
end
end

class ClockState
def initialize
@seq = [:left, :up, :right, :down]
@count = 1
@count_state = 0
@times = 0
@val = @seq.cnext
end

def next
if @count == @count_state
@val = @seq.cnext
@count_state = 0
@times += 1
if @times == 2
@count += 1
@times = 0
end
end
@count_state += 1
@val
end
end

class Spiral
def initialize(dim)
@m = []
dim.times do
@m << Array.new(dim, 0)
end
@x = dim/2
@y = dim/2
@val = 0
@sz = dim
end

def left
@x -= 1
end

def up
@y -= 1
end

def right
@x += 1
end

def down
@y +=1
end

def make_spiral dir_hash={:dir=>:clock}
c = ClockState.new
while ((@x < @sz) && (@y < @sz))
if dir_hash[:dir]==:counter
@m[@x][@y] = @val
elsif dir_hash[:dir]==:clock
@m[@y][@x] = @val
else
raise “Legal values are :clock and :counter”
end
self.send(c.next)
@val += 1
end
end

def print_spiral
fmt_sz = (@sz*@sz).to_s.length + 2
for i in 0…@sz do
print “\n”
for j in 0…@sz do
printf("%#{fmt_sz}d", @m[i][j])
end
end
end
end

s = Spiral.new(20)
s.make_spiral :dir=>:clock
s.print_spiral

#—

William J. wrote:


with this solution and of course you will start to feel ill and

I can’t get this to work.

E:\Ruby>ruby try.rb
4 4
try.rb:2:in %': too few arguments. (ArgumentError) from try.rb:2 from try.rb:2:inmap’
from try.rb:2

irb(main):006:0> s=1; x=5; [*s…s+x]
=> [1, 2, 3, 4, 5]
irb(main):007:0> s=1; x=5; [*s…s+=x]
=> []
irb(main):009:0> s=1; x=5; s…s+=x
=> 6…6

My first submission to Ruby Q.:

n = ARGV[0].to_i

pass this method two coordinates relative to the center of the spiral

def spiral(x, y)
max_xy = [x,y].collect{|num| num.abs}.max
offset = (max_xy * 2 - 1)**2 - 1

if -(x) == max_xy and x != y
y + offset + max_xy
elsif y == max_xy
x + offset + (3 * max_xy)
elsif x == max_xy
-y + offset + (5 * max_xy)
elsif -(y) == max_xy
-x + offset + (7 * max_xy)
end
end

for row in 0…(n - 1)

the ease of writing one-liners in ruby lends itself to abuse…

puts (0…(n - 1)).map{|col| spiral(col - (n / 2), (n / 2) -
row).to_s.rjust(4) }.join
end

On 1/15/07, Martin DeMello [email protected] wrote:

n = ARGV[0].to_i
square = Array.new(n+2) { Array.new(n+2) }

oops - didn’t read the question carefully enough. ignore.

m.

I can’t get this to work.

Hmm.

=> []
irb(main):009:0> s=1; x=5; s…s+=x
=> 6…6

Interesting:

C:\development>ruby -v -e “s=1; x=5; p s…s+=x”
ruby 1.8.5 (2006-08-25) [i386-mswin32]
1…6

cheers

Simon