2018 Day 24 Done
This commit is contained in:
parent
10af09b200
commit
83313cc77b
@ -1,210 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
type Army []*Group
|
||||
|
||||
const (
|
||||
ArmyTypeImmune = 1 << iota
|
||||
ArmyTypeInfection
|
||||
ArmyImmuneSystem = iota + 1
|
||||
ArmyInfection
|
||||
ArmyCount
|
||||
)
|
||||
|
||||
type Army struct {
|
||||
id int
|
||||
tp int
|
||||
units int
|
||||
hp int
|
||||
immunities []string
|
||||
weaknesses []string
|
||||
damageType string
|
||||
strength int
|
||||
init int
|
||||
target *Army
|
||||
targettedBy *Army
|
||||
var StringArmies = map[string]int{
|
||||
"Immune System": ArmyImmuneSystem,
|
||||
"Infection": ArmyInfection,
|
||||
}
|
||||
|
||||
func NewArmy(inp string, tp, id int) *Army {
|
||||
a := new(Army)
|
||||
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) Swap(i, j int) {
|
||||
a[i], a[j] = a[j], a[i]
|
||||
}
|
||||
|
||||
func (a *Army) IsImmuneTo(val string) bool {
|
||||
for _, v := range a.immunities {
|
||||
if v == val {
|
||||
func (a Army) Len() int {
|
||||
return len(a)
|
||||
}
|
||||
|
||||
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 false
|
||||
}
|
||||
|
||||
func (a *Army) IsWeakTo(val string) bool {
|
||||
for _, v := range a.weaknesses {
|
||||
if v == val {
|
||||
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) Boost(amount int) {
|
||||
for _, g := range a {
|
||||
g.AttackDamage += amount
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
@ -2,71 +2,160 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
helpers2017 "bitbucket.org/thezeez/advent-of-code-2017/helpers"
|
||||
)
|
||||
|
||||
type Battle struct {
|
||||
immune []*Army
|
||||
infect []*Army
|
||||
}
|
||||
type Battlefield map[int]Army
|
||||
|
||||
func NewBattle(immune, infect []*Army) *Battle {
|
||||
return &Battle{
|
||||
immune: immune,
|
||||
infect: infect,
|
||||
}
|
||||
}
|
||||
var (
|
||||
armyName = regexp.MustCompile(`^(.*):$`)
|
||||
groupImmunities = regexp.MustCompile(`immune to (.*?)[;)]`)
|
||||
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() {
|
||||
fmt.Println("Immune System:")
|
||||
for _, v := range b.immune {
|
||||
fmt.Printf("Group %d contains %d units\n", v.id, v.units)
|
||||
}
|
||||
fmt.Println("Infection:")
|
||||
for _, v := range b.infect {
|
||||
fmt.Printf("Group %d contains %d units\n", v.id, v.units)
|
||||
}
|
||||
}
|
||||
const (
|
||||
descriptionCount = iota + 1
|
||||
descriptionHitPoints
|
||||
descriptionDamage
|
||||
descriptionDamageType
|
||||
descriptionInitiative
|
||||
)
|
||||
|
||||
// All Battle Logic is in here
|
||||
func (b *Battle) Fight() {
|
||||
allCombatants := append(b.immune, b.infect...)
|
||||
sort.Sort(ByPower(allCombatants))
|
||||
for k := len(allCombatants) - 1; k >= 0; k-- {
|
||||
b.FindTargetFor(allCombatants[k])
|
||||
}
|
||||
if Debug {
|
||||
fmt.Println("")
|
||||
}
|
||||
for k := len(allCombatants) - 1; k >= 0; k-- {
|
||||
allCombatants[k].Fight()
|
||||
}
|
||||
i := 0
|
||||
for _, x := range b.immune {
|
||||
if x.units > 0 {
|
||||
b.immune[i] = x
|
||||
i++
|
||||
func PrepareForBattle(input []string) (Battlefield, Initiative) {
|
||||
var initiative Initiative
|
||||
battle := make(Battlefield)
|
||||
var currentArmy int
|
||||
|
||||
for _, line := range input {
|
||||
if armyName.MatchString(line) {
|
||||
if id, ok := StringArmies[armyName.FindStringSubmatch(line)[1]]; ok {
|
||||
currentArmy = id
|
||||
} else {
|
||||
panic(fmt.Errorf("unknown army: %s", armyName.FindStringSubmatch(line)[1]))
|
||||
}
|
||||
} else {
|
||||
if currentArmy <= 0 || currentArmy >= ArmyCount {
|
||||
panic(fmt.Errorf("tried to assign group to invalid army: %d", currentArmy))
|
||||
}
|
||||
description := groupDescription.FindStringSubmatch(line)
|
||||
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
|
||||
for _, x := range b.infect {
|
||||
if x.units > 0 {
|
||||
b.infect[i] = x
|
||||
i++
|
||||
|
||||
return battle, initiative
|
||||
}
|
||||
|
||||
func (b Battlefield) FindTargets() {
|
||||
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) {
|
||||
if a.tp == ArmyTypeImmune {
|
||||
a.FindTarget(b.infect)
|
||||
} else if a.tp == ArmyTypeInfection {
|
||||
a.FindTarget(b.immune)
|
||||
func (b Battlefield) Clean() {
|
||||
for army := range b {
|
||||
c := b[army][:0]
|
||||
for _, g := range b[army] {
|
||||
if g.Units > 0 {
|
||||
c = append(c, g)
|
||||
}
|
||||
}
|
||||
b[army] = c
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Battle) IsOver() bool {
|
||||
return len(b.immune) == 0 || len(b.infect) == 0
|
||||
func (b Battlefield) Active() bool {
|
||||
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
|
||||
}
|
||||
|
@ -12,45 +12,57 @@ const (
|
||||
|
||||
func main() {
|
||||
inp := StdinToStringSlice()
|
||||
immune, infect := ParseInput(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()
|
||||
fmt.Println(ConditionFight(inp))
|
||||
fmt.Println(ImmuneSystemBoost(inp))
|
||||
}
|
||||
|
||||
func ParseInput(inp []string) ([]*Army, []*Army) {
|
||||
var immune, infection []*Army
|
||||
var tp, id int
|
||||
for _, v := range inp {
|
||||
if v == "" {
|
||||
continue
|
||||
}
|
||||
if v == "Immune System:" {
|
||||
tp, id = ArmyTypeImmune, 0
|
||||
continue
|
||||
} else if v == "Infection:" {
|
||||
tp, id = ArmyTypeInfection, 0
|
||||
continue
|
||||
}
|
||||
id++
|
||||
switch tp {
|
||||
case ArmyTypeImmune:
|
||||
immune = append(immune, NewArmy(v, tp, id))
|
||||
case ArmyTypeInfection:
|
||||
infection = append(infection, NewArmy(v, tp, id))
|
||||
}
|
||||
func ConditionFight(input []string) int {
|
||||
battle, initiative := PrepareForBattle(input)
|
||||
|
||||
for battle.Active() {
|
||||
battle.FindTargets()
|
||||
initiative.Attack()
|
||||
|
||||
battle.Clean()
|
||||
initiative.Clean()
|
||||
}
|
||||
|
||||
_, units := battle.Result()
|
||||
return units
|
||||
}
|
||||
|
||||
func ImmuneSystemBoost(input []string) int {
|
||||
var boost int
|
||||
|
||||
for {
|
||||
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 {
|
||||
@ -61,3 +73,12 @@ func StdinToStringSlice() []string {
|
||||
}
|
||||
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
52
2018/day24/group.go
Normal 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
44
2018/day24/initiative.go
Normal 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
|
||||
}
|
@ -72,143 +72,242 @@ Advent of Code
|
||||
|
||||
For example, consider the following armies:
|
||||
|
||||
Immune System:
|
||||
17 units each with 5390 hit points (weak to radiation, bludgeoning) with
|
||||
an attack that does 4507 fire damage at initiative 2
|
||||
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
|
||||
Immune System: 17 units each with 5390 hit points (weak to radiation,
|
||||
bludgeoning) with an attack that does 4507 fire damage at initiative 2 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
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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:
|
||||
Group 1 contains 17 units
|
||||
Group 2 contains 989 units
|
||||
Infection:
|
||||
Group 1 contains 801 units
|
||||
Group 2 contains 4485 units
|
||||
Immune System: Group 1 contains 17 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 2 185832 damage
|
||||
Infection group 2 would deal defending group 2 107640 damage
|
||||
Immune System group 1 would deal defending group 1 76619 damage
|
||||
Immune System group 1 would deal defending group 2 153238 damage
|
||||
Immune System group 2 would deal defending group 1 24725 damage
|
||||
Infection group 1 would deal defending group 1 185832 damage Infection group 1
|
||||
would deal defending group 2 185832 damage Infection group 2 would deal
|
||||
defending group 2 107640 damage Immune System group 1 would deal defending
|
||||
group 1 76619 damage Immune System group 1 would deal defending group 2 153238
|
||||
damage Immune System group 2 would deal defending group 1 24725 damage
|
||||
|
||||
Infection group 2 attacks defending group 2, killing 84 units
|
||||
Immune System group 2 attacks defending group 1, killing 4 units
|
||||
Immune System group 1 attacks defending group 2, killing 51 units
|
||||
Infection group 1 attacks defending group 1, killing 17 units
|
||||
Infection group 2 attacks defending group 2, killing 84 units Immune System
|
||||
group 2 attacks defending group 1, killing 4 units Immune System group 1
|
||||
attacks defending group 2, killing 51 units Infection group 1 attacks
|
||||
defending group 1, killing 17 units
|
||||
|
||||
Immune System:
|
||||
Group 2 contains 905 units
|
||||
Infection:
|
||||
Group 1 contains 797 units
|
||||
Immune System: Group 2 contains 905 units Infection: Group 1 contains 797
|
||||
units Group 2 contains 4434 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
|
||||
|
||||
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
|
||||
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 4 units
|
||||
Infection group 1 attacks defending group 2, killing 144 units
|
||||
Immune System group 2 attacks defending group 1, killing 0 units Infection
|
||||
group 1 attacks defending group 2, killing 49 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
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
@ -228,4 +327,5 @@ References
|
||||
. https://adventofcode.com/2018/stats
|
||||
. https://adventofcode.com/2018/sponsors
|
||||
. https://www.youtube.com/watch?v=NDVjLt_QHL8&t=7
|
||||
. https://adventofcode.com/2018
|
||||
. https://adventofcode.com/2018/day/24/input
|
||||
|
2
go.mod
2
go.mod
@ -2,6 +2,8 @@ module aoc
|
||||
|
||||
require (
|
||||
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/units v0.0.0-20151022065526-2efee857e7cf // indirect
|
||||
github.com/cosiner/argv v0.0.1 // indirect
|
||||
|
4
go.sum
4
go.sum
@ -1,6 +1,10 @@
|
||||
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/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/go.mod h1:qfIpQGGz3d+NmgyPBqv+LSh50emm1pt72EtcX2vKYQk=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
|
||||
|
Loading…
Reference in New Issue
Block a user