Sunday, November 15, 2015

ASCII X-in-Box (Ruby)

After taking the Codecademy course on Ruby, I have started reading Eloquent Ruby by Russ Olsen. I saw a problem posted on a community for another language about making a kind of shape. I thought it would make a good exercise to try out what I have learned.

The shape is a box of numbers, hollow except for the diagonals. For example, a box of side-length 5 would look like

1 2 3 4 5
1 2 4 5
1 3 5
1 2 4 5
1 2 3 4 5

and one of side length 6 like

1 2 3 4 5 6
1 2 5 6
1 3 4 6
1 3 4 6
1 2 5 6
1 2 3 4 5 6

The thinking behind my solution is to separate printing the outside of the box from the inside. A function named interior? — ending with a question mark in the spirit of a Ruby convention for boolean functions — calculates this. The local input went out-of-scope, so I used a global $input instead.

To allow multi-digit numbers, I convert missing numbers into a string to find out how many characters would have been taken up.

I have a feeling there's a neat way to draw all this with just one if but it hasn't come to me yet. As you may be able to tell, I have enjoyed Ruby's parentheses-optional attitude. Also, the implicit return, like the one I use in my function.

Here's the code:

#!/usr/bin/ruby2.1

print "Input: "
$input = gets.chomp.to_i

def interior? index 
  0 < index and index < $input-1
end

$input.times do |row| 
  $input.times do |col|
    if interior? row and interior? col  
      if col == row or ($input-1)-col == row 
        print col + 1 
      else
        print " " * (col+1).to_s.length
      end 
    else
      print col + 1 
    end 
    print " " 
  end 
  puts 
end 

No comments:

Post a Comment