From 4b5ab7c1703260094585365c688e6c0995c4d977 Mon Sep 17 00:00:00 2001 From: beauttie <15842537+beauttie@users.noreply.github.com> Date: Mon, 19 Apr 2021 23:33:13 -0700 Subject: [PATCH 1/8] Implement grouped_anagrams to pass tests --- lib/exercises.rb | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/exercises.rb b/lib/exercises.rb index e1b3850..64c7cf8 100644 --- a/lib/exercises.rb +++ b/lib/exercises.rb @@ -1,11 +1,24 @@ # 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) +# Space Complexity: O(n) def grouped_anagrams(strings) - raise NotImplementedError, "Method hasn't been implemented yet!" + hash = Hash.new + strings.each do |string| + if hash[str_to_int(string)] + hash[str_to_int(string)] << string + else + hash[str_to_int(string)] = [string] + end + end + + return hash.values +end + +def str_to_int(string) + return string.chars.map { |char| char.ord }.sum end # This method will return the k most common elements @@ -13,7 +26,12 @@ def grouped_anagrams(strings) # Time Complexity: ? # Space Complexity: ? def top_k_frequent_elements(list, k) - raise NotImplementedError, "Method hasn't been implemented yet!" + hash = Hash.new(0) + list.each do |int| + hash[int] += 1 + end + + end From a859e23edf748a9966c9eaae97370bab3e44dbc4 Mon Sep 17 00:00:00 2001 From: beauttie <15842537+beauttie@users.noreply.github.com> Date: Tue, 20 Apr 2021 00:01:23 -0700 Subject: [PATCH 2/8] Implement top_k_frequent_elements to pass tests --- lib/exercises.rb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/exercises.rb b/lib/exercises.rb index 64c7cf8..8b80ebd 100644 --- a/lib/exercises.rb +++ b/lib/exercises.rb @@ -24,14 +24,18 @@ def str_to_int(string) # 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: ? +# Space Complexity: O(n) def top_k_frequent_elements(list, k) + return list if list.empty? || list.length == 1 + hash = Hash.new(0) - list.each do |int| - hash[int] += 1 - end + list.each { |int| hash[int] += 1 } + + nested_array = hash.sort_by { |k, v| -v } - + k_most_frequent = [] + k.times { |i| k_most_frequent << nested_array[i][0] } + return k_most_frequent end From 58c5649afe36ec6e77a902352f99f770badd50ac Mon Sep 17 00:00:00 2001 From: beauttie <15842537+beauttie@users.noreply.github.com> Date: Wed, 21 Apr 2021 21:45:50 -0700 Subject: [PATCH 3/8] Implement valid_sudoku to pass tests --- lib/exercises.rb | 65 +++++++++++++++++++++++++++++++++++++++--- test/exercises_test.rb | 2 +- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/lib/exercises.rb b/lib/exercises.rb index 8b80ebd..73185ad 100644 --- a/lib/exercises.rb +++ b/lib/exercises.rb @@ -23,7 +23,7 @@ def str_to_int(string) # This method will return the k most common elements # in the case of a tie it will select the first occuring element. -# Time Complexity: ? +# Time Complexity: O(n log n) # Space Complexity: O(n) def top_k_frequent_elements(list, k) return list if list.empty? || list.length == 1 @@ -44,8 +44,65 @@ 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: ? +# Time Complexity: O(1) because the table has nine rows and columns +# Space Complexity: O(1) because each hash will store up to nine cells def valid_sudoku(table) - raise NotImplementedError, "Method hasn't been implemented yet!" + return valid_rows(table) && valid_columns(table) && valid_subboxes(table) +end + +def valid_cell(char) + return char != "." && /[1-9]/.match(char) +end + +def valid_rows(table) + hash_row = Hash.new + table.each do |row| + # Each row is an array + row.each do |cell| + return false if hash_row[cell] && valid_cell(cell) + hash_row[cell] = true + end + hash_row.clear + end + + return true +end + +def valid_columns(table) + hash_column = Hash.new + i = 0 + j = 0 + while j < table[i].length + # Checks column + while i < table.length + return false if hash_column[table[i][j]] && valid_cell(table[i][j]) + hash_column[table[i][j]] = true + i += 1 + end + hash_column.clear + # Reset row number back to zero + i = 0 + j += 1 + end + + return true +end + +def valid_subboxes(table) + hash_subbox = Hash.new + 3.times do |row_corner| + 3.times do |col_corner| + 3.times do |row| + 3.times do |col| + subbox_row = row + 3 * row_corner + subbox_col = col + 3 * col_corner + return false if hash_subbox[table[subbox_row][subbox_col]] && valid_cell(table[subbox_row][subbox_col]) + hash_subbox[table[subbox_row][subbox_col]] = true + end + end + hash_subbox.clear + end + end + + return true end diff --git a/test/exercises_test.rb b/test/exercises_test.rb index 74646dc..8025075 100644 --- a/test/exercises_test.rb +++ b/test/exercises_test.rb @@ -151,7 +151,7 @@ end end - xdescribe "valid sudoku" do + describe "valid sudoku" do it "works for the table given in the README" do # Arrange table = [ From c14d6abc68ecd7a584d9382896609b8a388bd1ee Mon Sep 17 00:00:00 2001 From: beauttie <15842537+beauttie@users.noreply.github.com> Date: Wed, 21 Apr 2021 21:48:24 -0700 Subject: [PATCH 4/8] Replace instances of subbox with box --- lib/exercises.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/exercises.rb b/lib/exercises.rb index 73185ad..b4a1b77 100644 --- a/lib/exercises.rb +++ b/lib/exercises.rb @@ -47,7 +47,7 @@ def top_k_frequent_elements(list, k) # Time Complexity: O(1) because the table has nine rows and columns # Space Complexity: O(1) because each hash will store up to nine cells def valid_sudoku(table) - return valid_rows(table) && valid_columns(table) && valid_subboxes(table) + return valid_rows(table) && valid_columns(table) && valid_boxes(table) end def valid_cell(char) @@ -88,19 +88,19 @@ def valid_columns(table) return true end -def valid_subboxes(table) - hash_subbox = Hash.new +def valid_boxes(table) + hash_box = Hash.new 3.times do |row_corner| 3.times do |col_corner| 3.times do |row| 3.times do |col| - subbox_row = row + 3 * row_corner - subbox_col = col + 3 * col_corner - return false if hash_subbox[table[subbox_row][subbox_col]] && valid_cell(table[subbox_row][subbox_col]) - hash_subbox[table[subbox_row][subbox_col]] = true + box_row = row + 3 * row_corner + box_col = col + 3 * col_corner + return false if hash_box[table[box_row][box_col]] && valid_cell(table[box_row][box_col]) + hash_box[table[box_row][box_col]] = true end end - hash_subbox.clear + hash_box.clear end end From d39785b396d08e30d621ce9581d38375cc32ad77 Mon Sep 17 00:00:00 2001 From: beauttie <15842537+beauttie@users.noreply.github.com> Date: Wed, 21 Apr 2021 23:08:29 -0700 Subject: [PATCH 5/8] Improve time complexity of top_k_frequent_elements by increasing space usage --- lib/exercises.rb | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/exercises.rb b/lib/exercises.rb index b4a1b77..d18a7bd 100644 --- a/lib/exercises.rb +++ b/lib/exercises.rb @@ -23,7 +23,7 @@ def str_to_int(string) # This method will return the k most common elements # in the case of a tie it will select the first occuring element. -# Time Complexity: O(n log n) +# Time Complexity: O(n) # Space Complexity: O(n) def top_k_frequent_elements(list, k) return list if list.empty? || list.length == 1 @@ -31,10 +31,29 @@ def top_k_frequent_elements(list, k) hash = Hash.new(0) list.each { |int| hash[int] += 1 } - nested_array = hash.sort_by { |k, v| -v } + max_count = 0 + inverted_hash = Hash.new + hash.each do |key, value| + if inverted_hash[value] + inverted_hash[value] << key + else + inverted_hash[value] = [key] + end + + max_count = value if value > max_count + end + k_dup = k.dup k_most_frequent = [] - k.times { |i| k_most_frequent << nested_array[i][0] } + max_count.downto(1) do |key| + if inverted_hash[key] + inverted_hash[key].each do |int| + k_most_frequent << int if k_dup > 0 + k_dup -= 1 + end + end + end + return k_most_frequent end From e0152f7875b30ac25b7c709c69260593e0a94e6c Mon Sep 17 00:00:00 2001 From: beauttie <15842537+beauttie@users.noreply.github.com> Date: Wed, 21 Apr 2021 23:09:44 -0700 Subject: [PATCH 6/8] Rename variable --- lib/exercises.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/exercises.rb b/lib/exercises.rb index d18a7bd..1fd944d 100644 --- a/lib/exercises.rb +++ b/lib/exercises.rb @@ -45,9 +45,9 @@ def top_k_frequent_elements(list, k) k_dup = k.dup k_most_frequent = [] - max_count.downto(1) do |key| - if inverted_hash[key] - inverted_hash[key].each do |int| + max_count.downto(1) do |count| + if inverted_hash[count] + inverted_hash[count].each do |int| k_most_frequent << int if k_dup > 0 k_dup -= 1 end From e3aa46629dd7bcdbdf3469a6f7c2282fb2555801 Mon Sep 17 00:00:00 2001 From: beauttie <15842537+beauttie@users.noreply.github.com> Date: Wed, 21 Apr 2021 23:20:59 -0700 Subject: [PATCH 7/8] Fix logic inside last loop --- lib/exercises.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/exercises.rb b/lib/exercises.rb index 1fd944d..4b88f8c 100644 --- a/lib/exercises.rb +++ b/lib/exercises.rb @@ -48,8 +48,12 @@ def top_k_frequent_elements(list, k) max_count.downto(1) do |count| if inverted_hash[count] inverted_hash[count].each do |int| - k_most_frequent << int if k_dup > 0 - k_dup -= 1 + if k_dup > 0 + k_most_frequent << int + k_dup -= 1 + else + return k_most_frequent + end end end end From c28510aff304cfe14684f6bfefd3386e857c55b4 Mon Sep 17 00:00:00 2001 From: beauttie <15842537+beauttie@users.noreply.github.com> Date: Sat, 22 May 2021 15:29:43 -0700 Subject: [PATCH 8/8] Comment two approaches for what key to use in hash table --- lib/exercises.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/exercises.rb b/lib/exercises.rb index 4b88f8c..acdbaf4 100644 --- a/lib/exercises.rb +++ b/lib/exercises.rb @@ -4,6 +4,9 @@ # Time Complexity: O(n^2) # Space Complexity: O(n) +# sort the letters in the string alphabetically +# and use that sorted string as the key => O(n log n) +# or use a hash containing letter counts as the key def grouped_anagrams(strings) hash = Hash.new strings.each do |string|