[QUIZ] Number Spiral (#109)

My first submission to Ruby Quiz:

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

Simon Kröger wrote:

Dear Ruby Quiz,

this isn't really a solution to the quiz 109 because it violates
some (if not all) of the rules. But as James noted there was a
code golf problem very similar to this quiz and here is my
solution to that.
(see http://codegolf.com/oblongular-number-spirals for detailed
description of the code golf problem)

----------------------------------------------------------------
s,f=1,proc{|x,y|y<1?:[[*s...s+=x]]+f[y-1,x].reverse.transpose}

This is more obfuscated than

s=1
f=proc{|x,y|y<1?:[[*s...s+=x]]+f[y-1,x].reverse.transpose}

and is no shorter.

puts f[w=gets(' ').to_i,gets.to_i].map{|i|['%3i']*w*' '%i}
----------------------------------------------------------------

It draws a number spiral, starting with '1' in the upper left
corner and the highest number in the middle, it also features
spirals that are not quadratic.

Yes, you will get some score at the codegolf site if you repost
this solution there

If the site accepted this, then it wasn't tested thoroughly
enough. '%3i' gives every number-spiral a column-width
of 3; the column-width should equal the width of the
largest number.

William James wrote:

Simon Kröger wrote:
> Dear Ruby Quiz,
>
> this isn't really a solution to the quiz 109 because it violates
> some (if not all) of the rules. But as James noted there was a
> code golf problem very similar to this quiz and here is my
> solution to that.
> (see http://codegolf.com/oblongular-number-spirals for detailed
> description of the code golf problem)
>
> ----------------------------------------------------------------
> s,f=1,proc{|x,y|y<1?:[[*s...s+=x]]+f[y-1,x].reverse.transpose}
> puts f[w=gets(' ').to_i,gets.to_i].map{|i|['%3i']*w*' '%i}
> ----------------------------------------------------------------
>
> It draws a number spiral, starting with '1' in the upper left
> corner and the highest number in the middle, it also features
> spirals that are not quadratic.
>
> Yes, you will get some score at the codegolf site if you repost
> this solution there - but nowadays you will only get to Rank 9
> with this solution and of course you will start to feel ill and
> you won't be able to sleep for days and other nasty things might
> happen if you do so.
>
> If someone can derive an even shorter solution from this i would
> be very interested to see it (the best ruby solution today has 7
> bytes less)
>
> cheers
>
> Simon

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:in `map'
        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

Welcome and thanks for sharing.

James Edward Gray II

···

On Jan 17, 2007, at 2:31 PM, Krishna Dole wrote:

My first submission to Ruby Quiz:

William James wrote:

s,f=1,proc{|x,y|y<1?:[[*s...s+=x]]+f[y-1,x].reverse.transpose}

This is more obfuscated than

s=1
f=proc{|x,y|y<1?:[[*s...s+=x]]+f[y-1,x].reverse.transpose}

and is no shorter.

depends on your line end character(s) :slight_smile:

puts f[w=gets(' ').to_i,gets.to_i].map{|i|['%3i']*w*' '%i}
----------------------------------------------------------------

It draws a number spiral, starting with '1' in the upper left
corner and the highest number in the middle, it also features
spirals that are not quadratic.

Yes, you will get some score at the codegolf site if you repost
this solution there

If the site accepted this, then it wasn't tested thoroughly
enough. '%3i' gives every number-spiral a column-width
of 3; the column-width should equal the width of the
largest number.

Well, consider it cheating, most spirals have a column width of
3 - so you may have to post it twice to have it accepted.

cheers

Simon

I can't get this to work.

Hmm.

E:\Ruby>ruby try.rb
4 4
try.rb:2:in `%': too few arguments. (ArgumentError)
        from try.rb:2
        from try.rb:2:in `map'
        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

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

Simon Kröger wrote:

William James wrote:
>> s,f=1,proc{|x,y|y<1?:[[*s...s+=x]]+f[y-1,x].reverse.transpose}
>
> This is more obfuscated than
>
> s=1
> f=proc{|x,y|y<1?:[[*s...s+=x]]+f[y-1,x].reverse.transpose}
>
> and is no shorter.

depends on your line end character(s) :slight_smile:

Only if you're under windoze and you neglect to remove
the carriage-returns before uploading. Using vile, for example,
I do :set-unix-mode and save before uploading. If you're not
doing this, then you are really hurting your score.

By the way, in the ASCII Art contest I got the size
down to 76. I would pay to see how "flagitious" did it
in 71 bytes!

>> puts f[w=gets(' ').to_i,gets.to_i].map{|i|['%3i']*w*' '%i}
>> ----------------------------------------------------------------
>>
>> It draws a number spiral, starting with '1' in the upper left
>> corner and the highest number in the middle, it also features
>> spirals that are not quadratic.
>>
>> Yes, you will get some score at the codegolf site if you repost
>> this solution there
>
> If the site accepted this, then it wasn't tested thoroughly
> enough. '%3i' gives every number-spiral a column-width
> of 3; the column-width should equal the width of the
> largest number.

Well, consider it cheating, most spirals have a column width of
3 - so you may have to post it twice to have it accepted.

The site really should do more thorough testing.

Simon Kröger wrote:

>> I can't get this to work.

Hmm.

>> E:\Ruby>ruby try.rb
>> 4 4
>> try.rb:2:in `%': too few arguments. (ArgumentError)
>> from try.rb:2
>> from try.rb:2:in `map'
>> 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

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

E:\Ruby>ruby -v
ruby 1.8.2 (2004-12-25) [i386-mswin32]

So it seems that this won't work without modification under 1.8.2.

As for making it shorter,
  change
puts f[w=gets(' ').to_i,gets.to_i].map{|i|['%3i']*w*' '%i}
  to
puts f[w=gets.to_i,$_[-3,2].to_i].map{|i|"%3d "*w%i}

An invisible extra space is printed at the end of each line.

William James wrote:

E:\Ruby>ruby -v
ruby 1.8.2 (2004-12-25) [i386-mswin32]

So it seems that this won't work without modification under 1.8.2.

As for making it shorter,
  change
puts f[w=gets(' ').to_i,gets.to_i].map{|i|['%3i']*w*' '%i}
  to
puts f[w=gets.to_i,$_[-3,2].to_i].map{|i|"%3d "*w%i}

An invisible extra space is printed at the end of each line.

It may be invisible but it will void your solution on codegolf.com.

cheers

Simon