2018 Day 24 Done

This commit is contained in:
Brian Buller 2019-11-08 12:40:42 -06:00
parent 10af09b200
commit 83313cc77b
8 changed files with 548 additions and 402 deletions

View File

@ -1,210 +1,44 @@
package main package main
import ( type Army []*Group
"fmt"
"strings"
)
const ( const (
ArmyTypeImmune = 1 << iota ArmyImmuneSystem = iota + 1
ArmyTypeInfection ArmyInfection
ArmyCount
) )
type Army struct { var StringArmies = map[string]int{
id int "Immune System": ArmyImmuneSystem,
tp int "Infection": ArmyInfection,
units int
hp int
immunities []string
weaknesses []string
damageType string
strength int
init int
target *Army
targettedBy *Army
} }
func NewArmy(inp string, tp, id int) *Army { func (a Army) Swap(i, j int) {
a := new(Army) a[i], a[j] = a[j], a[i]
a.tp = tp
a.id = id
// Pull the parenthetical out, if one is there
var prnth, other string
var inPrnth bool
var ptsOfOther int
for _, v := range strings.Fields(inp) {
if len(v) > 0 && v[len(v)-1] == ')' {
prnth = prnth + " " + v
inPrnth = false
continue
} else if len(v) > 0 && v[0] == '(' {
inPrnth = true
prnth = v
continue
}
if inPrnth {
prnth = prnth + " " + v
} else {
if len(other) > 0 {
other = other + " "
}
other = other + v
ptsOfOther++
}
}
_, err := fmt.Sscanf(other, "%d units each with %d hit points with an attack that does %d %s damage at initiative %d", &a.units, &a.hp, &a.strength, &a.damageType, &a.init)
if err != nil {
panic(err)
}
// Now parse out immunities and weaknesses
if len(prnth) > 3 {
prnth = prnth[1 : len(prnth)-1]
var inImmune bool
for _, v := range strings.Fields(prnth) {
if v == "immune" {
inImmune = true
continue
} else if v == "weak" {
inImmune = false
continue
}
if v == "to" {
continue
}
if v[len(v)-1] == ';' || v[len(v)-1] == ',' {
v = v[:len(v)-1]
}
if inImmune {
a.immunities = append(a.immunities, v)
} else {
a.weaknesses = append(a.weaknesses, v)
}
}
}
return a
} }
func (a *Army) IsImmuneTo(val string) bool { func (a Army) Len() int {
for _, v := range a.immunities { return len(a)
if v == val { }
func (a Army) Less(i, j int) bool {
if a[i].EffectivePower() > a[j].EffectivePower() {
return true
}
return a[i].EffectivePower() == a[j].EffectivePower() && a[i].Initiative > a[j].Initiative
}
func (a Army) Alive() bool {
for _, g := range a {
if g.Units > 0 {
return true return true
} }
} }
return false return false
} }
func (a *Army) IsWeakTo(val string) bool { func (a Army) Boost(amount int) {
for _, v := range a.weaknesses { for _, g := range a {
if v == val { g.AttackDamage += amount
return true
}
}
return false
}
func (a *Army) Power() int {
return a.units * a.strength
}
func (a *Army) FindTarget(group []*Army) {
var tgt *Army
var tgtDmg int
for _, v := range group {
if v.targettedBy != nil {
continue
}
wrkDmg := a.CalculateDamage(v)
if tgt == nil || wrkDmg > tgtDmg {
tgt = v
tgtDmg = wrkDmg
} else if wrkDmg == tgtDmg {
if v.Power() > tgt.Power() {
tgt = v
tgtDmg = wrkDmg
} else if v.Power() == tgt.Power() {
if v.init > tgt.init {
tgt = v
tgtDmg = wrkDmg
}
}
}
if Debug {
var tpTxt string
if a.tp == ArmyTypeImmune {
tpTxt = "Immune System"
} else {
tpTxt = "Infection"
}
fmt.Printf("%s group %d would deal defending group %d %d damage\n", tpTxt, a.id, tgt.id, tgtDmg)
}
}
if tgt != nil {
a.target = tgt
tgt.targettedBy = a
} }
} }
func (a *Army) CalculateDamage(b *Army) int {
if b.IsWeakTo(a.damageType) {
return a.Power() * 2
} else if b.IsImmuneTo(a.damageType) {
return 0
}
return a.Power()
}
func (a *Army) Damage(b *Army) int {
var unitsDefeated int
dmg := a.CalculateDamage(b)
for dmg > 0 {
dmg -= b.hp
if dmg > 0 && b.units > 0 {
b.units--
unitsDefeated++
}
}
b.targettedBy = nil
return unitsDefeated
}
func (a *Army) Fight() {
if a.target != nil {
var tpTxt string
if a.tp == ArmyTypeImmune {
tpTxt = "Immune System"
} else if a.tp == ArmyTypeInfection {
tpTxt = "Infection"
}
dmg := a.Damage(a.target)
if Debug {
fmt.Printf("%s group %d attacks defending group %d, killing %d units\n", tpTxt, a.id, a.target.id, dmg)
}
}
}
func (a Army) String() string {
ret := fmt.Sprintf("%d units each with %d hit points ", a.units, a.hp)
if len(a.weaknesses) > 0 {
ret = ret + fmt.Sprintf("(weaknesses: %s) ", a.weaknesses)
}
if len(a.immunities) > 0 {
ret = ret + fmt.Sprintf("(immunities: %s) ", a.immunities)
}
ret = ret + fmt.Sprintf("with an attack that does %d %s damage at initiative %d\n",
a.strength, a.damageType, a.init,
)
return ret
}
// Army Sorting
type ByPower []*Army
func (b ByPower) Len() int { return len(b) }
func (b ByPower) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
func (b ByPower) Less(i, j int) bool {
if b[i].Power() == b[j].Power() {
return b[i].init < b[j].init
}
return b[i].Power() < b[j].Power()
}

