From 0e8e49af605d3160645e773fdec53b7cf60cc068 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Thu, 25 Nov 2021 22:33:45 +0000 Subject: more solutions --- 21/solution.py | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 21/solution.py (limited to '21') diff --git a/21/solution.py b/21/solution.py new file mode 100644 index 0000000..51bf19c --- /dev/null +++ b/21/solution.py @@ -0,0 +1,91 @@ +from math import ceil +from dataclasses import dataclass + +@dataclass +class Item: + cost: int + damage: int + armour: int + +weapons = [ + Item(8, 4, 0), + Item(10, 5, 0), + Item(25, 6, 0), + Item(40, 7, 0), + Item(74, 8, 0), +] + +armour = [ + Item(0, 0, 0), + Item(13, 0, 1), + Item(31, 0, 2), + Item(53, 0, 3), + Item(75, 0, 4), + Item(102, 0, 5), +] + +rings = [ + Item(0, 0, 0), + Item(25, 1, 0), + Item(50, 2, 0), + Item(100, 3, 0), + Item(20, 0, 1), + Item(40, 0, 2), + Item(80, 0, 3), +] + +@dataclass +class Player: + hit_points: int + damage: int + armour: int + +def damage_dealt(by: Player, to: Player) -> int: + return max(1, by.damage - to.armour) + +def part1(opponent: Player) -> int: + min_cost = float('inf') + + for weapon in weapons: + for a in armour: + for ring1 in rings: + for ring2 in rings: + if ring1 == ring2: + continue + + player = Player(100, weapon.damage + ring1.damage + ring2.damage, a.armour + ring1.armour + ring2.armour) + + pturns = ceil(opponent.hit_points / damage_dealt(by=player, to=opponent)) + oturns = ceil(player.hit_points / damage_dealt(by=opponent, to=player)) + + if pturns <= oturns: + min_cost = min(min_cost, weapon.cost + a.cost + ring1.cost + ring2.cost) + + return min_cost + + +def part2(opponent: Player) -> int: + max_cost = 0 + + for weapon in weapons: + for a in armour: + for ring1 in rings: + for ring2 in rings: + if ring1 == ring2: + continue + + player = Player(100, weapon.damage + ring1.damage + ring2.damage, a.armour + ring1.armour + ring2.armour) + + pturns = ceil(opponent.hit_points / damage_dealt(by=player, to=opponent)) + oturns = ceil(player.hit_points / damage_dealt(by=opponent, to=player)) + + if pturns > oturns: + max_cost = max(max_cost, weapon.cost + a.cost + ring1.cost + ring2.cost) + + return max_cost + +if __name__ == '__main__': + opponent = Player(103, 9, 2) + + print(part1(opponent)) + print(part2(opponent)) -- cgit v1.2.3-54-g00ecf