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
2 changes: 2 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--color
--require spec_helper
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.18)
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.4
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
70 changes: 70 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,74 @@
# assignment_search

## Efraim

Marco? Polo!

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

## Warmup 1: BFS and DFS Concepts

1. What data structure is used to implement DFS?

A Tree and a Graph, but the concept can be applied to any sequence that can be traversed.

2. What data structure is typically used to implement BFS?

Same as before.

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

The Tree.

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.?

Any one of the two, but since I like recursion I'd use a Tree.

5. What is the difference between a tree and a graph?

The Tree is a data structure represented by nodes; these nodes may have parent and child nodes.

The Graph may be represented as nodes too, but they don't have a hierarchy between each other.

## Pseudocode

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

```ruby
def depth_first_search(arr, obj)
return if arr.nil?
if arr.is_a? Array
depth_first_search(arr[0], obj) || depth_first_search(arr[1..-1], obj)
else
arr if arr == obj
end
end
```

2. Searching the same tree using BFS.

```ruby
def breadth_first_search(queue, obj)
if queue.empty?
nil
else
first, rest = queue[0], queue[1..-1]
if first.is_a? Array
rest.push(first[0])
rest.push(first[1..-1])
breadth_first_search(rest, obj)
else
return first if first == obj
breadth_first_search(rest, obj)
end
end
end
```

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

Same concept as the upper code.

4. Searching the same graph using BFS.

Same concept as the upper code.
109 changes: 109 additions & 0 deletions lib/knight.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# find the exact sequence of moves required to get from any given
# square to another square on the board
# 8x8

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

# Set up a very basic MoveTree class (as in, "a tree of moves").
# It should construct a tree of potential moves from a given position by using
# a series of Move structs.
# It should take two inputs -- a coordinate pair to represent the starting
# position and a max_depth value which prevents the tree from
# continuing infinitely large [ok]

class MoveTree
attr_accessor :axis, :max_depth, :root

def initialize(axis, max_depth)
@axis = axis
@max_depth = max_depth
@root = MoveTree.build_tree!(Move.new(axis[0], axis[1], 0), 0, max_depth)
end

# ---------------------------------------------------------------
# Access
# ---------------------------------------------------------------

def children
root.children
end

def x
root.x
end

def y
root.y
end

# ---------------------------------------------------------------
# Class Methods
# ---------------------------------------------------------------

def self.knight_moves
[
[2, 1], [2, -1], [-2, 1], [-2, -1],
[1, 2], [-1, 2], [1, -2], [-1, -2]
]
end

def self.moves_for(parent, depth)
MoveTree.knight_moves.map do |move|
to_x, to_y = move
Move.new(parent.x - to_x, parent.y - to_y, depth, nil, parent)
end.select do |move|
MoveTree.within_board_limits?(move.x, move.y)
end
end

def self.build_tree!(parent, depth, max_depth)
return parent if depth == max_depth
if parent.children.nil?
depth += 1
parent.children = MoveTree.moves_for(parent, depth)
MoveTree.build_tree!(parent, depth, max_depth)
else
parent.children.each do |node|
MoveTree.build_tree!(node, depth, max_depth)
end
parent
end
end

def self.within_board_limits?(x, y)
x >= 0 && x <= 7 &&
y >= 0 && y <= 7
end

def self.length(tr)
if tr.children
tr.children.length + tr.children.map{ |c| MoveTree.length(c) }.sum
else
0
end
end

# ---------------------------------------------------------------
# Instance Methods
# ---------------------------------------------------------------

def length
MoveTree.length(root) + 1
end

def depth
d = 0
parent = root
while true
break if parent.children.nil?
d += 1
parent = parent.children[0]
end
d
end

def inspect
"Your tree has #{length} Move nodes and a maximum depth of #{depth}"
end

end
Loading