View File

@ -2,71 +2,160 @@ package main
import ( import (
"fmt" "fmt"
"regexp"
"sort" "sort"
"strings"
helpers2017 "bitbucket.org/thezeez/advent-of-code-2017/helpers"
) )
type Battle struct { type Battlefield map[int]Army
immune []*Army
infect []*Army
}
func NewBattle(immune, infect []*Army) *Battle { var (
return &Battle{ armyName = regexp.MustCompile(`^(.*):$`)
immune: immune, groupImmunities = regexp.MustCompile(`immune to (.*?)[;)]`)
infect: infect, groupWeaknesses = regexp.MustCompile(`weak to (.*?)[;)]`)
} groupDescription = regexp.MustCompile(`^(\d+) units each with (\d+) hit points.*with an attack that does (\d+) (\w+) damage at initiative (\d+)$`)
} )
func (b *Battle) PrintStatus() { const (
fmt.Println("Immune System:") descriptionCount = iota + 1
for _, v := range b.immune { descriptionHitPoints
fmt.Printf("Group %d contains %d units\n", v.id, v.units) descriptionDamage
} descriptionDamageType
fmt.Println("Infection:") descriptionInitiative
for _, v := range b.infect { )
fmt.Printf("Group %d contains %d units\n", v.id, v.units)
}
}
// All Battle Logic is in here func PrepareForBattle(input []string) (Battlefield, Initiative) {
func (b *Battle) Fight() { var initiative Initiative
allCombatants := append(b.immune, b.infect...) battle := make(Battlefield)
sort.Sort(ByPower(allCombatants)) var currentArmy int
for k := len(allCombatants) - 1; k >= 0; k-- {
b.FindTargetFor(allCombatants[k]) for _, line := range input {
} if armyName.MatchString(line) {
if Debug { if id, ok := StringArmies[armyName.FindStringSubmatch(line)[1]]; ok {
fmt.Println("") currentArmy = id
} } else {
for k := len(allCombatants) - 1; k >= 0; k-- { panic(fmt.Errorf("unknown army: %s", armyName.FindStringSubmatch(line)[1]))
allCombatants[k].Fight() }
} } else {
i := 0 if currentArmy <= 0 || currentArmy >= ArmyCount {
for _, x := range b.immune { panic(fmt.Errorf("tried to assign group to invalid army: %d", currentArmy))
if x.units > 0 { }
b.immune[i] = x description := groupDescription.FindStringSubmatch(line)
i++ if len(description) == 0 {
continue
}
group := &Group{
Units: helpers2017.IntOrPanic(description[descriptionCount]),
HitPoints: helpers2017.IntOrPanic(description[descriptionHitPoints]),
AttackDamage: helpers2017.IntOrPanic(description[descriptionDamage]),
AttackType: description[descriptionDamageType],
Initiative: helpers2017.IntOrPanic(description[descriptionInitiative]),
}
immunities := groupImmunities.FindStringSubmatch(line)
if len(immunities) > 0 {
group.Immunities = strings.Split(immunities[1], ", ")
}
weaknesses := groupWeaknesses.FindStringSubmatch(line)
if len(weaknesses) > 0 {
group.Weaknesses = strings.Split(weaknesses[1], ", ")
}
battle[currentArmy] = append(battle[currentArmy], group)
initiative = append(initiative, group)
} }
} }
b.immune = b.immune[:i]
i = 0 return battle, initiative
for _, x := range b.infect { }
if x.units > 0 {
b.infect[i] = x func (b Battlefield) FindTargets() {
i++ for army, groups := range b {
sort.Sort(groups)
for _, group := range groups {
for enemyArmy, enemyGroups := range b {
if army == enemyArmy || group.Units <= 0 {
continue
}
var mostDamage int
var targetGroup *Group
for _, enemyGroup := range enemyGroups {
if enemyGroup.Units <= 0 || enemyGroup.Attacker != nil || group.DamageDealt(enemyGroup) == 0 || group.DamageDealt(enemyGroup) < mostDamage {
continue
}
if group.DamageDealt(enemyGroup) == mostDamage && targetGroup != nil {
if enemyGroup.EffectivePower() < targetGroup.EffectivePower() {
continue
}
if enemyGroup.EffectivePower() == targetGroup.EffectivePower() && enemyGroup.Initiative < targetGroup.Initiative {
continue
}
}
mostDamage = group.DamageDealt(enemyGroup)
targetGroup = enemyGroup
}
if targetGroup != nil {
group.Target = targetGroup
targetGroup.Attacker = group
}
}
} }
} }
b.infect = b.infect[:i]
} }
func (b *Battle) FindTargetFor(a *Army) { func (b Battlefield) Clean() {
if a.tp == ArmyTypeImmune { for army := range b {
a.FindTarget(b.infect) c := b[army][:0]
} else if a.tp == ArmyTypeInfection { for _, g := range b[army] {
a.FindTarget(b.immune) if g.Units > 0 {
c = append(c, g)
}
}
b[army] = c
} }
} }
func (b *Battle) IsOver() bool { func (b Battlefield) Active() bool {
return len(b.immune) == 0 || len(b.infect) == 0 for _, a := range b {
if !a.Alive() {
return false
}
}
return true
}
func (b Battlefield) Result() (int, int) {
var winner, units int
for army, groups := range b {
if groups.Alive() {
winner = army
for _, g := range groups {
if g.Units > 0 {
units += g.Units
}
}
}
}
return winner, units
}
func (b Battlefield) TotalUnits() int {
var sum int
for _, groups := range b {
for _, group := range groups {
if group.Units > 0 {
sum += group.Units
}
}
}
return sum
} }

