From c1b77c588e5bd5e7cff3587fe389d0b003dc51e6 Mon Sep 17 00:00:00 2001 From: cojenco Date: Sat, 12 Sep 2020 17:32:08 -0700 Subject: [PATCH 1/4] pass tests for group_anagrams --- lib/exercises.rb | 78 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 4 deletions(-) diff --git a/lib/exercises.rb b/lib/exercises.rb index e1b3850..58cf38c 100644 --- a/lib/exercises.rb +++ b/lib/exercises.rb @@ -1,19 +1,51 @@ # This method will return an array of arrays. # Each subarray will have strings which are anagrams of each other -# Time Complexity: ? -# Space Complexity: ? +# Time Complexity: O(n^2) where n is the number of strings? || O(n) where n is the total number of characters? +# Space Complexity: O(n) where a new hash is storing the n # of strings def grouped_anagrams(strings) - raise NotImplementedError, "Method hasn't been implemented yet!" + return [] if strings.empty? + groups = Hash.new() + + # sort each string so we can compare if they look the same == anagrams + strings.each do |string| + sorted_str = string.split("").sort.join + + # store data into groups + if groups[sorted_str] + groups[sorted_str] << string + else + groups[sorted_str] = [] + groups[sorted_str] << string + end + end + # print groups + + return groups.values end + # This method will return the k most common elements # in the case of a tie it will select the first occuring element. # Time Complexity: ? # Space Complexity: ? def top_k_frequent_elements(list, k) - raise NotImplementedError, "Method hasn't been implemented yet!" + # loop through list and create hash: num => count + # then search for the k-most frequent values mapped to key + return [] if list.empty? + + count = {} + list.each do |num| + count[num] ? count[num] += 1 : count[num] = 1 + end + # print count + + ans = count.keys.max_by(k){|key| count[key] } + # https://apidock.com/ruby/Enumerable/max_by + # print count.keys + # print ans + return ans end @@ -27,3 +59,41 @@ def top_k_frequent_elements(list, k) def valid_sudoku(table) raise NotImplementedError, "Method hasn't been implemented yet!" end + + +# Thought I could use a hash function to solve grouped_anagrams, but realized the sum/math would cause incorrect results +# def grouped_anagrams(strings) +# # hash function and add sum +# # 2 factors: score by alphabet and string length # can I assume they are anagrams if both factors meet? +# return [] if strings.empty? +# alpha = { +# "a" => 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5, +# "f" => 6, "g" => 7, "h" => 8, "i" => 9, "j" => 10, +# "k" => 11, "l" => 12, "m" => 13, "n" => 14, "o" => 15, +# "p" => 16, "q" => 17, "r" => 18, "s" => 19, "t" => 20, +# "u" => 21, "v" => 22, "w" => 23, "x" => 24, "y" => 25, "z" => 26, +# } +# groups = Hash.new() + +# strings.each do |string| +# # loop through each letter and count total score # get length +# l = 0 +# sum = 0 +# while l < string.length +# char = string[l] +# sum += alpha[char] +# l += 1 +# end + +# # store data into groups +# if groups[sum] +# groups[sum] << string +# else +# groups[sum] = [] +# groups[sum] << string +# end +# end +# # print groups + +# return groups.values +# end \ No newline at end of file From e0c95f293e32159e3ef76ce1d01ca863851140f7 Mon Sep 17 00:00:00 2001 From: cojenco Date: Sat, 12 Sep 2020 22:32:07 -0700 Subject: [PATCH 2/4] revise functions and pass all tests --- lib/exercises.rb | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/exercises.rb b/lib/exercises.rb index 58cf38c..2d47ad4 100644 --- a/lib/exercises.rb +++ b/lib/exercises.rb @@ -28,24 +28,28 @@ def grouped_anagrams(strings) # This method will return the k most common elements # in the case of a tie it will select the first occuring element. -# Time Complexity: ? -# Space Complexity: ? +# Time Complexity: O(nlogn) since I'm calling a sort_by enumerable +# Space Complexity: O(n) def top_k_frequent_elements(list, k) # loop through list and create hash: num => count # then search for the k-most frequent values mapped to key return [] if list.empty? - count = {} list.each do |num| count[num] ? count[num] += 1 : count[num] = 1 end - # print count - - ans = count.keys.max_by(k){|key| count[key] } - # https://apidock.com/ruby/Enumerable/max_by - # print count.keys - # print ans + + sorted_hash = count.sort_by {|k, v| -v} # hash#sort_by returns a matrix (2-D array) + ans = [] + i = 0 + while i < k + ans << sorted_hash[i][0] + i += 1 + end + return ans + # ans = count.keys.max_by(k){|key| count[key] } + # https://apidock.com/ruby/Enumerable/max_by # WHY?! what does the max_by actually do?! end From 597449563f51a6044095fa814e32b555370abd96 Mon Sep 17 00:00:00 2001 From: cojenco Date: Sun, 13 Sep 2020 14:18:40 -0700 Subject: [PATCH 3/4] pass all tests for 3 exercises --- lib/exercises.rb | 41 ++++++++++++++++++++++++++++++++++++++--- test/exercises_test.rb | 2 +- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/lib/exercises.rb b/lib/exercises.rb index 2d47ad4..f4ce0cf 100644 --- a/lib/exercises.rb +++ b/lib/exercises.rb @@ -58,10 +58,45 @@ def top_k_frequent_elements(list, k) # Each element can either be a ".", or a digit 1-9 # The same digit cannot appear twice or more in the same # row, column or 3x3 subgrid -# Time Complexity: ? -# Space Complexity: ? +# Reference: https://www.tutorialspoint.com/valid-sudoku-in-python +# Time Complexity: O(n^2) where n is the length of the input table and since table is a 2d array +# Space Complexity: O(1) where the extra hashes are constant tracking 1~9 def valid_sudoku(table) - raise NotImplementedError, "Method hasn't been implemented yet!" + # 1. check rows 2. check columns 3. check sub-boxes + # utilize the indices in the 2D-array and use hashed to keep track + (0...9).each do |i| + row = {} + col = {} + sub_box = {} + # below marks the anchor points for each sub-box: [0,0], [0,3], [0,6], [3,0], [3,3], [3,6], [6,0], [6,3], [6,6] + sub_row = 3 * (i / 3) + sub_col = 3 * (i % 3) + + (0...9).each do |j| + # check rows + if table[i][j] =~ /\d/ && row[table[i][j]] + return false + else + row[table[i][j]] = 1 + end + # check columns + if table[j][i] =~ /\d/ && col[table[j][i]] + return false + else + col[table[j][i]] = 1 + end + # check sub-boxes: scope the boundaries of sub-boxes according to the anchor points sub_row and sub_col + sr = sub_row + (j / 3) + sc = sub_col + (j % 3) + if table[sr][sc] =~ /\d/ && sub_box[table[sr][sc]] + return false + else + sub_box[table[sr][sc]] = 1 + end + end + end + + return true end diff --git a/test/exercises_test.rb b/test/exercises_test.rb index dd93104..710370e 100644 --- a/test/exercises_test.rb +++ b/test/exercises_test.rb @@ -131,7 +131,7 @@ end - xdescribe "valid sudoku" do + describe "valid sudoku" do it "works for the table given in the README" do # Arrange table = [ From 82f5b2a0af643a8d25c20c1c3688289509e18bc1 Mon Sep 17 00:00:00 2001 From: cojenco Date: Thu, 24 Sep 2020 14:40:06 -0700 Subject: [PATCH 4/4] revise time complexity comments --- lib/exercises.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/exercises.rb b/lib/exercises.rb index f4ce0cf..870c57b 100644 --- a/lib/exercises.rb +++ b/lib/exercises.rb @@ -1,7 +1,7 @@ # This method will return an array of arrays. # Each subarray will have strings which are anagrams of each other -# Time Complexity: O(n^2) where n is the number of strings? || O(n) where n is the total number of characters? +# Time Complexity: O(n) since we're only looping through the words once # Space Complexity: O(n) where a new hash is storing the n # of strings def grouped_anagrams(strings) @@ -59,7 +59,7 @@ def top_k_frequent_elements(list, k) # The same digit cannot appear twice or more in the same # row, column or 3x3 subgrid # Reference: https://www.tutorialspoint.com/valid-sudoku-in-python -# Time Complexity: O(n^2) where n is the length of the input table and since table is a 2d array +# Time Complexity: O(1) since a Sudoku board is always 9x9 (81 cells), scaling never changes # Space Complexity: O(1) where the extra hashes are constant tracking 1~9 def valid_sudoku(table) # 1. check rows 2. check columns 3. check sub-boxes