2015-day17: recursive backtrack to valid combinations

This commit is contained in:
alexchao26
2020-12-26 21:52:22 -05:00
parent 66a7bd706b
commit e8b6c9cbde
2 changed files with 105 additions and 0 deletions
+67
View File
@@ -0,0 +1,67 @@
package main
import (
"flag"
"fmt"
"math"
"strings"
"github.com/alexchao26/advent-of-code-go/cast"
"github.com/alexchao26/advent-of-code-go/mathutil"
"github.com/alexchao26/advent-of-code-go/util"
)
func main() {
var part int
flag.IntVar(&part, "part", 1, "part 1 or 2")
flag.Parse()
fmt.Println("Running part", part)
ans := eggnogCombinations(util.ReadFile("./input.txt"), 150, part)
fmt.Println("Output:", ans)
}
func eggnogCombinations(input string, target int, part int) int {
var nums []int
for _, line := range strings.Split(input, "\n") {
nums = append(nums, cast.ToInt(line))
}
allIndexCombinations := backtrack(nums, 0, target, []int{})
// part 1, just return len
if part == 1 {
return len(allIndexCombinations)
}
// part 2, get the number of combinations w/ the lowest length
minLen := math.MaxInt32
for _, comb := range allIndexCombinations {
minLen = mathutil.MinInt(minLen, len(comb))
}
var count int
for _, comb := range allIndexCombinations {
if len(comb) == minLen {
count++
}
}
return count
}
func backtrack(nums []int, startingIndex, remaining int, usedIndices []int) [][]int {
if remaining == 0 {
return [][]int{append([]int{}, usedIndices...)}
}
if remaining < 0 {
return nil
}
var validReturns [][]int
for i := startingIndex; i < len(nums); i++ {
usedIndices = append(usedIndices, i)
validReturns = append(validReturns, backtrack(nums, i+1, remaining-nums[i], usedIndices)...)
usedIndices = usedIndices[:len(usedIndices)-1]
}
return validReturns
}
+38
View File
@@ -0,0 +1,38 @@
package main
import (
"testing"
"github.com/alexchao26/advent-of-code-go/util"
)
var example = `20
15
10
5
5`
func Test_eggnogCombinations(t *testing.T) {
type args struct {
input string
target int
part int
}
tests := []struct {
name string
args args
want int
}{
{"part1 example", args{example, 25, 1}, 4},
{"part1 actual", args{util.ReadFile("input.txt"), 150, 1}, 1304},
{"part2 example", args{example, 25, 2}, 3},
{"part2 actual", args{util.ReadFile("input.txt"), 150, 2}, 18},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := eggnogCombinations(tt.args.input, tt.args.target, tt.args.part); got != tt.want {
t.Errorf("eggnogCombinations() = %v, want %v", got, tt.want)
}
})
}
}