View File

@ -12,45 +12,57 @@ const (
func main() { func main() {
inp := StdinToStringSlice() inp := StdinToStringSlice()
immune, infect := ParseInput(inp) fmt.Println(ConditionFight(inp))
fmt.Println(ImmuneSystemBoost(inp))
b := NewBattle(immune, infect)
//for !b.IsOver() {
if Debug {
b.PrintStatus()
fmt.Println("")
}
b.Fight()
//}
fmt.Println("")
fmt.Println("The battle is over!")
b.PrintStatus()
} }
func ParseInput(inp []string) ([]*Army, []*Army) { func ConditionFight(input []string) int {
var immune, infection []*Army battle, initiative := PrepareForBattle(input)
var tp, id int
for _, v := range inp { for battle.Active() {
if v == "" { battle.FindTargets()
continue initiative.Attack()
}
if v == "Immune System:" { battle.Clean()
tp, id = ArmyTypeImmune, 0 initiative.Clean()
continue }
} else if v == "Infection:" {
tp, id = ArmyTypeInfection, 0 _, units := battle.Result()
continue return units
} }
id++
switch tp { func ImmuneSystemBoost(input []string) int {
case ArmyTypeImmune: var boost int
immune = append(immune, NewArmy(v, tp, id))
case ArmyTypeInfection: for {
infection = append(infection, NewArmy(v, tp, id)) var stalemate bool
} battle, initiative := PrepareForBattle(input)
battle[ArmyImmuneSystem].Boost(boost)
for battle.Active() {
before := battle.TotalUnits()
battle.FindTargets()
initiative.Attack()
if battle.TotalUnits() == before {
stalemate = true
break
}
battle.Clean()
initiative.Clean()
}
if !stalemate {
winner, units := battle.Result()
if winner == ArmyImmuneSystem {
return units
}
}
boost++
} }
return immune, infection
} }
func StdinToStringSlice() []string { func StdinToStringSlice() []string {
@ -61,3 +73,12 @@ func StdinToStringSlice() []string {
} }
return input return input
} }
func ContainsString(l []string, t string) bool {
for _, s := range l {
if s == t {
return true
}
}
return false
}

