summaryrefslogtreecommitdiffstats
path: root/21
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2021-11-25 22:33:45 +0000
committerTomasz Kramkowski <tk@the-tk.com>2021-11-25 22:33:45 +0000
commit0e8e49af605d3160645e773fdec53b7cf60cc068 (patch)
treee6a57463ae610b0be85884c3ee4bc2b6dd927b37 /21
parenta7a6b86002b595bc167af72606b14c67ed1bdf8f (diff)
downloadaoc2015-0e8e49af605d3160645e773fdec53b7cf60cc068.tar.gz
aoc2015-0e8e49af605d3160645e773fdec53b7cf60cc068.tar.xz
aoc2015-0e8e49af605d3160645e773fdec53b7cf60cc068.zip
more solutions
Diffstat (limited to '21')
-rw-r--r--21/solution.py91
1 files changed, 91 insertions, 0 deletions
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))