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
Binary file added .DS_Store
Binary file not shown.
3 changes: 3 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--color
--require spec_helper
--format documentation
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.3)
ffi (1.9.17)
formatador (0.2.5)
guard (2.14.1)
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.11)
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.8)
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.14.3
70 changes: 70 additions & 0 deletions Guardfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# A sample Guardfile
# More info at https://github.com/guard/guard#readme

## Uncomment and set this to only include directories you want to watch
# directories %w(app lib config test spec features) \
# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}

## Note: if you are using the `directories` clause above and you are not
## watching the project directory ('.'), then you will want to move
## the Guardfile to a watched dir and symlink it back, e.g.
#
# $ mkdir config
# $ mv Guardfile config/
# $ ln -s config/Guardfile .
#
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"

# Note: The cmd option is now required due to the increasing number of ways
# rspec may be run, below are examples of the most common uses.
# * bundler: 'bundle exec rspec'
# * bundler binstubs: 'bin/rspec'
# * spring: 'bin/rspec' (This will use spring if running and you have
# installed the spring binstubs per the docs)
# * zeus: 'zeus rspec' (requires the server to be started separately)
# * 'just' rspec: 'rspec'

guard :rspec, cmd: "bundle exec rspec" do
require "guard/rspec/dsl"
dsl = Guard::RSpec::Dsl.new(self)

# Feel free to open issues for suggestions and improvements

# RSpec files
rspec = dsl.rspec
watch(rspec.spec_helper) { rspec.spec_dir }
watch(rspec.spec_support) { rspec.spec_dir }
watch(rspec.spec_files)

# Ruby files
ruby = dsl.ruby
dsl.watch_spec_files_for(ruby.lib_files)

# Rails files
rails = dsl.rails(view_extensions: %w(erb haml slim))
dsl.watch_spec_files_for(rails.app_files)
dsl.watch_spec_files_for(rails.views)

watch(rails.controllers) do |m|
[
rspec.spec.call("routing/#{m[1]}_routing"),
rspec.spec.call("controllers/#{m[1]}_controller"),
rspec.spec.call("acceptance/#{m[1]}")
]
end

# Rails config changes
watch(rails.spec_helper) { rspec.spec_dir }
watch(rails.routes) { "#{rspec.spec_dir}/routing" }
watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }

# Capybara features specs
watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }

# Turnip features and steps
watch(%r{^spec/acceptance/(.+)\.feature$})
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
end
end
95 changes: 94 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,97 @@
# assignment_search
Marco? Polo!
Andrea A

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

# Running the code
```
load 'knight_searcher.rb'
load 'benchmark.rb'

tree = MoveTree.new([2,2],1)
searcher = KnightSearcher.new( tree )
bm = BenchmarkTest.new(searcher)
```


# 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 is best designed to be done recursively


# 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 prints all the nodes at each level before going to the next level



# What is the difference between a tree and a graph?
Trees have nodes an graphs have vertices.
There is no root node in a graph, so they are slightly less structured than trees.
A tree has a hierarchical structure but a graph doesn't.

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

```Store the node to be found
Initialize an empty stack

starting at root, searching for x
current_node = root
loop - while stack is not empty
Take the end of the stack - y
if current_node.children is equal to x
return x and break loop
else current_node = current_node.children - push on to stack
break the loop if current_node has no children
end the loop
```

** 2) Searching the same tree using BFS. **

```Store the node to be found
Initialize an empty queue

Put all nodes on the queue

starting at root, searching for x
current_node = root
loop - while queue is not empty
Take the top of the queue - y
if current_node.children is equal to x
return x and break loop
else current_node = current_node.children - push on to queue
```


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

Searching the same tree using BFS.

Store the node to be found

``` starting at root
current_node = root and mark this as visited
get the next node from the root and iterate through its nodes
if the node hasn't been visited call the function again
else go the the next level up
break when there is no children
```

** 4. Searching the same graph using BFS. **

Store the node to be found

``` starting at root
current_node = root and mark this as visited
put the root on the queue
loop while the queue still elements
take an item from the top of the queue
check if the item is equal to the node to be found
iterate through the dequeued node
if the node is not visited put it on the queue otherwise go to the next.
```
38 changes: 38 additions & 0 deletions lib/benchmarking.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

require_relative 'move_tree'
require_relative 'knight_searcher'

class Benchmarking

attr_accessor :bfs_time, :dfs_time, :knight_searcher

def initialize
tree = MoveTree.new([1,2],1)
@knight_searcher = KnightSearcher.new( tree )
@bfs_time = 0
@dfs_time = 0
end

def bfs_measure(coords)
start_time = Time.now
10.times do
@knight_searcher.bfs_for(coords)
end
@bfs_time = (Time.now - start_time) / 60
end

def dfs_measure(coords)
start_time = Time.now
10.times do
@knight_searcher.dfs_for(coords)
end
@dfs_time = (Time.now - start_time) / 60
end

def statistics
puts "Breadth-first search vs Depth-first search"
puts "The bfs searcher took #{@bfs_time} and the dfs searcher took #{@dfs_time}"
end

end

67 changes: 67 additions & 0 deletions lib/knight_searcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

require_relative 'move_tree'

class KnightSearcher

attr_accessor :knight_tree, :moves, :trail

def initialize(tree)
@knight_tree = tree.root
@trail = Array.new
end


def bfs_for(target_coords)
queue = []
@moves = 0
@trail = []
queue << @knight_tree

while queue.length != 0
current = queue.shift
@moves += 1
@trail << [current.x, current.y]
if(current.x == target_coords[0] && current.y == target_coords[1])

print_trail
return "Found node"
elsif(current.children)
current.children.each do | descendants|
queue << descendants
end
end
end
puts "Path not found"
end

def dfs_for(target_coords)
stack = []
@moves = 0
@trail = []
stack << @knight_tree

while stack.length != 0
current = stack.pop
@moves += 1
@trail << [current.x, current.y]
if(current.x == target_coords[0] && current.y == target_coords[1])
print_trail
return "Found node"
elsif(current.children)
current.children.each do | descendants|
stack << descendants
end
end
end
puts "Path not found"
end

# Output the sequence of moves used to get there as well as the final depth required.
def print_trail
puts "#{@moves} moves:"
@trail.each do |x|
puts "[#{x[0]}, #{x[1]}]"
end
end
end

Loading