52
2018/day24/group.go Normal file
View File

@ -0,0 +1,52 @@
package main
import (
"fmt"
"strings"
)
type Group struct {
Units int
HitPoints int
AttackDamage int
AttackType string
Initiative int
Immunities []string
Weaknesses []string
Attacker *Group
Target *Group
}
func (g Group) EffectivePower() int {
return g.Units * g.AttackDamage
}
func (g Group) DamageDealt(e *Group) int {
if ContainsString(e.Immunities, g.AttackType) {
return 0
}
if ContainsString(e.Weaknesses, g.AttackType) {
return g.EffectivePower() * 2
}
return g.EffectivePower()
}
func (g Group) String() string {
out := fmt.Sprintf("%d units each with %d hit points", g.Units, g.HitPoints)
if len(g.Immunities) > 0 || len(g.Weaknesses) > 0 {
out += " ("
if len(g.Immunities) > 0 {
out += "immune to " + strings.Join(g.Immunities, " and ")
if len(g.Weaknesses) > 0 {
out += "; "
}
}
if len(g.Weaknesses) > 0 {
out += "weak to " + strings.Join(g.Weaknesses, " and ")
}
out += ")"
}
out += fmt.Sprintf(" with an attack that does %d %s damage at initiative %d", g.AttackDamage, g.AttackType, g.Initiative)
return out
}

44
2018/day24/initiative.go Normal file
View File

@ -0,0 +1,44 @@
package main
import (
"sort"
)
type Initiative []*Group
func (in Initiative) Len() int {
return len(in)
}
func (in Initiative) Swap(i, j int) {
in[i], in[j] = in[j], in[i]
}
func (in Initiative) Less(i, j int) bool {
return in[i].Initiative > in[j].Initiative
}
func (in Initiative) Attack() {
sort.Sort(in)
for _, group := range in {
if group.Units > 0 && group.Target != nil && group.Target.Units > 0 {
group.Target.Units -= group.DamageDealt(group.Target) / group.Target.HitPoints
}
if group.Target != nil {
group.Target.Attacker = nil
group.Target = nil
}
}
}
func (in *Initiative) Clean() {
c := (*in)[:0]
for _, g := range *in {
if g.Units > 0 {
c = append(c, g)
}
}
sort.Sort(c)
*in = c
}

View File

