Skip to content

Instantly share code, notes, and snippets.

@simon2k
Created December 14, 2014 17:42
Show Gist options
  • Save simon2k/9ae590acd451633fd778 to your computer and use it in GitHub Desktop.
Save simon2k/9ae590acd451633fd778 to your computer and use it in GitHub Desktop.
Solution for code eval 55
N = 4
class Coordinate
MAX_COORDINATE = N
MIN_COORDINATE = 0
def initialize(y, x)
@y = y
@x = x
end
attr_reader :x, :y
def sibling_coordinates
possible_next_coordinates = [[y-1, x], [y+1, x], [y, x-1], [y, x+1]]
valid_next_coordinates = possible_next_coordinates.select do |y, x|
y >= MIN_COORDINATE && x >= MIN_COORDINATE && y <= MAX_COORDINATE && x <= MAX_COORDINATE
end
valid_next_coordinates.map { |y, x| CoordinatesFactory.instance.get_coordinates_at(y, x) }
end
def is_end_coordinate?
x == y && x == MAX_COORDINATE
end
end
class CoordinatesFactory
require 'singleton'
include Singleton
attr_accessor :coordinates
def produce_coordinates!
@coordinates ||= {}
N.next.times do |y|
coordinates[y] = {}
N.next.times { |x| coordinates[y][x] = Coordinate.new(y, x) }
end
end
def get_coordinates_at(y, x)
coordinates[y][x]
end
end
class Step
def initialize(coordinate, parent = nil)
@coordinate = coordinate
@path_coordinates = parent ? parent.path_coordinates + [coordinate] : [coordinate]
end
attr_reader :path_coordinates, :coordinate
def next_steps
next_coordinates.map { |coordinate| Step.new(coordinate, self) }
end
def is_end_coordinate?
@coordinate.is_end_coordinate?
end
private
def next_coordinates
@coordinate.sibling_coordinates.reject { |coordinate| path_coordinates.include?(coordinate) }
# @coordinate.sibling_coordinates.select { |coordinate| !path_coordinates.include?(coordinate) }
# @coordinate.siblings.keep_if { |c| !path_coordinates.include?(c) }
# @coordinate.siblings - path_coordinates
end
end
def calculate_number_of_paths
first_coordinate = CoordinatesFactory.instance.get_coordinates_at(0, 0)
@current_steps = [Step.new(first_coordinate)]
@number_of_paths = 0
loop do
@current_steps = @current_steps.map(&:next_steps).flatten
break if @current_steps.empty?
number_of_current_steps = @current_steps.count
@current_steps.reject!(&:is_end_coordinate?)
@number_of_paths += number_of_current_steps - @current_steps.count
end
@number_of_paths
end
# CoordinatesFactory.instance.produce_coordinates!
# p calculate_number_of_paths
# require 'benchmark'
#
# Benchmark.bmbm do |x|
# x.report do
# CoordinatesFactory.instance.produce_coordinates!
# p calculate_number_of_paths
# end
# end
# require 'ruby-prof'
#
# RubyProf.start
# CoordinatesFactory.instance.produce_coordinates!
# p calculate_number_of_paths
# result = RubyProf.stop
# printer = RubyProf::FlatPrinter.new(result)
# printer.print(STDOUT)
CoordinatesFactory.instance.produce_coordinates!
p calculate_number_of_paths
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment