diff --git a/src/2015/Day21.cpp b/src/2015/Day21.cpp index 5e9a622..43181c2 100644 --- a/src/2015/Day21.cpp +++ b/src/2015/Day21.cpp @@ -2,30 +2,117 @@ namespace y2015::day21 { - REGISTER_DAY(2015, Day21, std::vector, int); + struct Entity + { + int hp; + int dmg; + int armor; + }; - REGISTER_TEST_EXAMPLE(2015, Day21, ExampleInput, 1, 0); - REGISTER_TEST(2015, Day21, Input, 1, 0); - REGISTER_TEST_EXAMPLE(2015, Day21, ExampleInput, 2, 0); - REGISTER_TEST(2015, Day21, Input, 2, 0); + struct Item + { + int cost; + int dmg; + int armor; + }; + + REGISTER_DAY(2015, Day21, Entity, int); + + REGISTER_TEST(2015, Day21, Input, 1, 91); + REGISTER_TEST(2015, Day21, Input, 2, 158); READ_INPUT(input) { - std::vector vec; - std::string str; - while (getline(input, str)) - { - } - return vec; + Entity monster; + input >> "Hit Points: " >> monster.hp >> "\n"; + input >> "Damage: " >> monster.dmg >> "\n"; + input >> "Armor: " >> monster.armor >> "\n"; + return monster; } + bool Win(Entity player, Entity monster) + { + int playerDmgPerRound = std::max(1, (player.dmg - monster.armor)); + int monsterDmgPerRound = std::max(1, (monster.dmg - player.armor)); + + int i = 0; + while (true) + { + if (i % 2 == 0) + { + monster.hp -= playerDmgPerRound; + if (monster.hp <= 0) + return true; + } + else + { + player.hp -= monsterDmgPerRound; + if (player.hp <= 0) + return false; + } + i++; + } + } + + std::vector weapons{Item{8, 4, 0}, Item{10, 5, 0}, Item{25, 6, 0}, Item{40, 7, 0}, Item{74, 8, 0}}; + std::vector armors{ + Item{13, 0, 1}, Item{31, 0, 2}, Item{53, 0, 3}, Item{75, 0, 4}, Item{102, 0, 5}, Item{0, 0, 0}}; + std::vector rings{Item{25, 0, 1}, + Item{50, 0, 2}, + Item{100, 0, 3}, + Item{20, 0, 1}, + Item{40, 0, 2}, + Item{80, 0, 3}, + Item{0, 0, 0}, + Item{0, 0, 0}}; + OUTPUT1(input) { - return 0; + int minCost = std::numeric_limits::max(); + for (auto& weapon : weapons) + { + for (auto& armor : armors) + { + for (int i = 0; i < rings.size(); i++) + { + for (int j = i + 1; j < rings.size(); j++) + { + int cost = weapon.cost + armor.cost + rings[i].cost + rings[j].cost; + int dmgStat = weapon.dmg + armor.dmg + rings[i].dmg + rings[j].dmg; + int armorStat = weapon.armor + armor.armor + rings[i].armor + rings[j].armor; + if (cost > minCost) + continue; + if (Win(Entity{100, dmgStat, armorStat}, input)) + minCost = cost; + } + } + } + } + return minCost; } OUTPUT2(input) { - return 0; + int maxCost = 0; + for (auto& weapon : weapons) + { + for (auto& armor : armors) + { + for (int i = 0; i < rings.size(); i++) + { + for (int j = i + 1; j < rings.size(); j++) + { + int cost = weapon.cost + armor.cost + rings[i].cost + rings[j].cost; + int dmgStat = weapon.dmg + armor.dmg + rings[i].dmg + rings[j].dmg; + int armorStat = weapon.armor + armor.armor + rings[i].armor + rings[j].armor; + if (cost < maxCost) + continue; + if (!Win(Entity{100, dmgStat, armorStat}, input)) + maxCost = cost; + } + } + } + } + return maxCost; } }