Skip to content

Commit

Permalink
geeksforgeeks: minimum initial points to reach destination
Browse files Browse the repository at this point in the history
  • Loading branch information
minizilla committed Dec 12, 2023
1 parent 800f1b9 commit ef73a72
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Minimum initial points to reach destination

Given a M*N grid with each cell consisting of positive, negative, or no points i.e., zero points.
From a cell (i, j) we can move to (i+1, j) or (i, j+1) and we can move to a cell only if we have positive points ( > 0 ) when we move to that cell.
Whenever we pass through a cell, points in that cell are added to our overall points.
We need to find minimum initial points to reach cell (m-1, n-1) from (0, 0).

## Copyright Notice

This problem is based on [content](https://www.geeksforgeeks.org/minimum-positive-points-to-reach-destination/)
from [GeeksforGeeks](https://www.geeksforgeeks.org)
written by Gaurav Ahirwar
and subject to [GeeksforGeeks copyright](https://www.geeksforgeeks.org/legal/copyright-information/).
The original content from GeeksforGeeks and any modifications made here are attributed to GeeksforGeeks contributors,
and this work is shared under [CC BY-SA 4.0](../LICENSE).
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package minimum_initial_points_to_reach_destination

func Solution(matrix [][]int) int {
m := len(matrix)
if m == 0 {
return 0
}
n := len(matrix[0])

var minPoints int
initialCell := cell{points: matrix[0][0]}
initialCell.setLowestPoints()

queue := []cell{initialCell}
for len(queue) > 0 {
curr := queue[0]
queue = queue[1:]
if curr.row == m-1 && curr.col == n-1 {
currMinPoints := curr.minPoints()
// fmt.Println(curr.lowestPoints)
if minPoints == 0 {
minPoints = currMinPoints
}
if currMinPoints < minPoints {
minPoints = currMinPoints
}
continue
}

neighbors := []cell{
{row: curr.row, col: curr.col + 1},
{row: curr.row + 1, col: curr.col},
}

for _, neighbor := range neighbors {
if neighbor.row >= m || neighbor.col >= n {
continue
}

neighbor.points = curr.points + matrix[neighbor.row][neighbor.col]
neighbor.lowestPoints = curr.lowestPoints
neighbor.setLowestPoints()
queue = append(queue, neighbor)
}
}

return minPoints
}

type cell struct {
row, col int
lowestPoints, points int
}

func (c *cell) setLowestPoints() {
if c.points < c.lowestPoints {
c.lowestPoints = c.points
}
}

func (c *cell) minPoints() int {
if c.lowestPoints >= 0 {
return 1
}
return 1 - c.lowestPoints
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package minimum_initial_points_to_reach_destination_test

import (
"testing"

sut "github.com/minizilla/minmax/geeksforgeeks/minimum-initial-points-to-reach-destination"
"github.com/minizilla/testr"
)

func TestMinimumInitialPointsToReachDestination(t *testing.T) {
tests := map[string]struct {
matrix [][]int
points int
}{
"zero": {nil, 0},
"one": {
[][]int{
{1},
}, 1,
},
"two": {
[][]int{
{-1, -1},
{1, -2},
}, 3,
},
"negative": {
[][]int{
{-1, -1, -10, -10},
{-1, -1, -10, -10},
{-1, -1, -10, -10},
{-1, -1, -10, -10},
{-1, -1, -10, -10},
{1, -1, -10, -10},
}, 26,
},
"positive": {
[][]int{
{1, 1, 10, 10},
{1, 1, 10, 10},
{1, 1, 10, 10},
{1, 1, 10, 10},
{1, 1, 10, 10},
{1, 1, 10, 10},
}, 1,
},
"random": {
[][]int{
{-1, -10, -1, 10},
{-10, -1, 0, 10},
{1, -1, -10, 10},
}, 13,
},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
assert := testr.New(t)
points := sut.Solution(tc.matrix)
assert.Equal(points, tc.points)
})
}
}

0 comments on commit ef73a72

Please sign in to comment.