Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,37 @@
Marco? Polo!

[A data structures and algorithms Ruby challenge from the Viking Code School](http://www.vikingcodeschool.com)

David J and Vishal

What data structure is used to implement DFS? Stack

What data structure is typically used to implement BFS? Queue

Which one can be done recursively? (the clue should be the data structure) Stack

Which one would you use to print a list of all the nodes in a tree or graph, starting with depth 1, then depth 2, then depth 3 etc.?
What is the difference between a tree and a graph? BFS

Next, pseudocode the following processes with enough detail to be clear:

Searching a simple tree of nodes where each Node has an array of child nodes (some_node.children) using DFS.

def search_node(start_node, node you're searching for)
if start node is nil, return
start at the root, pick a child and check it. return if this is the one you're looking for
if not found, pick a child of that child and check it. continue until you find the solution or you reach a leaf (no children)
when you reach a leaf, go back up to a node with a child that you have not checked yet and repeat for that child.


Searching the same tree using BFS.
Start at the root, and check every child, and return if any of them if he one
you want.
If not, repeat this process for each of those children's children.

Searching a graph (represented however you feel most comfortable -- Edge List, Adjacency List or Adjacency Matrix) using DFS.
(For adjacency list): Searching an edge?


Searching the same graph using BFS.

81 changes: 81 additions & 0 deletions part1-tree-builder/knight_searcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
require_relative 'move_tree'

class KnightSearcher

def initialize(tree)
#for bfs
@tree = tree
@path = []
@queue = []
@moves = 0
@current_node = nil
@checked_moves = []

#for dfs
@stack = []
end

def bfs_for(target_coords)
find_target(target_coords)
find_path(target_coords)
print_message
end

def find_target(target_coords)
@queue << @tree.root
@current_node = @queue.shift
@checked_moves << @current_node
until [@current_node.x,@current_node.y] == target_coords
@current_node.children.each do |child|
@queue << child
end
@current_node = @queue.shift
until !@checked_moves.include?(@current_node)
@current_node = @queue.shift
end
@checked_moves << @current_node
end
end

def find_path(target_coords)
@path << target_coords
until @current_node == @tree.root
@path << [@current_node.parent.x,@current_node.parent.y]
@moves += 1
@current_node = @current_node.parent
end
end

def print_message
puts "#{@moves} moves:"
index = @path.length-1
index.downto(0) {|i| puts "[#{@path[i][0]},#{@path[i][1]}]"}
end

def dfs_for(target_coords)
@stack << @tree.root
@current_node = @stack.pop
@checked_moves << @current_node
until ([@current_node.x,@current_node.y] == target_coords)
if @current_node.children
@current_node.children.each do |child|
@stack << child
end
end
@current_node = @stack.pop
until !@checked_moves.include?(@current_node)
@current_node = @stack.pop
end
@checked_moves << @current_node
end
find_path(target_coords)
print_message
end

end

tree = MoveTree.new([3,3],3)
bfs_searcher = KnightSearcher.new(tree)
dfs_searcher = KnightSearcher.new(tree)
bfs_searcher.bfs_for([1,3])
dfs_searcher.dfs_for([1,3])
4 changes: 4 additions & 0 deletions part1-tree-builder/move.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# move.rb

Move = Struct.new(:x, :y, :depth, :children, :parent)

62 changes: 62 additions & 0 deletions part1-tree-builder/move_tree.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# move_tree.rb
require_relative 'move'

class MoveTree
attr_reader :root

def initialize(start_coordinates, max_depth = 1)
@start_x = start_coordinates[0]
@start_y = start_coordinates[1]
@max_depth = max_depth
@root = Move.new(@start_x, @start_y, 0, nil, nil)
@counter=1
generate_tree_from(@root)
end

def inspect
puts "Your tree has #{@counter} Move nodes and a maximum depth of #{@max_depth}."
end

def generate_tree_from(move)
if move.depth == @max_depth
return
else
generate_children_for(move)
move.children.each do |child|
generate_tree_from(child)
end
end
end

def generate_children_for(move)
children = all_possible_coordinates(move.x,move.y).map do |coord|
Move.new(coord[0],coord[1], move.depth+1, nil, move)
end
move.children = children
@counter += children.length
end

def all_possible_coordinates(x, y)
possible_moves = [
[x + 1, y + 2],
[x + 2, y + 1],
[x + 2, y - 1],
[x + 1, y - 2],
[x - 1, y - 2],
[x - 2, y - 1],
[x - 2, y + 1],
[x - 1, y + 2]
]

possible_moves.select do |coordinates|
coordinates.all? do |coord|
coord.between?(0,7)
end
end
end

end

knight_tree = MoveTree.new([0,0],3)
knight_tree.inspect