# Number Spiral (#109)

**URL:** https://rubytalk.org/t/number-spiral-109/34453
**Category:** ruby-talk
**Created:** [14 January 2007 19:46 UTC](https://rubytalk.org/t/number-spiral-109/34453 "2007-01-14T19:46:15Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Tom\_Ayerst](https://avatars.discourse-cdn.com/v4/letter/t/13edae/32.png) [@Tom\_Ayerst](https://rubytalk.org/u/Tom_Ayerst)
#### Post date: [14 January 2007 19:46 UTC](https://rubytalk.org/t/number-spiral-109/34453/1 "2007-01-14T19:46:15Z")

</div>

My answers assumes an odd numbered spirals (I inferred it from "The number zero represents the center of the spiral").

Sorry for my beginners ruby (are there some standard min(x,y)/max(x,y,) functions?)

The approach is to work out a standard equation for the value in any cell (I ended up with two, for the top left and bottom right) and then to iterate through each cell and calculate the value. The algorithm is stateless.

class SpiralMaker  
&nbsp;&nbsp;def make\_spiral(size)  
&nbsp;&nbsp;&nbsp;&nbsp;# only allow odd numbered squares (as zero is centre)  
&nbsp;&nbsp;&nbsp;&nbsp;if (size.modulo(2) == 0)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1)  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#step along row  
&nbsp;&nbsp;&nbsp;&nbsp;(1..size).each do |y|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# step down columns  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1..size).each do |x|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# are we in top left or bottom right half of spiral? if (y+x \<= size) # top left - calculate value  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sn = size - (2 \* (min(x,y) - 1))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;val = (sn\*sn) - (3\*sn) + 2 - y + x  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else # bottom right - calculate value sn = size - (2 \* (size - max(x,y)))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;val = (sn\*sn) - sn + y - x  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Print value  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STDOUT.printf "%03d ", val  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Next line  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STDOUT.print "\n"  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;def min(a,b)  
&nbsp;&nbsp;&nbsp;&nbsp;(a \<= b) ? a : b  
&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;def max(a,b)  
&nbsp;&nbsp;&nbsp;&nbsp;(a \>= b) ? a : b  
&nbsp;&nbsp;end  
end

maker = SpiralMaker.new  
maker.make\_spiral 21

---

<div class="post-metadata">

### Author: ![Daniel\_Finnie1](https://avatars.discourse-cdn.com/v4/letter/d/4af34b/32.png) [@Daniel\_Finnie1](https://rubytalk.org/u/Daniel_Finnie1)
#### Post date: [14 January 2007 22:42 UTC](https://rubytalk.org/t/number-spiral-109/34453/2 "2007-01-14T22:42:16Z")

</div>

I think the standard idiom is to use the min/max functions of an array:

a = 5  
b = 10  
[a, b].max #=\> 10

You can also give max a block, similar to sort:

a = "Hello"  
b = "Hi"  
[a, b].max {|x, y| x.length \<=\> y.length}

Or you can write a method so it works more like sort\_by (the interface, not the implementation):

class Array  
&nbsp;&nbsp;&nbsp;&nbsp;def max\_by &blk  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max {|a, b| blk.call(a) \<=\> blk.call(b)}  
&nbsp;&nbsp;&nbsp;&nbsp;end  
end

a = "Hello"  
b = "Hi"  
[a, b].max {|x| x.length}

And then, in Ruby 1.9, you should be able to do this (using max\_by from above):

a = "Hello"  
b = "Hi"  
[a, b].max(&:length) # Not sure if the syntax is 100%

And if you still want your max() function:

def min(\*args)  
&nbsp;&nbsp;&nbsp;args.min  
end

Everything also applies to minimums using the min function.

Dan

Tom Ayerst wrote:

> **···**
>
> > Sorry for my beginners ruby (are there some standard min(x,y)/max(x,y,) functions?

---

<div class="post-metadata">

### Author: ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)
#### Post date: [15 January 2007 21:15 UTC](https://rubytalk.org/t/number-spiral-109/34453/3 "2007-01-15T21:15:46Z")

</div>

But the quiz example is an even spiral. 😉

James Edward Gray II

> **···**
>
> 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").

---

<div class="post-metadata">

### Author: ![Tom\_Ayerst](https://avatars.discourse-cdn.com/v4/letter/t/13edae/32.png) [@Tom\_Ayerst](https://rubytalk.org/u/Tom_Ayerst)
#### Post date: [16 January 2007 22:26 UTC](https://rubytalk.org/t/number-spiral-109/34453/4 "2007-01-16T22:26:16Z")

</div>

This one works for even and odd spirals (obvious really)

class SpiralMaker  
&nbsp;&nbsp;def make\_spiral(square\_size)  
&nbsp;&nbsp;&nbsp;&nbsp;# allow for even numbered squares by missing off the last row and column  
&nbsp;&nbsp;&nbsp;&nbsp;size = square\_size  
&nbsp;&nbsp;&nbsp;&nbsp;if (square\_size.modulo(2) == 0)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;square\_size = square\_size+1  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#step along row  
&nbsp;&nbsp;&nbsp;&nbsp;(1..size).each do |y|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# step down columns  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1..size).each do |x|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# are we in top left or bottom right half of spiral? if (y+x \<= square\_size) # top left - calculate value  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sn = square\_size - (2 \* (min(x,y) - 1))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;val = (sn\*sn) - (3\*sn) + 2 - y + x  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else # bottom right - calculate value sn = square\_size - (2 \* (square\_size - max(x,y)))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;val = (sn\*sn) - sn + y - x  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Print value  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STDOUT.printf "%03d ", val  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Next line  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STDOUT.print "\n"  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;def min(a,b)  
&nbsp;&nbsp;&nbsp;&nbsp;(a \<= b) ? a : b  
&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;def max(a,b)  
&nbsp;&nbsp;&nbsp;&nbsp;(a \>= b) ? a : b  
&nbsp;&nbsp;end  
end

maker = SpiralMaker.new  
maker.make\_spiral 3

> **···**
>
> >
