Created
December 14, 2014 17:42
-
-
Save simon2k/9ae590acd451633fd778 to your computer and use it in GitHub Desktop.
Solution for code eval 55
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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