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

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

Tamal Riedman

1. Stack
2. Queue
3. DFS
4. BFS
5. Tree would usually be much more organized, have direct relationship between parents and children, graph good for data that isn't easily organized, varying relationships, maybe no ROOT node

1. Start at first node
if no children, or all children visited already, move up to parent
elsif there are children, go to the left one
recurse
end
end

2. Start at first node
if children, index first level of children
if there are children, index second level of children
if there are children, index third level of children
if no child levels remain
stop
end
end
end
end
end

3. Start at first bucket
mark source node read
move to first child
mark child read
move to first child
mark child read
recurse...
end
end
end

4. Start at first bucket
mark source read
move to first child
mark read
move to second child of source
mark read
move to third child of source
mark read
end
end
end
mark first child as source
move to first child of new source
end
mark second child of original child as source
move to that child
end
etc.
end

Warmup II

Conceptually, each spot on a chess board will be a node. Knight will traverse the "nodes" of the board using depth-first search. Nodes cannot be visited twice, Search will end when all "nodes" have been visited.
75 changes: 75 additions & 0 deletions knight_searcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
require_relative 'move_tree.rb'

class KnightSearcher

attr_accessor :tree, :current_node

def initialize(tree)
@root = tree.root
@current_node = @root
@path = []
@depth = @current_node.depth
end

def bfs_for(target_coords)
queue = [@root]
until queue.empty?
if queue[0].x == target_coords[0] && queue[0].y == target_coords[1]
return list_moves(queue[0])
else
queue[0].children.each do |child|
queue << child
end
queue.shift
end
end
end

def dfs_for(target_coords)
stack = [@root]
until stack.empty?
current = stack.pop
if current.x == target_coords[0] && current.y == target_coords[1]
return list_moves(current)
else
current.children.each do |child|
stack << child
end
end
end
end

def list_moves(move)
moves = []
until move.parent.nil?
moves << move
move = move.parent
end
moves
end

def print_moves(moves)
puts "# #{moves.length} Moves:"
print "Moves: [#{@root.x}, #{@root.y}]"
until moves.empty? do
current = moves.pop
print "\n --> [#{current.x}, #{current.y}]"
end
puts
end

def benchmark
t = Time.new
yield
puts "# It took #{Time.new - t} seconds."
end

end

search = KnightSearcher.new(MoveTree.new([0, 0], 5))
search.benchmark do
search.print_moves(search.bfs_for([1, 3]))
end
search.benchmark do
search.print_moves(search.dfs_for([1, 3]))
end
64 changes: 64 additions & 0 deletions move_tree.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
Move = Struct.new(:x, :y, :depth, :children, :parent)

class MoveTree

attr_reader :coords, :max_depth, :root, :depth

def initialize(coords, max_depth=1)
@root = Move.new(coords[0], coords[1], 0, [], nil)
@max_depth = max_depth
@current_node = @root
@count = 1
create_moves
end

def create_moves
queue = []
depth = @count - 1
while @current_node.depth < @max_depth
get_children(@current_node)
@current_node.children.each do |n|
queue << n
@count += 1
end
@current_node = queue.shift
end
end

def get_children(parent)
moves = within_board?([parent.x, parent.y])
moves.each do |coords|
new_node = Move.new(coords[0], coords[1], parent.depth + 1, [], parent)
add_parent(@current_node, new_node)
end
return parent
end

def add_parent(parent, new_node)
parent.children << new_node
new_node.parent = parent
end

def within_board?(move)
x = move[0]
y = move[1]
moves = []
array = [[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], [x + 1, y + 2]]
array.each do |coords|
moves << coords if valid_move?(coords)
end
return moves
end

def valid_move?(coords)
return true if coords[0].between?(0, 7) && coords[1].between?(0, 7)
end

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

end