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 }