From a4c122b77807107237ac9ce34527ab7b70b9f819 Mon Sep 17 00:00:00 2001 From: Albert Hu Date: Thu, 27 Apr 2017 23:37:43 -0700 Subject: [PATCH 1/6] Day19: start --- day19/README.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 day19/README.md diff --git a/day19/README.md b/day19/README.md new file mode 100644 index 0000000..5e9fb3b --- /dev/null +++ b/day19/README.md @@ -0,0 +1,48 @@ +question of the day: https://leetcode.com/problems/01-matrix/#/description + +Given a matrix consists of 0 and 1, find the distance of +the nearest 0 for each cell. + +The distance between two adjacent cells is 1. + +*Example 1:* + +Input: + +```ruby +0 0 0 +0 1 0 +0 0 0 +``` + +Output: + +```ruby +0 0 0 +0 1 0 +0 0 0 +``` + +*Example 2:* + +Input: + +```ruby +0 0 0 +0 1 0 +1 1 1 +``` + +Output: + +```ruby +0 0 0 +0 1 0 +1 2 1 +``` + +## Ideas + +## Code + +## Follow up \ No newline at end of file From 90d563608b2800e93c3a00d38f4da1b362dac84f Mon Sep 17 00:00:00 2001 From: Albert Hu Date: Fri, 28 Apr 2017 00:31:53 -0700 Subject: [PATCH 2/6] Day19: type out ideas --- day19/README.md | 13 +++++++++++++ day19/matrixCountours.rb | 0 2 files changed, 13 insertions(+) create mode 100644 day19/matrixCountours.rb diff --git a/day19/README.md b/day19/README.md index 5e9fb3b..139a375 100644 --- a/day19/README.md +++ b/day19/README.md @@ -43,6 +43,19 @@ Output: ## Ideas +This is like drawing out a contour map. The 0's are the peaks of +hills and mountains, while the parts of the matrix that are far away +from any 0's are like the valleys. + +We can start from each peak and go outwards. It'd be a BFS-like +approach. Do a search through the whole matrix once first and find +where all the 0's are. Add each of those positions into a queue, +and then use that queue to start off a BFS. During this BFS, we +check the neighboring cells to see what the minimal value is that +we can place in this cell. + ## Code +[Ruby](./matrixCountours.rb) + ## Follow up \ No newline at end of file diff --git a/day19/matrixCountours.rb b/day19/matrixCountours.rb new file mode 100644 index 0000000..e69de29 From 652aa2d591199a67c2ebac108f437a05b79854ef Mon Sep 17 00:00:00 2001 From: Albert Hu Date: Fri, 28 Apr 2017 00:39:55 -0700 Subject: [PATCH 3/6] Day 19: add tests --- day19/README.md | 6 +++++ day19/matrixCountours.rb | 55 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/day19/README.md b/day19/README.md index 139a375..c760f57 100644 --- a/day19/README.md +++ b/day19/README.md @@ -41,6 +41,12 @@ Output: 1 2 1 ``` +Assumptions we can make: + +1. The number of elements of the given matrix will not exceed 10,000. +2. There are at least one 0 in the given matrix. +3. The cells are adjacent in only four directions: up, down, left and right. + ## Ideas This is like drawing out a contour map. The 0's are the peaks of diff --git a/day19/matrixCountours.rb b/day19/matrixCountours.rb index e69de29..74aacd0 100644 --- a/day19/matrixCountours.rb +++ b/day19/matrixCountours.rb @@ -0,0 +1,55 @@ +def countourDistances(matrix) + matrix +end + +######### +# Tests # +######### + +class AssertionError < RuntimeError +end + +def assert &block + raise AssertionError unless yield +end + +def tests + # edge cases + empty = [[]] + emptyOutput = [[]] + assert { countourDistances(empty) == emptyOutput } + + one = [[0]] + oneOutput = [[0]] + assert { countourDistances(one) == oneOutput } + + # other cases + matrix = [[1,1,1], + [1,0,1], + [1,1,1]] + + output = [[2,1,2], + [1,0,1], + [2,1,2]] + assert { countourDistances(matrix) == output } + + matrix1 = [[0,0,0], + [0,1,0], + [0,0,0]] + + output1 = [[0,0,0], + [0,1,0], + [0,0,0]] + assert { countourDistances(matrix1) == output1 } + + matrix2 = [[0,0,0], + [0,1,0], + [1,1,1]] + + output2 = [[0,0,0], + [0,1,0], + [1,2,1]] + assert { countourDistances(matrix2) == output2 } +end + +tests() \ No newline at end of file From b1c6d389508426798b7c5ea4912ec37a8fa99e74 Mon Sep 17 00:00:00 2001 From: Albert Hu Date: Fri, 28 Apr 2017 06:52:02 -0700 Subject: [PATCH 4/6] Day 19: uglyass code but fuggit it works --- day19/matrixCountours.rb | 69 +++++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/day19/matrixCountours.rb b/day19/matrixCountours.rb index 74aacd0..fe8d923 100644 --- a/day19/matrixCountours.rb +++ b/day19/matrixCountours.rb @@ -1,5 +1,58 @@ -def countourDistances(matrix) - matrix +def contourDistances(matrix) + rows, cols = matrix.size, matrix[0].size + + if rows == 0 || cols == 0 + return matrix + end + + contours = Array.new(rows).map { |x| [nil] * cols } + queue = [] + # start by finding 0s + for row in 0..rows-1 + for col in 0..cols-1 + if matrix[row][col] == 0 + queue << [row, col] + contours[row][col] = 0 + end + end + end + + # do bfs + while queue.size > 0 + current = queue.shift + row, col = current + contours[row][col] = getMinNeighbor(contours, row, col) + 1 + for i, j in [[row-1, col], [row, col-1], [row, col+1], [row+1, col]] + if withinBounds([i, j], rows, cols) && contours[i][j] == nil + queue << [i, j] + end + end + end + + contours +end + +def withinBounds(coordinate, rows, cols) + x, y = coordinate + x >= 0 && x < rows && y >= 0 && y < cols +end + +def getMinNeighbor(matrix, row, col) + if matrix[row][col] == 0 + return -1 + end + + vals = [] + rows, cols = matrix.size, matrix[0].size + for i, j in [[row-1, col], [row, col-1], [row, col+1], [row+1, col]] + if withinBounds([i, j], rows, cols) + if matrix[i][j] != nil + vals << matrix[i][j] + end + end + end + + vals.min end ######### @@ -17,11 +70,11 @@ def tests # edge cases empty = [[]] emptyOutput = [[]] - assert { countourDistances(empty) == emptyOutput } + assert { contourDistances(empty) == emptyOutput } one = [[0]] oneOutput = [[0]] - assert { countourDistances(one) == oneOutput } + assert { contourDistances(one) == oneOutput } # other cases matrix = [[1,1,1], @@ -31,7 +84,7 @@ def tests output = [[2,1,2], [1,0,1], [2,1,2]] - assert { countourDistances(matrix) == output } + assert { contourDistances(matrix) == output } matrix1 = [[0,0,0], [0,1,0], @@ -40,7 +93,7 @@ def tests output1 = [[0,0,0], [0,1,0], [0,0,0]] - assert { countourDistances(matrix1) == output1 } + assert { contourDistances(matrix1) == output1 } matrix2 = [[0,0,0], [0,1,0], @@ -49,7 +102,7 @@ def tests output2 = [[0,0,0], [0,1,0], [1,2,1]] - assert { countourDistances(matrix2) == output2 } + assert { contourDistances(matrix2) == output2 } end -tests() \ No newline at end of file +tests() From a28028e5bf0ea538bef156e9f3b38da3abdff855 Mon Sep 17 00:00:00 2001 From: Albert Hu Date: Fri, 28 Apr 2017 06:54:55 -0700 Subject: [PATCH 5/6] Day 19: update readme with runtime analysis --- day19/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/day19/README.md b/day19/README.md index c760f57..93aec2d 100644 --- a/day19/README.md +++ b/day19/README.md @@ -60,6 +60,11 @@ and then use that queue to start off a BFS. During this BFS, we check the neighboring cells to see what the minimal value is that we can place in this cell. +This solution is `O(n)` to find the 0s, and then `O(n)` to run the +BFS. My implementation also requires `O(1)` space, although I think +it's possible to modify the matrix in-place with some more clever +checking. + ## Code [Ruby](./matrixCountours.rb) From 6424ebb0491a17d532f84ec7a7e121578cace14d Mon Sep 17 00:00:00 2001 From: Albert Hu Date: Fri, 28 Apr 2017 13:52:03 -0700 Subject: [PATCH 6/6] Day 19: fix space analysis --- day19/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/day19/README.md b/day19/README.md index 93aec2d..6b4d032 100644 --- a/day19/README.md +++ b/day19/README.md @@ -61,7 +61,7 @@ check the neighboring cells to see what the minimal value is that we can place in this cell. This solution is `O(n)` to find the 0s, and then `O(n)` to run the -BFS. My implementation also requires `O(1)` space, although I think +BFS. My implementation also requires `O(n)` space, although I think it's possible to modify the matrix in-place with some more clever checking. @@ -69,4 +69,4 @@ checking. [Ruby](./matrixCountours.rb) -## Follow up \ No newline at end of file +## Follow up