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
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source "https://rubygems.org"

gem 'rspec'
gem 'guard-rspec', require: false
65 changes: 65 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
GEM
remote: https://rubygems.org/
specs:
coderay (1.1.1)
diff-lcs (1.2.5)
ffi (1.9.14)
formatador (0.2.5)
guard (2.14.0)
formatador (>= 0.2.4)
listen (>= 2.7, < 4.0)
lumberjack (~> 1.0)
nenv (~> 0.1)
notiffany (~> 0.0)
pry (>= 0.9.12)
shellany (~> 0.0)
thor (>= 0.18.1)
guard-compat (1.2.1)
guard-rspec (4.7.3)
guard (~> 2.1)
guard-compat (~> 1.1)
rspec (>= 2.99.0, < 4.0)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
lumberjack (1.0.10)
method_source (0.8.2)
nenv (0.3.0)
notiffany (0.1.1)
nenv (~> 0.1)
shellany (~> 0.0)
pry (0.10.4)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
rb-fsevent (0.9.8)
rb-inotify (0.9.7)
ffi (>= 0.5.0)
rspec (3.5.0)
rspec-core (~> 3.5.0)
rspec-expectations (~> 3.5.0)
rspec-mocks (~> 3.5.0)
rspec-core (3.5.4)
rspec-support (~> 3.5.0)
rspec-expectations (3.5.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.5.0)
rspec-mocks (3.5.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.5.0)
rspec-support (3.5.0)
ruby_dep (1.5.0)
shellany (0.0.1)
slop (3.6.0)
thor (0.19.4)

PLATFORMS
ruby

DEPENDENCIES
guard-rspec
rspec

BUNDLED WITH
1.13.6
8 changes: 8 additions & 0 deletions Move = Struct.new(:x, :y, :depth, :children, :pare
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Move = Struct.new(:x, :y, :depth, :children, :parent)

class MoveTree




end
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,62 @@
Marco? Polo!

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


Tingting Wang


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)
DFS

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

What is the difference between a tree and a graph?
tree is hierarchical, graph isn't
=====================
Searching a simple tree of nodes where each Node has an array of child nodes (some_node.children) using DFS.

starting at root, searching for x
curr_node = root
loop
curr_node.children == x ? return x : curr_node = curr_node.children
break if curr_node.children.nil
end

add root and branches to stack


Searching the same tree using BFS.

starting at root, searching for x
node = root
enqueue(node)
node contains x ? return node : enqueue node.children
dequeue node


Searching a graph (represented however you feel most comfortable -- Edge List, Adjacency List or Adjacency Matrix) using DFS.

adjacency list
array.each |list|
list contains x? return node : next
end

adjacency matrix
search matrix through each array (row)


Searching the same graph using BFS.

adjacency list
search first node for each list
search second node for each list
etcparen

adjacency matrix
search matrix through indexes (columns)
30 changes: 30 additions & 0 deletions benchmark.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require_relative 'knight_searcher.rb'


bfs_time = []
dfs_time = []


1000.times do
root_coordinates = [rand(7), rand(7)]
b = MoveTree.new([rand(7), rand(7)], rand(5))
a = KnightSearcher.new(b)
target_coordinates = [rand(7), rand(7)]

bfs_start = Time.now
a.bfs_for(target_coordinates)
bfs_end = Time.now
bfs_time << bfs_end - bfs_start

dfs_start = Time.now
a.dfs_for(target_coordinates)
dfs_end = Time.now
dfs_time << dfs_end - dfs_start
end



bfs_time.inject(:+)
dfs_time.inject(:+)


59 changes: 59 additions & 0 deletions knight_searcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require_relative 'move_tree.rb'
require 'pry'

class KnightSearcher

def initialize(tree)
@tree = tree
@searched_nodes = []
end

#conducts search through iterations of depth layers
def bfs_for(target_coords)
queue = [@tree.root]
until queue.empty?
curr_node = queue[0]
if match?(curr_node, target_coords)
search_trail
break
end
queue += curr_node.children
#search queue for children
queue.shift
end
end

def dfs_for(target_coords)
stack = [@tree.root]
until stack.empty?
curr_branch = stack.pop
break if match?(curr_branch, target_coords)
stack += curr_branch.children
end
search_trail
end


def match?(curr_node, target_coords)
@searched_nodes << curr_node
[curr_node.x, curr_node.y] == target_coords
end

def search_trail
puts "#{@searched_nodes.size} Moves:"
@searched_nodes.each {|node| puts "[#{node.x}, #{node.y}]" }
return
end

end

=begin

load 'knight_searcher.rb'
b = MoveTree.new([3,3], 1)
a = KnightSearcher.new(b)
a.dfs_for([4,1])
a.bfs_for([4,1])


=end
97 changes: 97 additions & 0 deletions move_tree.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
Move = Struct.new(:x,:y,:depth,:children,:parent)

class MoveTree
attr_accessor :tree, :root

MOVEMENT_DIFF = [
[+2, +1],
[+2, -1],
[-2, +1],
[-2, -1],
[+1, +2],
[-1, +2],
[+1, -2],
[-1, -2]
]

def initialize(coordinate, depth)
@root = Move.new(coordinate[0],coordinate[1],0,[],nil)
@node_count = 1
@max_depth = depth
make_tree
end

def make_tree
(1..@max_depth).each do |depth_layer|
#find parents
find_childless
# make children for each parent node
make_children(depth_layer)
end
@node_count
end

#should generate queue (array of all childless parent nodes)
def find_childless
@childless = []
queue = [@root]
until queue.empty?
curr_node = queue[0]
if curr_node.children.empty?
@childless << curr_node
else
queue += curr_node.children
end
queue.shift
end
@childless
end

#should generate children nodes
def make_children(depth_layer)
@childless.each do |node|
coords = generate_children_coordinates(node.x, node.y)
coords.each do |x,y|
child = Move.new(x,y,depth_layer,[],node)
node.children ||= []
node.children << child
@node_count += 1
end
end
#generate coordinates for children
#creates child nodes with child coordinates, appropriate depth attribute, appropriate parent node attribute)
end

#should generate coordinates for each child node
def generate_children_coordinates(x,y)
child_coordinates = []
MOVEMENT_DIFF.each do |dx, dy|
move = [x+dx, y+dy]
child_coordinates << move if within_limits?(move)
end
child_coordinates
end

def within_limits?(move)
move.each { |var| return false unless var <= 7 && var >= 0 }
true
end

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



=begin



load 'move_tree.rb'
a = MoveTree.new([3,3], 10)




=end
12 changes: 12 additions & 0 deletions movetree.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Move = Struct.new(:x, :y, :depth, :children, :parent)

class MoveTree

def initiate(coordinate, depth)
@coordinate = coordinate
@max_depth = depth
end



end
41 changes: 41 additions & 0 deletions pseudocode.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
knight pseudo

given a coordinate and depth, map all possible moves in a searchable tree

coordinate = root node

depth = number of iterations for mapping moves
distance(#steps) to finding node with no children

Move = Struct.new(coordainte, depth, parent, child)

class MoveTree
def init(coordinate, depth)
@coordinate = coordinate
@root = Move.new(coordinate, 0, nil, nil)
@depth = depth
end

def make_tree
depth.times
add_layer
end
end

def add_layer(depth)
@tree
find childless nodes in existing tree
add to parent array
make children nodes with depth attribute
end

def make_child_nodes
ensure moves stay within limits of board
every time move created, map to board
end

def board
when filled, halt child_node making process
prevents redundancy
end
end