110 lines
2.8 KiB
Go
110 lines
2.8 KiB
Go
package day15
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
"tools"
|
|
)
|
|
|
|
func getIngredientsFromInput(input []string) ([]string, map[string]map[string]int) {
|
|
ingredients := make(map[string]map[string]int)
|
|
var ingredientList []string
|
|
for _, line := range input {
|
|
lineParts := strings.Split(line, " ")
|
|
ingredient := lineParts[0][:len(lineParts[0])-1]
|
|
ingredientList = append(ingredientList, ingredient)
|
|
ingredients[ingredient] = make(map[string]int)
|
|
ingredients[ingredient][lineParts[1]], _ = strconv.Atoi(lineParts[2][:len(lineParts[2])-1])
|
|
ingredients[ingredient][lineParts[3]], _ = strconv.Atoi(lineParts[4][:len(lineParts[4])-1])
|
|
ingredients[ingredient][lineParts[5]], _ = strconv.Atoi(lineParts[6][:len(lineParts[6])-1])
|
|
ingredients[ingredient][lineParts[7]], _ = strconv.Atoi(lineParts[8][:len(lineParts[8])-1])
|
|
ingredients[ingredient][lineParts[9]], _ = strconv.Atoi(lineParts[10])
|
|
}
|
|
|
|
return ingredientList, ingredients
|
|
}
|
|
|
|
func getCombinations(sum int, count int) (combinations [][]int) {
|
|
if count == 1 {
|
|
return [][]int{
|
|
{sum},
|
|
}
|
|
}
|
|
for i := sum - count + 1; i > 0; i-- {
|
|
subCombinations := getCombinations(sum-i, count-1)
|
|
for _, v := range subCombinations {
|
|
subCombination := append([]int{i}, v...)
|
|
combinations = append(combinations, subCombination)
|
|
}
|
|
}
|
|
|
|
return combinations
|
|
}
|
|
|
|
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
|
ingredientList, ingredients := getIngredientsFromInput(puzzle.GetInputArray())
|
|
maxScore := 0
|
|
multiplierCombinations := getCombinations(100, len(ingredients))
|
|
properties := []string{"capacity", "durability", "flavor", "texture"}
|
|
for _, multiplier := range multiplierCombinations {
|
|
sums := make(map[string]int)
|
|
for _, propName := range properties {
|
|
for index, ingredient := range ingredientList {
|
|
sums[propName] += ingredients[ingredient][propName] * multiplier[index]
|
|
}
|
|
}
|
|
|
|
thisScore := 1
|
|
for _, v := range sums {
|
|
if v <= 0 {
|
|
thisScore = 0
|
|
} else {
|
|
thisScore *= v
|
|
}
|
|
}
|
|
|
|
if thisScore > maxScore {
|
|
maxScore = thisScore
|
|
}
|
|
}
|
|
|
|
return maxScore
|
|
}
|
|
|
|
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
|
ingredientList, ingredients := getIngredientsFromInput(puzzle.GetInputArray())
|
|
maxScore := 0
|
|
multiplierCombinations := getCombinations(100, len(ingredients))
|
|
properties := []string{"capacity", "durability", "flavor", "texture", "calories"}
|
|
for _, multiplier := range multiplierCombinations {
|
|
sums := make(map[string]int)
|
|
for _, propName := range properties {
|
|
for index, ingredient := range ingredientList {
|
|
sums[propName] += ingredients[ingredient][propName] * multiplier[index]
|
|
}
|
|
}
|
|
|
|
if sums["calories"] != 500 {
|
|
continue
|
|
}
|
|
|
|
thisScore := 1
|
|
for prop, v := range sums {
|
|
if prop == "calories" {
|
|
continue
|
|
}
|
|
if v <= 0 {
|
|
thisScore = 0
|
|
} else {
|
|
thisScore *= v
|
|
}
|
|
}
|
|
|
|
if thisScore > maxScore {
|
|
maxScore = thisScore
|
|
}
|
|
}
|
|
|
|
return maxScore
|
|
}
|