diff --git a/config.json b/config.json index 8e4aa5a..e152679 100644 --- a/config.json +++ b/config.json @@ -467,6 +467,14 @@ "prerequisites": [], "difficulty": 3 }, + { + "slug": "saddle-points", + "name": "Saddle Points", + "uuid": "13894e67-0f5f-42d7-86b3-4ce12b9cba4e", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "scrabble-score", "name": "Scrabble Score", diff --git a/exercises/practice/saddle-points/.docs/instructions.md b/exercises/practice/saddle-points/.docs/instructions.md new file mode 100644 index 0000000..f69cdab --- /dev/null +++ b/exercises/practice/saddle-points/.docs/instructions.md @@ -0,0 +1,27 @@ +# Instructions + +Your task is to find the potential trees where you could build your tree house. + +The data company provides the data as grids that show the heights of the trees. +The rows of the grid represent the east-west direction, and the columns represent the north-south direction. + +An acceptable tree will be the largest in its row, while being the smallest in its column. + +A grid might not have any good trees at all. +Or it might have one, or even several. + +Here is a grid that has exactly one candidate tree. + +```text + ↓ + 1 2 3 4 + |----------- + 1 | 9 8 7 8 +→ 2 |[5] 3 2 4 + 3 | 6 6 7 1 +``` + +- Row 2 has values 5, 3, 2, and 4. The largest value is 5. +- Column 1 has values 9, 5, and 6. The smallest value is 5. + +So the point at `[2, 1]` (row: 2, column: 1) is a great spot for a tree house. diff --git a/exercises/practice/saddle-points/.docs/introduction.md b/exercises/practice/saddle-points/.docs/introduction.md new file mode 100644 index 0000000..34b2c77 --- /dev/null +++ b/exercises/practice/saddle-points/.docs/introduction.md @@ -0,0 +1,11 @@ +# Introduction + +You plan to build a tree house in the woods near your house so that you can watch the sun rise and set. + +You've obtained data from a local survey company that show the height of every tree in each rectangular section of the map. +You need to analyze each grid on the map to find good trees for your tree house. + +A good tree is both: + +- taller than every tree to the east and west, so that you have the best possible view of the sunrises and sunsets. +- shorter than every tree to the north and south, to minimize the amount of tree climbing. diff --git a/exercises/practice/saddle-points/.meta/config.json b/exercises/practice/saddle-points/.meta/config.json new file mode 100644 index 0000000..7e4a3c5 --- /dev/null +++ b/exercises/practice/saddle-points/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "saddle_points.vim" + ], + "test": [ + "saddle_points.vader" + ], + "example": [ + ".meta/example.vim" + ] + }, + "blurb": "Detect saddle points in a matrix.", + "source": "J Dalbey's Programming Practice problems", + "source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" +} diff --git a/exercises/practice/saddle-points/.meta/example.vim b/exercises/practice/saddle-points/.meta/example.vim new file mode 100644 index 0000000..0fe905f --- /dev/null +++ b/exercises/practice/saddle-points/.meta/example.vim @@ -0,0 +1,31 @@ +function! SaddlePoints(matrix) abort + if empty(a:matrix) + return [] + endif + + let l:row_count = len(a:matrix) + let l:col_count = len(a:matrix[0]) + let l:highest_in_a_row = map(copy(a:matrix), 'max(v:val)') + let l:lowest_in_a_column = [] + for l:i in range(l:col_count) + let l:values = [] + for l:j in range(l:row_count) + call add(l:values, a:matrix[l:j][l:i]) + endfor + call add(l:lowest_in_a_column, min(l:values)) + endfor + + let l:saddle_points = [] + + for l:i in range(l:row_count) + for l:j in range(l:col_count) + let l:current = a:matrix[l:i][l:j] + if l:current == l:highest_in_a_row[l:i] && + \ l:current == l:lowest_in_a_column[l:j] + call add(l:saddle_points, {'row': l:i + 1, 'column': l:j + 1}) + endif + endfor + endfor + + return l:saddle_points +endfunction diff --git a/exercises/practice/saddle-points/.meta/tests.toml b/exercises/practice/saddle-points/.meta/tests.toml new file mode 100644 index 0000000..ca00852 --- /dev/null +++ b/exercises/practice/saddle-points/.meta/tests.toml @@ -0,0 +1,37 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[3e374e63-a2e0-4530-a39a-d53c560382bd] +description = "Can identify single saddle point" + +[6b501e2b-6c1f-491f-b1bb-7f278f760534] +description = "Can identify that empty matrix has no saddle points" + +[8c27cc64-e573-4fcb-a099-f0ae863fb02f] +description = "Can identify lack of saddle points when there are none" + +[6d1399bd-e105-40fd-a2c9-c6609507d7a3] +description = "Can identify multiple saddle points in a column" + +[3e81dce9-53b3-44e6-bf26-e328885fd5d1] +description = "Can identify multiple saddle points in a row" + +[88868621-b6f4-4837-bb8b-3fad8b25d46b] +description = "Can identify saddle point in bottom right corner" + +[5b9499ca-fcea-4195-830a-9c4584a0ee79] +description = "Can identify saddle points in a non square matrix" + +[ee99ccd2-a1f1-4283-ad39-f8c70f0cf594] +description = "Can identify that saddle points in a single column matrix are those with the minimum value" + +[63abf709-a84b-407f-a1b3-456638689713] +description = "Can identify that saddle points in a single row matrix are those with the maximum value" diff --git a/exercises/practice/saddle-points/saddle_points.vader b/exercises/practice/saddle-points/saddle_points.vader new file mode 100644 index 0000000..96e43c4 --- /dev/null +++ b/exercises/practice/saddle-points/saddle_points.vader @@ -0,0 +1,74 @@ +Execute (Can identify single saddle point): + let g:matrix = [[9, 8, 7], + \ [5, 3, 2], + \ [6, 6, 7]] + let g:expected = [{'row': 2, 'column': 1}] + let g:result = sort(SaddlePoints(g:matrix)) + AssertEqual g:expected, g:result + +Execute (Can identify that empty matrix has no saddle points): + let g:matrix = [[]] + let g:expected = [] + let g:result = sort(SaddlePoints(g:matrix)) + AssertEqual g:expected, g:result + +Execute (Can identify lack of saddle points when there are none): + let g:matrix = [[1, 2, 3], + \ [3, 1, 2], + \ [2, 3, 1]] + let g:expected = [] + let g:result = sort(SaddlePoints(g:matrix)) + AssertEqual g:expected, g:result + +Execute (Can identify multiple saddle points in a column): + let g:matrix = [[4, 5, 4], + \ [3, 5, 5], + \ [1, 5, 4]] + let g:expected = [{'row': 1, 'column': 2}, + \ {'row': 2, 'column': 2}, + \ {'row': 3, 'column': 2}] + let g:result = sort(SaddlePoints(g:matrix)) + AssertEqual g:expected, g:result + +Execute (Can identify multiple saddle points in a row): + let g:matrix = [[6, 7, 8], + \ [5, 5, 5], + \ [7, 5, 6]] + let g:expected = [{'row': 2, 'column': 1}, + \ {'row': 2, 'column': 2}, + \ {'row': 2, 'column': 3}] + let g:result = sort(SaddlePoints(g:matrix)) + AssertEqual g:expected, g:result + +Execute (Can identify saddle point in bottom right corner): + let g:matrix = [[8, 7, 9], + \ [6, 7, 6], + \ [3, 2, 5]] + let g:expected = [{'row': 3, 'column': 3}] + let g:result = sort(SaddlePoints(g:matrix)) + AssertEqual g:expected, g:result + +Execute (Can identify saddle points in a non square matrix): + let g:matrix = [[3, 1, 3], + \ [3, 2, 4]] + let g:expected = [{'row': 1, 'column': 1}, + \ {'row': 1, 'column': 3}] + let g:result = sort(SaddlePoints(g:matrix)) + AssertEqual g:expected, g:result + +Execute (Can identify that saddle points in a single column matrix are those with the minimum value): + let g:matrix = [[2], + \ [1], + \ [4], + \ [1]] + let g:expected = [{'row': 2, 'column': 1}, + \ {'row': 4, 'column': 1}] + let g:result = sort(SaddlePoints(g:matrix)) + AssertEqual g:expected, g:result + +Execute (Can identify that saddle points in a single row matrix are those with the maximum value): + let g:matrix = [[2, 5, 3, 5]] + let g:expected = [{'row': 1, 'column': 2}, + \ {'row': 1, 'column': 4}] + let g:result = sort(SaddlePoints(g:matrix)) + AssertEqual g:expected, g:result diff --git a/exercises/practice/saddle-points/saddle_points.vim b/exercises/practice/saddle-points/saddle_points.vim new file mode 100644 index 0000000..767cafa --- /dev/null +++ b/exercises/practice/saddle-points/saddle_points.vim @@ -0,0 +1,17 @@ +" +" Given a 2D matrix of tree heights, return a list of +" saddle points that are the tallest in their row +" and the shortest in their column. The list can be +" returned in any order. +" +" Example: +" :echo SaddlePoints([[4, 5, 4], +" [3, 5, 5], +" [1, 5, 4]]) +" [{'row': 1, 'column': 2}, +" {'row': 2, 'column': 2}, +" {'row': 3, 'column': 2}] +" +function! SaddlePoints(matrix) abort + " your code goes here +endfunction