@ -72,143 +72,242 @@ Advent of Code
For example, consider the following armies: For example, consider the following armies:
Immune System: Immune System: 17 units each with 5390 hit points (weak to radiation,
17 units each with 5390 hit points (weak to radiation, bludgeoning) with bludgeoning) with an attack that does 4507 fire damage at initiative 2 989
an attack that does 4507 fire damage at initiative 2 units each with 1274 hit points (immune to fire; weak to bludgeoning,
989 units each with 1274 hit points (immune to fire; weak to bludgeoning, slashing) with an attack that does 25 slashing damage at initiative 3
slashing) with an attack that does 25 slashing damage at initiative 3
Infection: Infection: 801 units each with 4706 hit points (weak to radiation) with an
801 units each with 4706 hit points (weak to radiation) with an attack attack that does 116 bludgeoning damage at initiative 1 4485 units each with
that does 116 bludgeoning damage at initiative 1 2961 hit points (immune to radiation; weak to fire, cold) with an attack that
4485 units each with 2961 hit points (immune to radiation; weak to fire, does 12 slashing damage at initiative 4
cold) with an attack that does 12 slashing damage at initiative 4
If these armies were to enter combat, the following fights, including details during the target selection and attacking phases, would take place: If these armies were to enter combat, the following fights, including
details during the target selection and attacking phases, would take place:
Immune System: Immune System: Group 1 contains 17 units Group 2 contains 989 units Infection:
Group 1 contains 17 units Group 1 contains 801 units Group 2 contains 4485 units
Group 2 contains 989 units
Infection:
Group 1 contains 801 units
Group 2 contains 4485 units
Infection group 1 would deal defending group 1 185832 damage Infection group 1 would deal defending group 1 185832 damage Infection group 1
Infection group 1 would deal defending group 2 185832 damage would deal defending group 2 185832 damage Infection group 2 would deal
Infection group 2 would deal defending group 2 107640 damage defending group 2 107640 damage Immune System group 1 would deal defending
Immune System group 1 would deal defending group 1 76619 damage group 1 76619 damage Immune System group 1 would deal defending group 2 153238
Immune System group 1 would deal defending group 2 153238 damage damage Immune System group 2 would deal defending group 1 24725 damage
Immune System group 2 would deal defending group 1 24725 damage
Infection group 2 attacks defending group 2, killing 84 units Infection group 2 attacks defending group 2, killing 84 units Immune System
Immune System group 2 attacks defending group 1, killing 4 units group 2 attacks defending group 1, killing 4 units Immune System group 1
Immune System group 1 attacks defending group 2, killing 51 units attacks defending group 2, killing 51 units Infection group 1 attacks
Infection group 1 attacks defending group 1, killing 17 units defending group 1, killing 17 units
Immune System: Immune System: Group 2 contains 905 units Infection: Group 1 contains 797
Group 2 contains 905 units units Group 2 contains 4434 units
Infection:
Group 1 contains 797 units Infection group 1 would deal defending group 2 184904 damage Immune System
group 2 would deal defending group 1 22625 damage Immune System group 2 would
deal defending group 2 22625 damage
Immune System group 2 attacks defending group 1, killing 4 units Infection
group 1 attacks defending group 2, killing 144 units
Immune System: Group 2 contains 761 units Infection: Group 1 contains 793
units Group 2 contains 4434 units
Infection group 1 would deal defending group 2 183976 damage Immune System
group 2 would deal defending group 1 19025 damage Immune System group 2 would
deal defending group 2 19025 damage
Immune System group 2 attacks defending group 1, killing 4 units Infection
group 1 attacks defending group 2, killing 143 units
Immune System: Group 2 contains 618 units Infection: Group 1 contains 789
units Group 2 contains 4434 units
Infection group 1 would deal defending group 2 183048 damage Immune System
group 2 would deal defending group 1 15450 damage Immune System group 2 would
deal defending group 2 15450 damage
Immune System group 2 attacks defending group 1, killing 3 units Infection
group 1 attacks defending group 2, killing 143 units
Immune System: Group 2 contains 475 units Infection: Group 1 contains 786
units Group 2 contains 4434 units
Infection group 1 would deal defending group 2 182352 damage Immune System
group 2 would deal defending group 1 11875 damage Immune System group 2 would
deal defending group 2 11875 damage
Immune System group 2 attacks defending group 1, killing 2 units Infection
group 1 attacks defending group 2, killing 142 units
Immune System: Group 2 contains 333 units Infection: Group 1 contains 784
units Group 2 contains 4434 units
Infection group 1 would deal defending group 2 181888 damage Immune System
group 2 would deal defending group 1 8325 damage Immune System group 2 would
deal defending group 2 8325 damage
Immune System group 2 attacks defending group 1, killing 1 unit Infection
group 1 attacks defending group 2, killing 142 units
Immune System: Group 2 contains 191 units Infection: Group 1 contains 783
units Group 2 contains 4434 units
Infection group 1 would deal defending group 2 181656 damage Immune System
group 2 would deal defending group 1 4775 damage Immune System group 2 would
deal defending group 2 4775 damage
Immune System group 2 attacks defending group 1, killing 1 unit Infection
group 1 attacks defending group 2, killing 142 units
Immune System: Group 2 contains 49 units Infection: Group 1 contains 782 units
Group 2 contains 4434 units Group 2 contains 4434 units
Infection group 1 would deal defending group 2 184904 damage Infection group 1 would deal defending group 2 181424 damage Immune System
Immune System group 2 would deal defending group 1 22625 damage group 2 would deal defending group 1 1225 damage Immune System group 2 would
Immune System group 2 would deal defending group 2 22625 damage deal defending group 2 1225 damage
Immune System group 2 attacks defending group 1, killing 4 units Immune System group 2 attacks defending group 1, killing 0 units Infection
Infection group 1 attacks defending group 2, killing 144 units group 1 attacks defending group 2, killing 49 units
Immune System: Immune System: No groups remain. Infection: Group 1 contains 782 units Group 2
Group 2 contains 761 units contains 4434 units
Infection:
Group 1 contains 793 units
Group 2 contains 4434 units
Infection group 1 would deal defending group 2 183976 damage
Immune System group 2 would deal defending group 1 19025 damage
Immune System group 2 would deal defending group 2 19025 damage
Immune System group 2 attacks defending group 1, killing 4 units
Infection group 1 attacks defending group 2, killing 143 units
Immune System:
Group 2 contains 618 units
Infection:
Group 1 contains 789 units
Group 2 contains 4434 units
Infection group 1 would deal defending group 2 183048 damage
Immune System group 2 would deal defending group 1 15450 damage
Immune System group 2 would deal defending group 2 15450 damage
Immune System group 2 attacks defending group 1, killing 3 units
Infection group 1 attacks defending group 2, killing 143 units
Immune System:
Group 2 contains 475 units
Infection:
Group 1 contains 786 units
Group 2 contains 4434 units
Infection group 1 would deal defending group 2 182352 damage
Immune System group 2 would deal defending group 1 11875 damage
Immune System group 2 would deal defending group 2 11875 damage
Immune System group 2 attacks defending group 1, killing 2 units
Infection group 1 attacks defending group 2, killing 142 units
Immune System:
Group 2 contains 333 units
Infection:
Group 1 contains 784 units
Group 2 contains 4434 units
Infection group 1 would deal defending group 2 181888 damage
Immune System group 2 would deal defending group 1 8325 damage
Immune System group 2 would deal defending group 2 8325 damage
Immune System group 2 attacks defending group 1, killing 1 unit
Infection group 1 attacks defending group 2, killing 142 units
Immune System:
Group 2 contains 191 units
Infection:
Group 1 contains 783 units
Group 2 contains 4434 units
Infection group 1 would deal defending group 2 181656 damage
Immune System group 2 would deal defending group 1 4775 damage
Immune System group 2 would deal defending group 2 4775 damage
Immune System group 2 attacks defending group 1, killing 1 unit
Infection group 1 attacks defending group 2, killing 142 units
Immune System:
Group 2 contains 49 units
Infection:
Group 1 contains 782 units
Group 2 contains 4434 units
Infection group 1 would deal defending group 2 181424 damage
Immune System group 2 would deal defending group 1 1225 damage
Immune System group 2 would deal defending group 2 1225 damage
Immune System group 2 attacks defending group 1, killing 0 units
Infection group 1 attacks defending group 2, killing 49 units
Immune System:
No groups remain.
Infection:
Group 1 contains 782 units
Group 2 contains 4434 units
In the example above, the winning army ends up with 782 + 4434 = 5216 units. In the example above, the winning army ends up with 782 + 4434 = 5216 units.
You scan the reindeer's condition (your puzzle input); the white-bearded man looks nervous. As it stands now, how many units would the winning army have? You scan the reindeer's condition (your puzzle input); the white-bearded man
looks nervous. As it stands now, how many units would the winning army have?
To begin, get your puzzle input. Your puzzle answer was 16747.
Answer: _____________________ [ [Submit] ] --- Part Two ---
Things aren't looking good for the reindeer. The man asks whether more milk
and cookies would help you think.
If only you could give the reindeer's immune system a boost, you might be
able to change the outcome of the combat.
A boost is an integer increase in immune system units' attack damage. For
example, if you were to boost the above example's immune system's units by
1570, the armies would instead look like this:
Immune System: 17 units each with 5390 hit points (weak to radiation,
bludgeoning) with an attack that does 6077 fire damage at initiative 2 989
units each with 1274 hit points (immune to fire; weak to bludgeoning,
slashing) with an attack that does 1595 slashing damage at initiative 3
Infection: 801 units each with 4706 hit points (weak to radiation) with an
attack that does 116 bludgeoning damage at initiative 1 4485 units each with
2961 hit points (immune to radiation; weak to fire, cold) with an attack that
does 12 slashing damage at initiative 4
With this boost, the combat proceeds differently:
Immune System: Group 2 contains 989 units Group 1 contains 17 units Infection:
Group 1 contains 801 units Group 2 contains 4485 units
Infection group 1 would deal defending group 2 185832 damage Infection group 1
would deal defending group 1 185832 damage Infection group 2 would deal
defending group 1 53820 damage Immune System group 2 would deal defending
group 1 1577455 damage Immune System group 2 would deal defending group 2
1577455 damage Immune System group 1 would deal defending group 2 206618
damage
Infection group 2 attacks defending group 1, killing 9 units Immune System
group 2 attacks defending group 1, killing 335 units Immune System group 1
attacks defending group 2, killing 32 units Infection group 1 attacks
defending group 2, killing 84 units
Immune System: Group 2 contains 905 units Group 1 contains 8 units Infection:
Group 1 contains 466 units Group 2 contains 4453 units
Infection group 1 would deal defending group 2 108112 damage Infection group 1
would deal defending group 1 108112 damage Infection group 2 would deal
defending group 1 53436 damage Immune System group 2 would deal defending
group 1 1443475 damage Immune System group 2 would deal defending group 2
1443475 damage Immune System group 1 would deal defending group 2 97232 damage
Infection group 2 attacks defending group 1, killing 8 units Immune System
group 2 attacks defending group 1, killing 306 units Infection group 1 attacks
defending group 2, killing 29 units
Immune System: Group 2 contains 876 units Infection: Group 2 contains 4453
units Group 1 contains 160 units
Infection group 2 would deal defending group 2 106872 damage Immune System
group 2 would deal defending group 2 1397220 damage Immune System group 2
would deal defending group 1 1397220 damage
Infection group 2 attacks defending group 2, killing 83 units Immune System
group 2 attacks defending group 2, killing 427 units
After a few fights...
Immune System: Group 2 contains 64 units Infection: Group 2 contains 214 units
Group 1 contains 19 units
Infection group 2 would deal defending group 2 5136 damage Immune System group
2 would deal defending group 2 102080 damage Immune System group 2 would deal
defending group 1 102080 damage
Infection group 2 attacks defending group 2, killing 4 units Immune System
group 2 attacks defending group 2, killing 32 units
Immune System: Group 2 contains 60 units Infection: Group 1 contains 19 units
Group 2 contains 182 units
Infection group 1 would deal defending group 2 4408 damage Immune System group
2 would deal defending group 1 95700 damage Immune System group 2 would deal
defending group 2 95700 damage
Immune System group 2 attacks defending group 1, killing 19 units
Immune System: Group 2 contains 60 units Infection: Group 2 contains 182 units
Infection group 2 would deal defending group 2 4368 damage Immune System group
2 would deal defending group 2 95700 damage
Infection group 2 attacks defending group 2, killing 3 units Immune System
group 2 attacks defending group 2, killing 30 units
After a few more fights...
Immune System: Group 2 contains 51 units Infection: Group 2 contains 40 units
Infection group 2 would deal defending group 2 960 damage Immune System group
2 would deal defending group 2 81345 damage
Infection group 2 attacks defending group 2, killing 0 units Immune System
group 2 attacks defending group 2, killing 27 units
Immune System: Group 2 contains 51 units Infection: Group 2 contains 13 units
Infection group 2 would deal defending group 2 312 damage Immune System group
2 would deal defending group 2 81345 damage
Infection group 2 attacks defending group 2, killing 0 units Immune System
group 2 attacks defending group 2, killing 13 units
Immune System: Group 2 contains 51 units Infection: No groups remain.
This boost would allow the immune system's armies to win! It would be left
with 51 units.
You don't even know how you could boost the reindeer's immune system or what
effect it might have, so you need to be cautious and find the smallest boost
that would allow the immune system to win.
How many units does the immune system have left after getting the smallest
boost it needs to win?
Your puzzle answer was 5923.
Both parts of this puzzle are complete! They provide two gold stars: **
At this point, you should return to your Advent calendar and try another
puzzle.
If you still want to see it, you can get your puzzle input.
References References
@ -228,4 +327,5 @@ References
. https://adventofcode.com/2018/stats . https://adventofcode.com/2018/stats
. https://adventofcode.com/2018/sponsors . https://adventofcode.com/2018/sponsors
. https://www.youtube.com/watch?v=NDVjLt_QHL8&t=7 . https://www.youtube.com/watch?v=NDVjLt_QHL8&t=7
. https://adventofcode.com/2018
. https://adventofcode.com/2018/day/24/input . https://adventofcode.com/2018/day/24/input

