Skip to content

Commit

Permalink
day 138: implement a smarter optimal change maker
Browse files Browse the repository at this point in the history
  • Loading branch information
vaskoz committed Jan 9, 2019
1 parent feca005 commit 5b171cf
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
30 changes: 29 additions & 1 deletion day138/problem.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package day138

import "errors"
import (
"errors"
)

var errNotPossible = errors.New("Can not make this value")

Expand Down Expand Up @@ -31,3 +33,29 @@ func MinCurrencyRequiredBrute(amt int, denomCents []int) (int, error) {
}
return 0, errNotPossible
}

// MinCurrencyRequiredSmarter returns the minimum number of currency
// necessary to make the desired amount.
func MinCurrencyRequiredSmarter(amt int, denomCents []int) (int, error) {
return minCurrencyRequiredSmarter(amt, int(^uint(0)>>1), 0, denomCents)
}

func minCurrencyRequiredSmarter(amt, min, count int, denomCents []int) (int, error) {
if count > min || amt < 0 {
return 0, errNotPossible
} else if amt == 0 {
return count, nil
}
found := false
for i := range denomCents {
current := denomCents[len(denomCents)-1-i]
if result, err := minCurrencyRequiredSmarter(amt-current, min, count+1, denomCents); err == nil && result < min {
found = true
min = result
}
}
if found {
return min, nil
}
return 0, errNotPossible
}
19 changes: 19 additions & 0 deletions day138/problem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ var testcases = []struct {
}{
{[]int{1, 5, 10, 25}, 16, 3, nil},
{[]int{25}, 16, 0, ErrNotPossible()},
{[]int{2, 5}, 16, 5, nil},
{[]int{2, 3, 6}, 6, 1, nil},
}

func TestMinCurrencyRequiredBrute(t *testing.T) {
Expand All @@ -28,3 +30,20 @@ func BenchmarkMinCurrencyRequiredBrute(b *testing.B) {
}
}
}

func TestMinCurrencyRequiredSmarter(t *testing.T) {
t.Parallel()
for _, tc := range testcases {
if result, err := MinCurrencyRequiredSmarter(tc.n, tc.denom); err != tc.err || result != tc.expected {
t.Errorf("Expected (%v,%v) got (%v,%v)", tc.expected, tc.err, result, err)
}
}
}

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

0 comments on commit 5b171cf

Please sign in to comment.