Printing numbers in a spiral ( in Ruby )

Printing numbers in a spiral ( in Ruby )

=begin

Have a look at the above representation of the array. 
This is how the numbers should print spirally.

The first array is of the size 3X3. The second is 5X5. 

This would mean, for the 5X5 matrix - to fill all the spaces 
of the topmost row (5 places) , take a turn (T) , then fill up all 
the available places on the leftmost column (4 places) , going down. 
Turn (T). Then filling up the free spaces on the bottom row (4 places) , 
going backwards. Turn (T).Then fill the free spaces of the leftmost 
column going up (3 places). Turn (T). Fill up the available spaces in 
the 2nd row (3 places). Do work out the rest of the place filling the 
same way.  

5 - T - 4 - T - 4 - T - 3 - T - 3 - T - 2 - T - 2 - T - 1 - T - 1.

Similarly, considering a 4X4 matrix filled similarly, the way the places 
would be filled are 4 - T - 3 - T - 3 - T - 2 - T - 2 - T - 1 - T - 1.

Generalising, this would be summarised as. for filling up a matrix of 
n length, first fill up n rows i nthe first row. then turn. fill up 
n-1 places, turn. fill up n-1 places again. turn and fill up n-2 
places. twice. Repeat till you decrease number of places to 0, 
thats when you stop. 

This brings us to the next question....how does one calculate the exact 
array positions? Since there will be 4 kinds of turns:


1. Going right. 
   X is steady since we are going in the same secondary array. 
   Y is incrementing. 
   so our calculating array for this would be [0,1]
2. Going down . 
   X is increamenting since we are going to fill the 
      same index in succeeding arrays. 
   Y is steady. 
   so our calculating array for this would be [1,0].
3. Going left . 
   X is steady. 
   Y is decrementing. 
   So our calculating array for this would be [0,-1].
4. Going up.
   X is decrementing. 
   Y is steady. 
   So our calculating array for this would be [-1,0].

From the above cases, we can get the correct row and column position.

Now if you read up the code and the comments, i think this will be an easy 
wrap up.

=end

require 'pp' # for pretty print

i = 5 # size of the martix i want to print in a spiral
num = 0 # the number i want to start with for filling in the empty spaces.

# an empty array of arrays is created, of size 5 in both dimensions. 
array_to_fill = Array.new( i ) { Array.new(i , 0) } 

first = i # This plays an important part in the second printing.

directions = [[0,1],[1,0],[0,-1],[-1,0]] # As given above.
# this shows us which one of the array of the 'directions' you should take.
direction = 0 

#This specific starting offset makes out upcoming code easy to understand.
row_pointer = 0 - directions[direction][0] 
col_pointer = 0 - directions[direction][1]

while i > 0  do
    inner = i
    puts("Inside the loop i = #{i}" )
    
    for j in 1..i
        #  Updating the row and column pointers.
        row_pointer = row_pointer + directions[direction][0] 
        col_pointer = col_pointer + directions[direction][1]
        array_to_fill[row_pointer][col_pointer] = num 
        puts("puts #{num} in #{row_pointer} , #{col_pointer}.")
        num += 1
    end

    direction = ( direction + 1 ) % directions.length 
    # Take that turn!
    puts("turn #{direction}")

    # see? here is where we print everything else a second time, 
    # apart from the very first number.

    if i != first 

        puts("Inside the loop i = #{i} : a second time!" )
        for j in 1..i
            row_pointer = row_pointer + directions[direction][0]
            col_pointer = col_pointer + directions[direction][1]
            array_to_fill[row_pointer][col_pointer] = num 
            puts("puts #{num} in #{row_pointer} , #{col_pointer}.")
            num += 1
        end 
        direction = ( direction + 1 ) % directions.length 
        # take a turn, again. yes. this one actually comes first.
        # the once above comes later.
        puts("turn #{direction}")
           
    end
    
    i -=1
end

pp array_to_fill # pretty printing the filled up array 

__END__

The code in a gist:
https://gist.github.com/Trshant/101297d63501ed6fdccf45d568bc7d6c

To view or add a comment, sign in

Others also viewed

Explore content categories