From b65c3de28399daed7eeacbcda821485475e60532 Mon Sep 17 00:00:00 2001 From: TimoSci Date: Sun, 8 Dec 2019 12:40:40 +0100 Subject: [PATCH 1/4] separate search functionality from seller checking fucntionality according to single responsibility principle --- .../ruby/01_breadth-first_search.rb | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/06_breadth-first_search/ruby/01_breadth-first_search.rb b/06_breadth-first_search/ruby/01_breadth-first_search.rb index cb21b9f..a47e0d0 100644 --- a/06_breadth-first_search/ruby/01_breadth-first_search.rb +++ b/06_breadth-first_search/ruby/01_breadth-first_search.rb @@ -1,4 +1,4 @@ -def person_is_seller(name) +def person_is_seller?(name) name[-1] == "m" end @@ -24,17 +24,13 @@ def search(name) person = search_queue.shift # Only search this person if you haven't already searched them. next if searched.member?(person) - if person_is_seller(person) - puts "#{person} is a mango seller!" - return true - else - search_queue += @graph[person] + return person if yield person + search_queue += @graph[person] # Marks this person as searched - searched.push(person) - end + searched.push(person) end false end -search("you") +search("you"){|person| person_is_seller?(person) }.tap{|person| puts "#{person} is a mango seller!" if person} From 70ddf46cb3254718fc371255eaba0773e52aa63c Mon Sep 17 00:00:00 2001 From: TimoSci Date: Sun, 8 Dec 2019 12:56:36 +0100 Subject: [PATCH 2/4] represent record of searched verices as a hash for O(1) lookup --- 06_breadth-first_search/ruby/01_breadth-first_search.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/06_breadth-first_search/ruby/01_breadth-first_search.rb b/06_breadth-first_search/ruby/01_breadth-first_search.rb index a47e0d0..2aa15f3 100644 --- a/06_breadth-first_search/ruby/01_breadth-first_search.rb +++ b/06_breadth-first_search/ruby/01_breadth-first_search.rb @@ -18,16 +18,16 @@ def search(name) search_queue = [] search_queue += @graph[name] # This array is how you keep track of which people you've searched before. - searched = [] + searched = {} until search_queue.empty? person = search_queue.shift # Only search this person if you haven't already searched them. - next if searched.member?(person) + next if searched[person] return person if yield person search_queue += @graph[person] # Marks this person as searched - searched.push(person) + searched[person] = true end false From 1f6cf7d460c51f0a3d74de94a8765bb901c4da27 Mon Sep 17 00:00:00 2001 From: TimoSci Date: Sun, 8 Dec 2019 13:07:44 +0100 Subject: [PATCH 3/4] avoid use of global variables; it is more rubyish to represent a graph as a class --- .../ruby/01_breadth-first_search.rb | 57 ++++++++++--------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/06_breadth-first_search/ruby/01_breadth-first_search.rb b/06_breadth-first_search/ruby/01_breadth-first_search.rb index 2aa15f3..39e2fd7 100644 --- a/06_breadth-first_search/ruby/01_breadth-first_search.rb +++ b/06_breadth-first_search/ruby/01_breadth-first_search.rb @@ -2,35 +2,38 @@ def person_is_seller?(name) name[-1] == "m" end -@graph = {} +class Graph < Hash + def search(name) + search_queue = [] + search_queue += self[name] + # This array is how you keep track of which people you've searched before. + searched = {} -# %w(string1 string2 ...) is a shorter way to define arrays of strings -@graph["you"] = %w(alice bob claire) -@graph["bob"] = %w(anuj peggy) -@graph["alice"] = %w(peggy) -@graph["claire"] = %w(thom jonny) -@graph["anuj"] = [] -@graph["peggy"] = [] -@graph["thom"] = [] -@graph["jonny"] = [] + until search_queue.empty? + pp searched + person = search_queue.shift + # Only search this person if you haven't already searched them. + next if searched[person] + return person if yield person + search_queue += self[person] + # Marks this person as searched + searched[person] = true + end -def search(name) - search_queue = [] - search_queue += @graph[name] - # This array is how you keep track of which people you've searched before. - searched = {} - - until search_queue.empty? - person = search_queue.shift - # Only search this person if you haven't already searched them. - next if searched[person] - return person if yield person - search_queue += @graph[person] - # Marks this person as searched - searched[person] = true + false end - - false end -search("you"){|person| person_is_seller?(person) }.tap{|person| puts "#{person} is a mango seller!" if person} + +# %w(string1 string2 ...) is a shorter way to define arrays of strings +graph = Graph.new +graph["you"] = %w(alice bob claire) +graph["bob"] = %w(anuj peggy) +graph["alice"] = %w(peggy) +graph["claire"] = %w(thom jonny) +graph["anuj"] = [] +graph["peggy"] = [] +graph["thom"] = [] +graph["jonny"] = [] + +graph.search("you"){|person| person_is_seller?(person) }.tap{|person| puts "#{person} is a mango seller!" if person} From ff7ae962c173ae36c01f158a1ea178740356284a Mon Sep 17 00:00:00 2001 From: TimoSci Date: Sun, 8 Dec 2019 13:31:33 +0100 Subject: [PATCH 4/4] edit comments --- 06_breadth-first_search/ruby/01_breadth-first_search.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/06_breadth-first_search/ruby/01_breadth-first_search.rb b/06_breadth-first_search/ruby/01_breadth-first_search.rb index 39e2fd7..4436019 100644 --- a/06_breadth-first_search/ruby/01_breadth-first_search.rb +++ b/06_breadth-first_search/ruby/01_breadth-first_search.rb @@ -6,17 +6,16 @@ class Graph < Hash def search(name) search_queue = [] search_queue += self[name] - # This array is how you keep track of which people you've searched before. + # The "searched" Hash is how you keep track of which people you've searched before. We use a hash because hash lookups are fast! searched = {} until search_queue.empty? - pp searched person = search_queue.shift # Only search this person if you haven't already searched them. next if searched[person] return person if yield person search_queue += self[person] - # Marks this person as searched + # Marks this person as searched searched[person] = true end @@ -36,4 +35,5 @@ graph["peggy"] = [] graph["thom"] = [] graph["jonny"] = [] -graph.search("you"){|person| person_is_seller?(person) }.tap{|person| puts "#{person} is a mango seller!" if person} +# we begin the search from vertex "you" and pass the match criterion in the block, then we tap the search result +graph.search("you"){|person| person_is_seller?(person)}.tap{|person| puts "#{person} is a mango seller!" if person}