Skip to content

Instantly share code, notes, and snippets.

@gfontenot
Created August 16, 2012 02:54
Show Gist options
  • Save gfontenot/3366004 to your computer and use it in GitHub Desktop.
Save gfontenot/3366004 to your computer and use it in GitHub Desktop.
SquareSum exercize for RubyReloaded
class MatrixNumericError < StandardError; end
class MatrixLengthError < StandardError; end
class MatrixSizeError < StandardError; end
class Sum
attr_accessor :value, :location
def to_s
"#{value} starting at location #{location.join(', ')}"
end
def include? test_loc
x_array = (location[0]..location[0] + 1).to_a
y_array = (location[1]..location[1] + 1).to_a
x_array.include?(test_loc[:x]) && y_array.include?(test_loc[:y])
end
end
class SquareSum
attr_reader :max, :min
def initialize(matrix)
@matrix = matrix
@max = Sum.new
@min = Sum.new
validate_matrix
end
def calculate
@matrix.each_with_index do |top_line, y_index|
bottom_line = @matrix[y_index + 1]
break unless bottom_line
max_length = top_line.length - 1
max_length.times do |x_index|
arr_one = top_line[x_index..x_index+1]
val_one = arr_one.inject(&:+)
arr_two = bottom_line[x_index..x_index+1]
val_two = arr_two.inject(&:+)
this_sum = val_one + val_two
if [email protected] || this_sum > @max.value
@max.value = this_sum
@max.location = [x_index, y_index]
elsif [email protected] || this_sum < @min.value
@min.value = this_sum
@min.location = [x_index, y_index]
end
end
end
end
def max_value
@max.value
end
def min_value
@min.value
end
def pretty_output
y_axis = 0
output = @matrix.map do |array|
x_axis = 0
result = array.map do |item|
item_result = if @max.include?({ x: x_axis, y: y_axis })
"\033[32m#{item}\033[0m"
elsif @min.include?({ x: x_axis, y: y_axis })
"\033[31m#{item}\033[0m"
else
item
end
x_axis += 1
item_result
end.join(" ")
y_axis += 1
result
end
output.unshift "\033[31mMin\033[0m"
output.unshift "\033[32mMax\033[0m"
output.unshift ""
output.join("\n")
end
private
def validate_matrix
begin
@matrix.flatten(1).inject(&:+)
rescue TypeError
raise MatrixNumericError, "Matrix must only contain numbers!"
end
unless @matrix.map(&:size).uniq.size == 1
raise MatrixLengthError, "Matrix sub-arrays must all be of equal length!"
end
unless @matrix.size > 1 && @matrix.first.size > 1
raise MatrixSizeError, "Must be at least 2 rows and 2 columns in the matrix"
end
end
end
if __FILE__ == $0
arr = [ [1, 4, 6, 1, 9],
[7, 7, 9, 3, 7],
[3, 2, 4, 8, 3],
[5, 5, 8, 5, 5],
[2, 1, 4, 3, 1],
[6, 0, 5, 7, 4],
[6, 7, 0, 1, 3],
[9, 4, 0, 4, 6],
[1, 2, 6, 1, 0] ]
sum = SquareSum.new arr
sum.calculate
puts ""
puts "Max = #{sum.max}"
puts "Min = #{sum.min}"
puts sum.pretty_output
end
require 'minitest/spec'
require 'minitest/autorun'
require_relative 'square_sum'
describe "Valid matrices" do
before do
arr = [ [1, 4, 6, 1, 9],
[3, 7, 9, 2, 3],
[9, 2, 0, 4, 6],
[1, 2, 6, 1, 0] ]
@sum = SquareSum.new arr
@sum.calculate
end
it "can return the max value" do
@sum.max_value.must_equal 26
end
it "can return the min value" do
@sum.min_value.must_equal 10
end
end
describe "Invalid matrices" do
it "cannot contain non numeric values" do
arr = [ [1, 4, "FooBar", 1, 9],
[3, 7, 9, 2, 3] ]
lambda { SquareSum.new(arr) }.must_raise MatrixNumericError
end
it "cannot contain other arrays" do
arr = [ [1, 4, [1, 2, 3], 1, 9],
[3, 7, 9, 2, 3] ]
lambda { SquareSum.new(arr) }.must_raise MatrixNumericError
end
it "cannot contain nil values" do
arr = [ [1, 4, nil, 1, 9],
[3, 7, 9, 2, 3] ]
lambda { SquareSum.new(arr) }.must_raise MatrixNumericError
end
it "has even rows" do
arr = [ [1, 4, 3, 1, 9, 16],
[3, 7, 9, 2, 3] ]
lambda { SquareSum.new(arr) }.must_raise MatrixLengthError
end
it "has at least 2 rows" do
arr = [[1, 2, 3, 4]]
lambda { SquareSum.new(arr) }.must_raise MatrixSizeError
end
it "has at least 2 columns" do
arr = [[1], [2], [3]]
lambda { SquareSum.new(arr) }.must_raise MatrixSizeError
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment