aboutsummaryrefslogtreecommitdiffstats
path: root/src/24
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2023-04-07 16:16:42 -0400
committerLouis Burda <quent.burda@gmail.com>2023-04-07 16:16:42 -0400
commit277e5d08e28b5fcab8b019f66211883d976efbad (patch)
treeb1e8ae3ae602edb98236ea79676f913d0328c798 /src/24
parent73b29dfa9d07c37e8d4db2136cd73fdd9f0650b8 (diff)
downloadaoc2018-python-277e5d08e28b5fcab8b019f66211883d976efbad.tar.gz
aoc2018-python-277e5d08e28b5fcab8b019f66211883d976efbad.zip
Add helper to check solutions and reorder to new layout
Diffstat (limited to 'src/24')
-rw-r--r--src/24/input.txt23
-rw-r--r--src/24/notes.txt26
-rw-r--r--src/24/solve.py129
3 files changed, 0 insertions, 178 deletions
diff --git a/src/24/input.txt b/src/24/input.txt
deleted file mode 100644
index 969be90..0000000
--- a/src/24/input.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Immune System:
-2728 units each with 5703 hit points (weak to fire) with an attack that does 18 cold damage at initiative 12
-916 units each with 5535 hit points (weak to bludgeoning) with an attack that does 55 slashing damage at initiative 20
-2255 units each with 7442 hit points (weak to radiation) with an attack that does 31 bludgeoning damage at initiative 8
-112 units each with 4951 hit points (immune to cold) with an attack that does 360 fire damage at initiative 9
-7376 units each with 6574 hit points (immune to cold, slashing, fire) with an attack that does 7 bludgeoning damage at initiative 4
-77 units each with 5884 hit points (weak to slashing) with an attack that does 738 radiation damage at initiative 6
-6601 units each with 8652 hit points (weak to fire, cold) with an attack that does 11 fire damage at initiative 19
-3259 units each with 10067 hit points (weak to bludgeoning) with an attack that does 29 cold damage at initiative 13
-2033 units each with 4054 hit points (immune to cold; weak to fire, slashing) with an attack that does 18 slashing damage at initiative 3
-3109 units each with 3593 hit points with an attack that does 9 bludgeoning damage at initiative 11
-
-Infection:
-1466 units each with 57281 hit points (weak to slashing, fire) with an attack that does 58 slashing damage at initiative 7
-247 units each with 13627 hit points with an attack that does 108 fire damage at initiative 15
-1298 units each with 41570 hit points (immune to fire, bludgeoning) with an attack that does 63 fire damage at initiative 14
-2161 units each with 40187 hit points (weak to fire) with an attack that does 33 slashing damage at initiative 5
-57 units each with 55432 hit points (weak to cold) with an attack that does 1687 radiation damage at initiative 17
-3537 units each with 24220 hit points (weak to cold) with an attack that does 11 fire damage at initiative 10
-339 units each with 44733 hit points (immune to cold, bludgeoning; weak to radiation, fire) with an attack that does 258 cold damage at initiative 18
-1140 units each with 17741 hit points (weak to bludgeoning; immune to fire, slashing) with an attack that does 25 fire damage at initiative 2
-112 units each with 44488 hit points (weak to bludgeoning, radiation; immune to cold) with an attack that does 749 radiation damage at initiative 16
-2918 units each with 36170 hit points (immune to bludgeoning; weak to slashing, cold) with an attack that does 24 radiation damage at initiative 1
diff --git a/src/24/notes.txt b/src/24/notes.txt
deleted file mode 100644
index c81d665..0000000
--- a/src/24/notes.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-infection and immune sys are armies
- - made of groups of identical units
- - group:
- - same hitpoint
- - same attack damage
- - same initiative (who attacks first has highest)
- - same weaknesses / immunities
- - effective power = n of members * attack damage
-
-target selection:
- - highest effective power chooses first sorted
- if tie => higher initiative chooses first
- - choose group it would damage most
- if tie => largest effective power
- if tie => largest intiative
- if no group => no attack
-
-attack:
- - attack in descending order of initiative
- - regardless of army
- - immune: 0 dmg
- - weak: 2 x dmg
- - only full death, units dont have dynamic health
-
-
-(army, # of units, # of hp, initiative, dict of weaknesses / immunity, damage, type)
diff --git a/src/24/solve.py b/src/24/solve.py
deleted file mode 100644
index 020af79..0000000
--- a/src/24/solve.py
+++ /dev/null
@@ -1,129 +0,0 @@
-from sys import argv as args
-
-sinput = open("input.txt").read()
-
-immunesys = 0
-infection = 1
-ctype = 0
-
-# parse input from file
-def parseInput():
- groups = list()
- for l in sinput.split("\n"):
- pl = parseLine(l)
- if pl != None:
- groups.append(pl)
- return groups
-
-# parse line of input
-def parseLine(line):
- global ctype
- group = None
- if "Immune" in line:
- ctype = immunesys
- elif "Infection" in line:
- ctype = infection
- elif line != "":
- ls = line.split()
- group = dict()
- group["type"] = ctype
- group["units"] = int(ls[0])
- group["unithp"] = int(ls[4])
- group["initiative"] = int(ls[-1])
- group["weak"] = list()
- group["immune"] = list()
- if "(" in line:
- parenthstr = line.split("(")[1].split(")")[0]
- traits = parenthstr.split(";")
- for traitstr in traits:
- info = traitstr.split()
- group[info[0]] = [v.replace(",","") for v in info[2:]]
- dmginfo = line.split("does")[1].split("damage")[0].split()
- group["dmg"] = int(dmginfo[0])
- group["dmgtype"] = dmginfo[1]
- return group
-
-def getEffectivePower(g):
- return g["units"] * g["dmg"]
-
-def getDamage(attacker, defender):
- dmg = getEffectivePower(attacker)
- dmg *= (0 if attacker["dmgtype"] in defender["immune"] else 1)
- dmg *= (2 if attacker["dmgtype"] in defender["weak"] else 1)
- return dmg
-
-groups = parseInput()
-
-def fight():
- global groups
-
- lunits = 0
-
- immalive = len([g for g in groups if g["type"] == immunesys])
- infalive = len([g for g in groups if g["type"] == infection])
-
- while immalive > 0 and infalive > 0:
- # target selection
- attacked = list()
- attackpairs = list()
- groups = sorted(groups, key = lambda x : (getEffectivePower(x), x["initiative"]), reverse = True)
- for group in groups:
- # choose group of other army, which is not already being attacked and sort appropriately
- enemies = [g for g in groups if g["type"] != group["type"] and g not in attacked]
- if len(enemies) == 0:
- continue
- target = max(enemies, key = lambda x : (getDamage(group, x), getEffectivePower(x), x["initiative"]))
- if getDamage(group, target) != 0: # enemies which arent immune
- attacked.append(target)
- attackpairs.append((groups.index(group), groups.index(target)))
-
- # attacking phase
- attackpairs = sorted(attackpairs, key = lambda x : groups[x[0]]["initiative"], reverse = True)
-
- for ap in attackpairs:
- attacker = groups[ap[0]]
- attacked = groups[ap[1]]
- if attacker["units"] > 0 and attacked["units"] > 0: # if attacker or defender is dead, no need to attack
- dmg = getDamage(attacker, attacked)
- attacked["units"] = max(0, attacked["units"] - dmg // attacked["unithp"]) # remove whole numbers of units
-
- groups = [g for g in groups if g["units"] > 0]
- immalive = sum([g["units"] for g in groups if g["type"] == immunesys])
- infalive = sum([g["units"] for g in groups if g["type"] == infection])
- units = immalive + infalive
- if units == lunits:
- return units
- lunits = units
- return units
-
-def solve1():
- print(fight())
-
-def solve2():
- global groups
-
- immunewin = False
- boost = 1
- while not immunewin:
- groups = parseInput()
- for g in groups:
- if g["type"] == immunesys:
- g["dmg"] += boost
-
- fight()
-
- immunewin = (sum([0 if g["type"] == immunesys else 1 for g in groups]) == 0)
-
- boost += 1
-
- #print("boost:", boost)
- print("units:", sum([v["units"] for v in groups]))
-
-def main():
- if len(args) > 1:
- if args[1] == "1":
- solve1()
- elif args[1] == "2":
- solve2()
-
-main()