package day21 import ( "math" "strconv" "strings" "tools" ) var armor = map[string]map[string]int{ "none": { "cost": 0, "armor": 0, }, "Leather": { "cost": 13, "armor": 1, }, "Chainmail": { "cost": 31, "armor": 2, }, "Splintmail": { "cost": 53, "armor": 3, }, "Bandedmail": { "cost": 75, "armor": 4, }, "Platemail": { "cost": 102, "armor": 5, }, } var weapons = map[string]map[string]int{ "Dagger": { "cost": 8, "damage": 4, }, "Shortsword": { "cost": 10, "damage": 5, }, "Warhammer": { "cost": 25, "damage": 6, }, "Longsword": { "cost": 40, "damage": 7, }, "Greataxe": { "cost": 74, "damage": 8, }, } var rings = map[string]map[string]int{ "none1": { "cost": 0, "damage": 0, "armor": 0, }, "none2": { "cost": 0, "damage": 0, "armor": 0, }, "Damage +1": { "cost": 25, "damage": 1, "armor": 0, }, "Damage +2": { "cost": 50, "damage": 2, "armor": 0, }, "Damage +3": { "cost": 100, "damage": 3, "armor": 0, }, "Armor +1": { "cost": 20, "damage": 0, "armor": 1, }, "Armor +2": { "cost": 40, "damage": 0, "armor": 2, }, "Armor +3": { "cost": 80, "damage": 0, "armor": 3, }, } func fight(playerHp, playerPower, playerArmor, bossHp, bossPower, bossArmor int) bool { playerStrike := float64(tools.Max(1, playerPower-bossArmor)) bossStrike := float64(tools.Max(1, bossPower-playerArmor)) return math.Ceil(float64(bossHp)/playerStrike) <= math.Ceil(float64(playerHp)/bossStrike) } func getMinMaxGold(puzzle tools.AoCPuzzle) (minGold int, maxGold int) { input := puzzle.GetInputArray() hpLine := strings.Split(input[0], ": ") powerLine := strings.Split(input[1], ": ") armorLine := strings.Split(input[2], ": ") bossHp, _ := strconv.Atoi(hpLine[1]) bossPower, _ := strconv.Atoi(powerLine[1]) bossArmor, _ := strconv.Atoi(armorLine[1]) playerHp := 100 playerPower := 0 playerArmor := 0 goldSpent := 0 minGold = math.MaxInt32 for _, weaponStats := range weapons { for _, armorStats := range armor { for ring1Name, ring1Stats := range rings { for ring2Name, ring2Stats := range rings { if ring1Name == ring2Name { continue } goldSpent = weaponStats["cost"] + armorStats["cost"] + ring1Stats["cost"] + ring2Stats["cost"] playerPower = weaponStats["damage"] + ring1Stats["damage"] + ring2Stats["damage"] playerArmor = armorStats["armor"] + ring1Stats["armor"] + ring2Stats["armor"] playerWon := fight(playerHp, playerPower, playerArmor, bossHp, bossPower, bossArmor) if playerWon && goldSpent < minGold { minGold = goldSpent } else if !playerWon && goldSpent > maxGold { maxGold = goldSpent } } } } } return minGold, maxGold } func Part1(puzzle tools.AoCPuzzle) interface{} { minGold, _ := getMinMaxGold(puzzle) return minGold } func Part2(puzzle tools.AoCPuzzle) interface{} { _, maxGold := getMinMaxGold(puzzle) return maxGold }