HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyMinor

Maze solver for 2D matrix in Ruby

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
mazeforrubysolvermatrix

Problem

I got rejected for a junior Ruby job entry where I had to solve a 2D matrix as a maze with walls.

This is the main class:

solver.rb

```
require 'json'

class MazeSolver

def initialize(file)
@file = file
@data = ""
@table = Array.new
@table_reversed = Array.new
@table_merged = Array.new
@table_convert = Array.new
@nodes = Array.new
@step = 1
@start_node = 999
@goal_node = 999
@current_node = 999
@table_x = 0
@table_y = 0
@unvisited_set = Array.new
@node_list = Array.new
@shortest_path = Array.new
@shortest_path_coords = Array.new
@backtrack = Array.new
parse_maze
create_nodes
end

# convert the maze string to an array of arrays
def parse_maze

k = 0
@data = File.read(@file)
@data.strip.split(/[\l|\n\/]/).each do |line|
@row = Array.new
line.split(/ /).each do |item|
@row 0 do

# set the current node as the first element of the list and remove it
@current_node = unvisited_set.shift

# set values for neighbours
neighbours = []
left_node = @current_node - @step
top_node = @current_node + @table_x
right_node = @current_node + @step
bottom_node = @current_node - @table_x

# check If neighbours are not in the edges
if left_node > 0 && @current_node % @table_x != 0 && @table_merged[left_node] != "X"
neighbours = 0 && @table_merged[bottom_node] != "X"
neighbours @current_node,
:neighs => neighbours,
:dist => @distance,
:prev => previous_node
}
end

return @node_list
end # create nodes

# does what it says !
def solve_dijkstra

unvisited_set = @unvisited_set.dup

# create a queue for nodes to check
@queue = Array.new
current_node = @start_node
@queue 0 && @queue.size > 0 do

# set the current node as visited and remove it from the unvisited set
current_node = @queue.shift

# remove visited node

Solution

I think your code shows ability of writing readable code, understanding and implementing algorithms, writing helpful comments, and if the code works like I believe it does, providing a working solution to the problem.

The only major issue about your solution I can think of is that perhaps they expected you to take a more modular and object oriented approach to the problem.

Now your MazeSolver class handles all tasks: reading a file, modelling the problem domain, solving the maze and printing the solution. Instead you could write classes like

  • Maze



  • MazeFile



  • MazeSolution



  • MazeSolver



This kind of approach would lead to solving the problem by having objects process and encapsulate different bits of the problem and communicating through simple and well defined interfaces.

The key benefit of modularity is that it makes it easier to make changes to a program. If, for instance, you needed to support another maze file format or try out another maze solving algorithm, then having separate modules or classes for handling files and solving mazes would help.

Ok, since you asked for an example, here's an example of splitting the functionality you've already written to several classes:

class Maze
    # 1. Encapsulate the in-memory maze data here.
    # 2. Provide methods giving read access to the maze data.
    # 3. Provide methods to initialize the maze data. A constructor could work.
end

class MazeFile
    # 1. Move reading and parsing a maze file here.
    # 2. Parsing a file should produce a Maze object.
end

class MazeSolution
    # 1. Encapsulate data that describes a solution to a maze.
    # 2. Provide methods to initialize and/or build a solution step by step.
    # 3. Provide a method that returns the solution as a formatted string
end

class MazeSolver
    # 1. Move the solve method here. 
    # The method should take a Maze as a parameter and return a MazeSolution.
    # It should not mutate the Maze given as a parameter.
end

# Main program (for command line interface)
    # 1. Read command line
    # 2. Use MazeFile to read a Maze from a file.
    # 3. Use MazeSolver to produce a MazeSolution by calling the solve method
    # 4. Print the solution using MazeSolutions formatting


Now, this is just one quickly sketched initial design. Refactoring your implementation to this skeleton would quickly show whether this is a good design or not. Perhaps you could do just fine with fewer classes or perhaps you would need more classes.

I don't think you need object oriented programming skills to land some entry level job. However, the lack of modularity and/or object orientation is the only major issue I can spot in your code, so it's my best guess for the reason for this rejection. Ruby is an object oriented language, and thus showing OO skills wouldn't probably hurt, even though the true advantages of object orientation don't really show in a small scale one-time program.

Code Snippets

class Maze
    # 1. Encapsulate the in-memory maze data here.
    # 2. Provide methods giving read access to the maze data.
    # 3. Provide methods to initialize the maze data. A constructor could work.
end

class MazeFile
    # 1. Move reading and parsing a maze file here.
    # 2. Parsing a file should produce a Maze object.
end

class MazeSolution
    # 1. Encapsulate data that describes a solution to a maze.
    # 2. Provide methods to initialize and/or build a solution step by step.
    # 3. Provide a method that returns the solution as a formatted string
end

class MazeSolver
    # 1. Move the solve method here. 
    # The method should take a Maze as a parameter and return a MazeSolution.
    # It should not mutate the Maze given as a parameter.
end

# Main program (for command line interface)
    # 1. Read command line
    # 2. Use MazeFile to read a Maze from a file.
    # 3. Use MazeSolver to produce a MazeSolution by calling the solve method
    # 4. Print the solution using MazeSolutions formatting

Context

StackExchange Code Review Q#105236, answer score: 8

Revisions (0)

No revisions yet.