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
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,48 @@
Marco? Polo!

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

1) What data structure is used to implement DFS?
-- Stack

2) What data structure is typically used to implement BFS?
-- Queue

3) Which one can be done recursively? (the clue should be the data structure)
--DFS

4) 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.?
-- BFS

5) What is the difference between a tree and a graph?
-- A tree is a type of graph having only one path between any two verticies so there can be no loops or cycles.

PSEUDOCODE
1) Searching a simple tree of nodes where each Node has an array of child nodes (some_node.children) using DFS
a. start with root node and compare to target
b. if they match return root node, else push children into stack from "worst" to "best"
c. pop first element on stack and compare to target.
d. if they match return element else push its children into stack from "worst" to "best"
e. repeat until target found or no more nodes

2) Searching the same tree using BFS.
a. start with root node and compare to target
b. if they match return root node, else enqueue children
c. dequeue first element and compare to target
d. if they match return element else enqueue children
e. dequeue next element and repeat until target found or no more nodes


3) Searching a graph (represented however you feel most comfortable -- Edge List, Adjacency List or Adjacency Matrix) using DFS.
a. choose one vertex and iterate through edges until you find target or move to next one.

4) Searching the same graph using BFS.
a. use nested loops to iterate through each path until target found or iteration complete.

KNIGHT"S PSEUDOCODE
a. Establish the board as a 2D array of verticies
b. create method that takes two vertex args of where to start and target
c. define helper method of possible moves
d. add record to node of depth from root
e. iterate through possible moves until target hit
13 changes: 13 additions & 0 deletions knight.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# require_relative 'knight_searcher'
# require_relative 'move_tree'

module KnightsTravails

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

class Move
def to_s
"position: #{x}, #{y}\ndepth: #{depth}"
end
end
end
50 changes: 50 additions & 0 deletions knight_searcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
class KnightSearcher
include KnightsTravails
attr_reader :move_tree
def initialize(move_tree)
@move_tree = move_tree
end

def bfs_for(target)
start = move_tree.start_node
start.depth = 0
queue = [start]
until queue.empty?
current = queue.pop
if target == [current.x, current.y]
return path_to(current)
else
current.children.each do |move|
next if move.depth
queue.unshift(move)
move.depth = current.depth + 1
end
end
end
puts "Could not find node."
end

def dfs_for(target)
stack = [move_tree.start_node]
depth = 0
current = nil
until stack.empty?
current = stack.pop
current.depth = depth
return path_to(current) if target == [current.x, current.y]
depth += 1
current.children.each {|s| stack.push(s) unless s.depth}
end
puts "Could not find node."
end

def path_to(move)
path = []
node = move
until node.nil?
path.unshift[node.x, node.y]
node = node.parent
end
puts path
end
end
46 changes: 46 additions & 0 deletions move_tree.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
class MoveTree
include KnightsTravails
attr_accessor :start_node, :max_depth, :node_count

def initialize(coords = nil, max_depth = nil)
@start_node = Move.new(coords[0], coords[1], nil, nil, []) || [0,0]
@max_depth = max_depth || 3
@board_size = 8
@node_count = 0
build_tree
puts inspect
end

def inspect
"Your tree starts with [#{start_node.x}, #{start_node.y}]. It has a maximum depth of #{max_depth}, and #{node_count} total nodes."
end

def build_tree
x = @start_node[0]
y = @start_node[1]
@tree = create_node(x, y)
end

def create_node(x, y, depth = 0, parent = nil)
@node_count += 1
node = Move.new(x, y, depth, [], parent)
unless depth == @depth
possible_moves(x, y) do |ex, why|
node.children << create_node(ex, why, depth + 1, node)
end
node
end
end

def possible_moves(x, y)
[[x + 2, y - 1], [x + 2, y + 1],
[x - 2, y + 1], [x - 2, y - 1],
[x + 1, y + 2], [x - 1, y + 2],
[x + 1, y - 2], [x - 1, y - 2]].select {|pos_move| legal?(pos_move)}
end

def legal?(move)
((move[0]).between?(0, 7)) && ((move[1]).between?(0, 7))
end

end
11 changes: 11 additions & 0 deletions test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require_relative 'knight'
require_relative 'move_tree'
require_relative 'knight_searcher'

include KnightsTravails

mt = MoveTree.new([0, 0], 6)
ks = KnightSearcher.new(mt)
puts
print ks.dfs_for([1,2])
puts