Skip to content
Merged
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
44 changes: 44 additions & 0 deletions 06_breadth-first_search/lua/01_breadth-first_search.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
-- Custom deque module
require "deque"

local function person_is_seller(name)
return string.char(string.byte(name, -1)) == "m"
end

local graph = {}
graph["you"] = {"alice", "bob", "claire"}
graph["bob"] = {"anuj", "peggy"}
graph["alice"] = {"peggy"}
graph["claire"] = {"thom", "jonny"}
graph["anuj"] = {}
graph["peggy"] = {}
graph["thom"] = {}
graph["jonny"] = {}

local function search(name)
local search_queue = deque:new()
for _, value in pairs(graph[name]) do
search_queue:push_right(value)
end
-- This array is how you keep track of which people you've searched before.
local searched = {}
while search_queue:len() > 0 do
local person = search_queue:pop_left()
-- Only search this person if you haven't already searched them.
if not searched[person] then
if person_is_seller(person) then
print(person .. " is a mango seller!")
return true
else
for _, value in pairs(graph[person]) do
search_queue:push_right(value)
end
-- Marks this person as searched
searched[person] = true
end
end
end
return false
end

search("you")
46 changes: 46 additions & 0 deletions 06_breadth-first_search/lua/deque.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
deque = {}

function deque:new()
self.__index = self
return setmetatable({first = 0, last = -1}, self)
end

function deque:len()
return self.last - self.first + 1
end

function deque:push_left(value)
local first = self.first - 1
self.first = first
self[first] = value
end

function deque:push_right(value)
local last = self.last + 1
self.last = last
self[last] = value
end

function deque:pop_left()
local first = self.first
if first > self.last then
error "deque is empty"
end
local value = self[first]
self[first] = nil
self.first = first + 1
return value
end

function deque:pop_right()
local last = self.last
if self.first > last then
error "deque is empty"
end
local value = self[last]
self[last] = nil
self.last = last - 1
return value
end

return deque
72 changes: 72 additions & 0 deletions 07_dijkstras_algorithm/lua/01_dijkstras_algorithm.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
-- the graph
local graph = {}
graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2

graph["a"] = {}
graph["a"]["fin"] = 1

graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["fin"] = 5

graph["fin"] = {}

-- the costs table
local infinity = math.huge
local costs = {}
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity

-- the parents table
local parents = {}
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = nil

local processed = {}

local function find_lowest_cost_node(costs)
local lowest_cost = math.huge
local lowest_cost_node = nil
-- Go through each node.
for node, cost in pairs(costs) do
-- If it's the lowest cost so far and hasn't been processed yet...
if cost < lowest_cost and not processed[node] then
-- ... set it as the new lowest-cost node.
lowest_cost = cost
lowest_cost_node = node
end
end
return lowest_cost_node
end

-- Find the lowest-cost node that you haven't processed yet.
local node = find_lowest_cost_node(costs)
-- If you've processed all the nodes, this while loop is done.
while node ~= nil do
local cost = costs[node]
-- Go through all the neighbors of this node.
local neighbors = graph[node]
for n, n_cost in pairs(neighbors) do
local new_cost = cost + n_cost
-- If it's cheaper to get to this neighbor by going through this node...
if costs[n] > new_cost then
-- ... update the cost for this node.
costs[n] = new_cost
-- This node becomes the new parent for this neighbor.
parents[n] = node
end
end
-- Mark the node as processed.
processed[node] = true
-- Find the next node to process, and loop.
node = find_lowest_cost_node(costs)
end

print("Cost from the start to each node:")
for key, value in pairs(costs) do
print(key .. ": " .. value)
end
31 changes: 31 additions & 0 deletions 08_greedy_algorithms/lua/01_set_covering.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
-- Custom set module
require "set"

-- You pass an array in, and it gets converted to a set.
local states_needed = set.new({"mt", "wa", "or", "id", "nv", "ut", "ca", "az"})

local stations = {}
stations["kone"] = set.new({"id", "nv", "ut"})
stations["ktwo"] = set.new({"wa", "id", "mt"})
stations["kthree"] = set.new({"or", "nv", "ca"})
stations["kfour"] = set.new({"nv", "ut"})
stations["kfive"] = set.new({"ca", "az"})

local final_stations = set.new()

while next(states_needed) ~= nil do
local best_station = nil
local states_covered = set.new()
for station, states in pairs(stations) do
local covered = states_needed * states
if covered:len() > states_covered:len() then
best_station = station
states_covered = covered
end
end

states_needed = states_needed - states_covered
final_stations:add(best_station)
end

print(final_stations)
79 changes: 79 additions & 0 deletions 08_greedy_algorithms/lua/set.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
set = {}
local mt = {__index = set}

function set.new(array)
local s = {}
if array ~= nil then
for _, value in pairs(array) do
s[value] = true
end
end
return setmetatable(s, mt)
end

function set:add(value)
if value ~= nil then
self[value] = true
end
return self
end

function set:remove(value)
if value ~= nil then
self[value] = nil
end
return self
end

function set:len()
local len = 0
for _ in pairs(self) do
len = len + 1
end
return len
end

function set.union(a, b)
local result = set.new()
for key in pairs(a) do
result[key] = true
end
for key in pairs(b) do
result[key] = true
end
return result
end

function set.difference(a, b)
local result = set.new()
for key in pairs(a) do
result[key] = true
end
for key in pairs(b) do
result[key] = nil
end
return result
end

function set.intersection(a, b)
local result = set.new()
for key in pairs(a) do
result[key] = b[key]
end
return result
end

function set.tostring(s)
local array = {}
for key in pairs(s) do
array[#array + 1] = tostring(key)
end
return "{" .. table.concat(array, ", ") .. "}"
end

mt.__add = set.union
mt.__sub = set.difference
mt.__mul = set.intersection
mt.__tostring = set.tostring

return set
7 changes: 7 additions & 0 deletions 09_dynamic_programming/lua/01_longest_common_subsequence.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
if word_a[i] == word_b[j] then
-- The letters match.
cell[i][j] = cell[i - 1][j - 1] + 1
else
-- The letters don't match.
cell[i][j] = math.max(cell[i - 1][j], cell[i][j - 1])
end