Skip to content

Commit

Permalink
Merge c0e3013 into 93b1af5
Browse files Browse the repository at this point in the history
  • Loading branch information
vaskoz committed Feb 25, 2020
2 parents 93b1af5 + c0e3013 commit c22cd90
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -458,4 +458,5 @@ problems from
* [Day 458](https://github.com/vaskoz/dailycodingproblem-go/issues/925)
* [Day 459](https://github.com/vaskoz/dailycodingproblem-go/issues/927)
* [Day 460](https://github.com/vaskoz/dailycodingproblem-go/issues/929)
* [Day 461](https://github.com/vaskoz/dailycodingproblem-go/issues/931)

60 changes: 60 additions & 0 deletions day461/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package day461

// CountPathsBrute counts the number of paths from upper-left to lower-right.
// Allowed movement is only down and right.
// Runs in O(2^N) time.
func CountPathsBrute(n, m int) int {
if n < 1 || m < 1 {
panic("invalid size. both arguments must be 1 or greater")
} else if n == 1 || m == 1 {
return 1
}

return CountPathsBrute(m-1, n) + CountPathsBrute(m, n-1)
}

// CountPathsDP is the same solution just using dynamic programming.
// Runs in O(m*n) time and O(m*n) space.
func CountPathsDP(n, m int) int {
if n < 1 || m < 1 {
panic("invalid size. both arguments must be 1 or greater")
}

counts := make([][]int, m)

for i := range counts {
counts[i] = make([]int, n)
counts[i][0] = 1
}

for i := 0; i < n; i++ {
counts[0][i] = 1
}

for i := 1; i < m; i++ {
for j := 1; j < n; j++ {
counts[i][j] = counts[i-1][j] + counts[i][j-1]
}
}

return counts[m-1][n-1]
}

// CountPathsCalculate is the same solution using an equation to calculate the result.
// Runs in O(1) time and O(1) space.
func CountPathsCalculate(n, m int) int {
if n < 1 || m < 1 {
panic("invalid size. both arguments must be 1 or greater")
}

return factorial((n-1)+(m-1)) / (factorial(m-1) * factorial(n-1))
}

func factorial(n int) int {
result := 1
for i := 2; i <= n; i++ {
result *= i
}

return result
}
98 changes: 98 additions & 0 deletions day461/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package day461

import "testing"

// nolint
var testcases = []struct {
n, m, expected int
}{
{2, 2, 2},
{5, 5, 70},
}

func TestCountPathsBrute(t *testing.T) {
t.Parallel()

for _, tc := range testcases {
if result := CountPathsBrute(tc.m, tc.n); result != tc.expected {
t.Errorf("Expected %d got %d", tc.expected, result)
}
}
}

func TestCountPathsBruteBadArgs(t *testing.T) {
t.Parallel()

defer func() {
if err := recover(); err == nil {
t.Errorf("Expected a panic")
}
}()
CountPathsBrute(0, 0)
}

func BenchmarkCountPathsBrute(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, tc := range testcases {
CountPathsBrute(tc.m, tc.n)
}
}
}

func TestCountPathsDP(t *testing.T) {
t.Parallel()

for _, tc := range testcases {
if result := CountPathsDP(tc.m, tc.n); result != tc.expected {
t.Errorf("Expected %d got %d", tc.expected, result)
}
}
}

func TestCountPathsDPBadArgs(t *testing.T) {
t.Parallel()

defer func() {
if err := recover(); err == nil {
t.Errorf("Expected a panic")
}
}()
CountPathsDP(0, 0)
}

func BenchmarkCountPathsDP(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, tc := range testcases {
CountPathsDP(tc.m, tc.n)
}
}
}

func TestCountPathsCalculate(t *testing.T) {
t.Parallel()

for _, tc := range testcases {
if result := CountPathsCalculate(tc.m, tc.n); result != tc.expected {
t.Errorf("Expected %d got %d", tc.expected, result)
}
}
}

func TestCountPathsCalculateBadArgs(t *testing.T) {
t.Parallel()

defer func() {
if err := recover(); err == nil {
t.Errorf("Expected a panic")
}
}()
CountPathsCalculate(0, 0)
}

func BenchmarkCountPathsCalculate(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, tc := range testcases {
CountPathsCalculate(tc.m, tc.n)
}
}
}

0 comments on commit c22cd90

Please sign in to comment.