From e073665523d7d7e1b27d0c0711b064b867ca3310 Mon Sep 17 00:00:00 2001 From: zhangjiong Date: Wed, 18 Oct 2017 13:27:46 +0800 Subject: [PATCH 1/4] Add Lua code for chapter 6 --- .../lua/01_breadth-first_search.lua | 44 ++++++++++++++++++ 06_breadth-first_search/lua/deque.lua | 46 +++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 06_breadth-first_search/lua/01_breadth-first_search.lua create mode 100644 06_breadth-first_search/lua/deque.lua diff --git a/06_breadth-first_search/lua/01_breadth-first_search.lua b/06_breadth-first_search/lua/01_breadth-first_search.lua new file mode 100644 index 00000000..fb4b0235 --- /dev/null +++ b/06_breadth-first_search/lua/01_breadth-first_search.lua @@ -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") \ No newline at end of file diff --git a/06_breadth-first_search/lua/deque.lua b/06_breadth-first_search/lua/deque.lua new file mode 100644 index 00000000..62515f2d --- /dev/null +++ b/06_breadth-first_search/lua/deque.lua @@ -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 \ No newline at end of file From bc8cf0db4bb6e486d9eb24de652a53ba7ca46460 Mon Sep 17 00:00:00 2001 From: zhangjiong Date: Wed, 18 Oct 2017 13:28:52 +0800 Subject: [PATCH 2/4] Add Lua code for chapter 7 --- .../lua/01_dijkstras_algorithm.lua | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 07_dijkstras_algorithm/lua/01_dijkstras_algorithm.lua diff --git a/07_dijkstras_algorithm/lua/01_dijkstras_algorithm.lua b/07_dijkstras_algorithm/lua/01_dijkstras_algorithm.lua new file mode 100644 index 00000000..2c3f79fd --- /dev/null +++ b/07_dijkstras_algorithm/lua/01_dijkstras_algorithm.lua @@ -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 \ No newline at end of file From 5833db66829683b7916fb44ba6919fca7c47f5e0 Mon Sep 17 00:00:00 2001 From: zhangjiong Date: Wed, 18 Oct 2017 13:29:44 +0800 Subject: [PATCH 3/4] Add Lua code for chapter 8 --- 08_greedy_algorithms/lua/01_set_covering.lua | 31 ++++++++ 08_greedy_algorithms/lua/set.lua | 79 ++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 08_greedy_algorithms/lua/01_set_covering.lua create mode 100644 08_greedy_algorithms/lua/set.lua diff --git a/08_greedy_algorithms/lua/01_set_covering.lua b/08_greedy_algorithms/lua/01_set_covering.lua new file mode 100644 index 00000000..1c6bb82c --- /dev/null +++ b/08_greedy_algorithms/lua/01_set_covering.lua @@ -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) \ No newline at end of file diff --git a/08_greedy_algorithms/lua/set.lua b/08_greedy_algorithms/lua/set.lua new file mode 100644 index 00000000..1f351804 --- /dev/null +++ b/08_greedy_algorithms/lua/set.lua @@ -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 \ No newline at end of file From f86439810299e8de7c7517f08d69e97fd352fc1c Mon Sep 17 00:00:00 2001 From: zhangjiong Date: Wed, 18 Oct 2017 13:30:33 +0800 Subject: [PATCH 4/4] Add Lua code for chapter 9 --- .../lua/01_longest_common_subsequence.lua | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 09_dynamic_programming/lua/01_longest_common_subsequence.lua diff --git a/09_dynamic_programming/lua/01_longest_common_subsequence.lua b/09_dynamic_programming/lua/01_longest_common_subsequence.lua new file mode 100644 index 00000000..b027bd44 --- /dev/null +++ b/09_dynamic_programming/lua/01_longest_common_subsequence.lua @@ -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 \ No newline at end of file