2
go.mod
View File

@ -2,6 +2,8 @@ module aoc
require ( require (
9fans.net/go v0.0.0-20181112161441-237454027057 // indirect 9fans.net/go v0.0.0-20181112161441-237454027057 // indirect
bitbucket.org/thezeez/advent-of-code-2017 v0.0.0-20171225063809-1918042ef639
bitbucket.org/thezeez/advent-of-code-2018 v0.0.0-20181225065213-533e12eb8451 // indirect
github.com/alecthomas/gometalinter v2.0.11+incompatible // indirect github.com/alecthomas/gometalinter v2.0.11+incompatible // indirect
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect
github.com/cosiner/argv v0.0.1 // indirect github.com/cosiner/argv v0.0.1 // indirect

4
go.sum
View File

@ -1,6 +1,10 @@
9fans.net/go v0.0.0-20150709035532-65b8cf069318/go.mod h1:diCsxrliIURU9xsYtjCp5AbpQKqdhKmf0ujWDUSkfoY= 9fans.net/go v0.0.0-20150709035532-65b8cf069318/go.mod h1:diCsxrliIURU9xsYtjCp5AbpQKqdhKmf0ujWDUSkfoY=
9fans.net/go v0.0.0-20181112161441-237454027057 h1:OcHlKWkAMJEF1ndWLGxp5dnJQkYM/YImUOvsBoz6h5E= 9fans.net/go v0.0.0-20181112161441-237454027057 h1:OcHlKWkAMJEF1ndWLGxp5dnJQkYM/YImUOvsBoz6h5E=
9fans.net/go v0.0.0-20181112161441-237454027057/go.mod h1:diCsxrliIURU9xsYtjCp5AbpQKqdhKmf0ujWDUSkfoY= 9fans.net/go v0.0.0-20181112161441-237454027057/go.mod h1:diCsxrliIURU9xsYtjCp5AbpQKqdhKmf0ujWDUSkfoY=
bitbucket.org/thezeez/advent-of-code-2017 v0.0.0-20171225063809-1918042ef639 h1:DsF/Ldc/v0ftwLoE1WFJ1yAAkzK4XJ0Rx6Ww87AWFdo=
bitbucket.org/thezeez/advent-of-code-2017 v0.0.0-20171225063809-1918042ef639/go.mod h1:0hCXmcMGkJQ6c4PhTVJLrbCvsxRpLoq84HQE8u8fFeY=
bitbucket.org/thezeez/advent-of-code-2018 v0.0.0-20181225065213-533e12eb8451 h1:IFdtuKSjoogiNOcVqsANmYqy3jR2+AYdKolN6fDO2rg=
bitbucket.org/thezeez/advent-of-code-2018 v0.0.0-20181225065213-533e12eb8451/go.mod h1:EmAD0MqW6nbmxrTlT7Lvzjv22xm5tcKgu6k0sBIMf6Y=
github.com/alecthomas/gometalinter v2.0.11+incompatible h1:toROE7pXPU/pUB4lh6ICqUKwpDtmkRCyJIr1nYqmKp0= github.com/alecthomas/gometalinter v2.0.11+incompatible h1:toROE7pXPU/pUB4lh6ICqUKwpDtmkRCyJIr1nYqmKp0=
github.com/alecthomas/gometalinter v2.0.11+incompatible/go.mod h1:qfIpQGGz3d+NmgyPBqv+LSh50emm1pt72EtcX2vKYQk= github.com/alecthomas/gometalinter v2.0.11+incompatible/go.mod h1:qfIpQGGz3d+NmgyPBqv+LSh50emm1pt72EtcX2vKYQk=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=