diff --git a/2015/day24/main.go b/2015/day24/main.go index 4901f3c..91b441e 100644 --- a/2015/day24/main.go +++ b/2015/day24/main.go @@ -1,10 +1,14 @@ +// TODO: pull combinations, multiplying a slice of ints, into algos and mathy packages? package main import ( "flag" "fmt" + "sort" "strings" + "github.com/alexchao26/advent-of-code-go/mathy" + "github.com/alexchao26/advent-of-code-go/cast" "github.com/alexchao26/advent-of-code-go/util" ) @@ -15,32 +19,73 @@ func main() { flag.Parse() fmt.Println("Running part", part) - if part == 1 { - ans := part1(util.ReadFile("./input.txt")) - util.CopyToClipboard(fmt.Sprintf("%v", ans)) - fmt.Println("Output:", ans) - } else { - ans := part2(util.ReadFile("./input.txt")) - util.CopyToClipboard(fmt.Sprintf("%v", ans)) - fmt.Println("Output:", ans) + ans := balancingPackages(util.ReadFile("./input.txt"), part) + fmt.Println("Output:", ans) +} + +func balancingPackages(input string, part int) int { + var nums []int + for _, line := range strings.Split(input, "\n") { + nums = append(nums, cast.ToInt(line)) } -} -func part1(input string) int { - parsed := parseInput(input) - _ = parsed + sum := mathy.SumIntSlice(nums) - return 0 -} - -func part2(input string) int { - return 0 -} - -func parseInput(input string) (ans []int) { - lines := strings.Split(input, "\n") - for _, l := range lines { - ans = append(ans, cast.ToInt(l)) + target := sum / 3 + if part == 2 { + target = sum / 4 } - return ans + + var individualGroups [][]int + for groupLen := 2; len(individualGroups) == 0; groupLen++ { + for i := 0; i < len(nums); i++ { + individualGroups = append(individualGroups, combinations(nums, groupLen, []int{}, i)...) + } + + // validate that a combination adds up to the target sum + var validGroups [][]int + for _, gr := range individualGroups { + if mathy.SumIntSlice(gr) == target { + validGroups = append(validGroups, gr) + } + } + // reassign individual groups, if len(validGroups) == 0; we need to rerun + // with a larger groupLen + individualGroups = validGroups + } + + individualGroups = sortGroups(individualGroups) + + return quantumEntanglement(individualGroups[0]) +} + +func combinations(nums []int, length int, combo []int, index int) [][]int { + if len(combo) == length { + return [][]int{append([]int{}, combo...)} + } + var combos [][]int + for i := index; i < len(nums); i++ { + combo = append(combo, nums[i]) + with := combinations(nums, length, combo, i+1) + combos = append(combos, with...) + // backtrack + combo = combo[:len(combo)-1] + } + + return combos +} + +func sortGroups(groups [][]int) [][]int { + sort.Slice(groups, func(i, j int) bool { + return quantumEntanglement(groups[i]) < quantumEntanglement(groups[j]) + }) + return groups +} + +func quantumEntanglement(nums []int) int { + prod := 1 + for _, n := range nums { + prod *= n + } + return prod } diff --git a/2015/day24/main_test.go b/2015/day24/main_test.go index 22a4487..540b4e6 100644 --- a/2015/day24/main_test.go +++ b/2015/day24/main_test.go @@ -2,37 +2,24 @@ package main import ( "testing" + + "github.com/alexchao26/advent-of-code-go/util" ) -func Test_part1(t *testing.T) { +func Test_balancingPackages(t *testing.T) { tests := []struct { name string input string + part int want int }{ - // {"actual", util.ReadFile("input.txt"), ACTUAL_ANSWER}, + {"part1 actual", util.ReadFile("input.txt"), 1, 10439961859}, + {"part2 actual", util.ReadFile("input.txt"), 2, 72050269}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := part1(tt.input); got != tt.want { - t.Errorf("part1() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_part2(t *testing.T) { - tests := []struct { - name string - input string - want int - }{ - // {"actual", util.ReadFile("input.txt"), ACTUAL_ANSWER}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := part2(tt.input); got != tt.want { - t.Errorf("part2() = %v, want %v", got, tt.want) + if got := balancingPackages(tt.input, tt.part); got != tt.want { + t.Errorf("balancingPackages() = %v, want %v", got, tt.want) } }) }