Combine AoC Repos
This commit is contained in:
227
2015/day22/main.go
Normal file
227
2015/day22/main.go
Normal file
@@ -0,0 +1,227 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
playerTurn = iota
|
||||
bossTurn
|
||||
)
|
||||
|
||||
type state struct {
|
||||
bossHp int
|
||||
bossDmg int
|
||||
playerHp int
|
||||
playerMp int
|
||||
playerDef int
|
||||
shield int
|
||||
poison int
|
||||
recharge int
|
||||
manaSpent int
|
||||
move int
|
||||
}
|
||||
|
||||
type spell struct {
|
||||
name string
|
||||
mpCost int
|
||||
damage int
|
||||
heal int
|
||||
duration int
|
||||
}
|
||||
|
||||
var minMp int
|
||||
var spellBook []spell
|
||||
var stateStack []state
|
||||
|
||||
func main() {
|
||||
minMp = -1
|
||||
initSpellBook()
|
||||
if len(os.Args) == 2 && os.Args[1] == "-help" {
|
||||
fmt.Println("Usage: day22 [<boss hp> <boss dmg> [<player hp> <player mp>]]")
|
||||
os.Exit(1)
|
||||
}
|
||||
//debugMode = true
|
||||
eHp := 71
|
||||
eDmg := 10
|
||||
if len(os.Args) >= 3 {
|
||||
eHp = mustAtoi(os.Args[1])
|
||||
eDmg = mustAtoi(os.Args[2])
|
||||
}
|
||||
pHp := 50
|
||||
pMp := 500
|
||||
if len(os.Args) == 5 {
|
||||
pHp = mustAtoi(os.Args[3])
|
||||
pMp = mustAtoi(os.Args[4])
|
||||
}
|
||||
s := state{
|
||||
bossHp: eHp,
|
||||
bossDmg: eDmg,
|
||||
playerHp: pHp,
|
||||
playerMp: pMp,
|
||||
playerDef: 0,
|
||||
shield: 0,
|
||||
poison: 0,
|
||||
recharge: 0,
|
||||
manaSpent: 0,
|
||||
move: playerTurn,
|
||||
}
|
||||
stateStack = append(stateStack, s)
|
||||
for len(stateStack) > 0 {
|
||||
var wrk state
|
||||
wrk, stateStack = stateStack[0], stateStack[1:]
|
||||
// Hard Mode
|
||||
if wrk.move == playerTurn {
|
||||
wrk.playerHp--
|
||||
}
|
||||
wrk.playerDef = 0
|
||||
if wrk.shield > 0 {
|
||||
wrk.playerDef = 7
|
||||
}
|
||||
if wrk.poison > 0 {
|
||||
wrk.bossHp -= 3
|
||||
}
|
||||
if wrk.recharge > 0 {
|
||||
wrk.playerMp += 101
|
||||
}
|
||||
wrk = decrementTimers(wrk)
|
||||
if wrk.playerHp <= 0 || (wrk.manaSpent > minMp && minMp != -1) {
|
||||
// Unsuccessful path
|
||||
continue
|
||||
}
|
||||
if wrk.bossHp <= 0 {
|
||||
// Successful path!
|
||||
if minMp == -1 || minMp > wrk.manaSpent {
|
||||
minMp = wrk.manaSpent
|
||||
}
|
||||
continue
|
||||
}
|
||||
if wrk.move == bossTurn {
|
||||
wrk.move = playerTurn
|
||||
atk := 1
|
||||
if wrk.bossDmg-wrk.playerDef > 1 {
|
||||
atk = wrk.bossDmg - wrk.playerDef
|
||||
}
|
||||
wrk.playerHp -= atk
|
||||
stateStack = append([]state{wrk}, stateStack...)
|
||||
} else {
|
||||
wrk.move = bossTurn
|
||||
for i := range spellBook {
|
||||
tstSpell := spellBook[i]
|
||||
if tstSpell.mpCost >= wrk.playerMp {
|
||||
continue
|
||||
}
|
||||
nextState, ok := castSpell(wrk, tstSpell)
|
||||
if ok {
|
||||
stateStack = append([]state{nextState}, stateStack...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Printf("%d\n", minMp)
|
||||
}
|
||||
|
||||
func castSpell(w state, s spell) (state, bool) {
|
||||
if s.name == "Magic Missile" || s.name == "Drain" {
|
||||
w.bossHp -= s.damage
|
||||
w.playerHp += s.heal
|
||||
} else if s.name == "Shield" {
|
||||
if w.shield > 0 {
|
||||
return w, false
|
||||
}
|
||||
w.shield = s.duration
|
||||
} else if s.name == "Poison" {
|
||||
if w.poison > 0 {
|
||||
return w, false
|
||||
}
|
||||
w.poison = s.duration
|
||||
} else if s.name == "Recharge" {
|
||||
if w.recharge > 0 {
|
||||
return w, false
|
||||
}
|
||||
w.recharge = s.duration
|
||||
}
|
||||
w.playerMp -= s.mpCost
|
||||
w.manaSpent += s.mpCost
|
||||
return w, true
|
||||
}
|
||||
|
||||
func copyState(w state) state {
|
||||
ret := state{
|
||||
bossHp: w.bossHp,
|
||||
bossDmg: w.bossDmg,
|
||||
playerHp: w.playerHp,
|
||||
playerMp: w.playerMp,
|
||||
playerDef: w.playerDef,
|
||||
shield: w.shield,
|
||||
poison: w.poison,
|
||||
recharge: w.recharge,
|
||||
manaSpent: w.manaSpent,
|
||||
move: w.move,
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func printState(w state) {
|
||||
if w.move == playerTurn {
|
||||
fmt.Println("*** Player Turn ***")
|
||||
} else {
|
||||
fmt.Println("*** Boss Turn ***")
|
||||
}
|
||||
fmt.Printf("Player - HP(%d) MP(%d)\n", w.playerHp, w.playerMp)
|
||||
fmt.Printf("Boss - HP(%d) DMG(%d)\n", w.bossHp, w.bossDmg)
|
||||
fmt.Printf("Shield(%d); Poison(%d); Recharge(%d)\n", w.shield, w.poison, w.recharge)
|
||||
fmt.Printf("Mana Used: %d\n", w.manaSpent)
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func decrementTimers(w state) state {
|
||||
w.shield--
|
||||
w.poison--
|
||||
w.recharge--
|
||||
return w
|
||||
}
|
||||
|
||||
func initSpellBook() {
|
||||
spellBook = append(spellBook, spell{
|
||||
name: "Magic Missile",
|
||||
mpCost: 53,
|
||||
damage: 4,
|
||||
})
|
||||
spellBook = append(spellBook, spell{
|
||||
name: "Drain",
|
||||
mpCost: 73,
|
||||
damage: 2,
|
||||
heal: 2,
|
||||
})
|
||||
spellBook = append(spellBook, spell{
|
||||
name: "Shield",
|
||||
mpCost: 113,
|
||||
duration: 6,
|
||||
})
|
||||
spellBook = append(spellBook, spell{
|
||||
name: "Poison",
|
||||
mpCost: 173,
|
||||
duration: 6,
|
||||
})
|
||||
spellBook = append(spellBook, spell{
|
||||
name: "Recharge",
|
||||
mpCost: 229,
|
||||
duration: 5,
|
||||
})
|
||||
}
|
||||
|
||||
func itoa(i int) string {
|
||||
return strconv.Itoa(i)
|
||||
}
|
||||
func mustAtoi(s string) int {
|
||||
var i int
|
||||
var err error
|
||||
if i, err = strconv.Atoi(s); err != nil {
|
||||
fmt.Println("Tried to atoi " + s)
|
||||
os.Exit(1)
|
||||
}
|
||||
return i
|
||||
}
|
161
2015/day22/problem
Normal file
161
2015/day22/problem
Normal file
@@ -0,0 +1,161 @@
|
||||
Advent of Code
|
||||
|
||||
br0xen 44*
|
||||
|
||||
• [About]
|
||||
• [Stats]
|
||||
• [Leaderboard]
|
||||
• [Settings]
|
||||
• [Log out]
|
||||
|
||||
--- Day 22: Wizard Simulator 20XX ---
|
||||
|
||||
Little Henry Case decides that defeating bosses with swords and stuff is boring. Now he's
|
||||
playing the game with a wizard. Of course, he gets stuck on another boss and needs your help
|
||||
again.
|
||||
|
||||
In this version, combat still proceeds with the player and the boss taking alternating turns.
|
||||
The player still goes first. Now, however, you don't get any equipment; instead, you must
|
||||
choose one of your spells to cast. The first character at or below 0 hit points loses.
|
||||
|
||||
Since you're a wizard, you don't get to wear armor, and you can't attack normally. However,
|
||||
since you do magic damage, your opponent's armor is ignored, and so the boss effectively has
|
||||
zero armor as well. As before, if armor (from a spell, in this case) would reduce damage below
|
||||
1, it becomes 1 instead - that is, the boss' attacks always deal at least 1 damage.
|
||||
|
||||
On each of your turns, you must select one of your spells to cast. If you cannot afford to
|
||||
cast any spell, you lose. Spells cost mana; you start with 500 mana, but have no maximum
|
||||
limit. You must have enough mana to cast a spell, and its cost is immediately deducted when
|
||||
you cast it. Your spells are Magic Missile, Drain, Shield, Poison, and Recharge.
|
||||
|
||||
• Magic Missile costs 53 mana. It instantly does 4 damage.
|
||||
• Drain costs 73 mana. It instantly does 2 damage and heals you for 2 hit points.
|
||||
• Shield costs 113 mana. It starts an effect that lasts for 6 turns. While it is active,
|
||||
your armor is increased by 7.
|
||||
• Poison costs 173 mana. It starts an effect that lasts for 6 turns. At the start of each
|
||||
turn while it is active, it deals the boss 3 damage.
|
||||
• Recharge costs 229 mana. It starts an effect that lasts for 5 turns. At the start of each
|
||||
turn while it is active, it gives you 101 new mana.
|
||||
|
||||
Effects all work the same way. Effects apply at the start of both the player's turns and the
|
||||
boss' turns. Effects are created with a timer (the number of turns they last); at the start of
|
||||
each turn, after they apply any effect they have, their timer is decreased by one. If this
|
||||
decreases the timer to zero, the effect ends. You cannot cast a spell that would start an
|
||||
effect which is already active. However, effects can be started on the same turn they end.
|
||||
|
||||
For example, suppose the player has 10 hit points and 250 mana, and that the boss has 13 hit
|
||||
points and 8 damage:
|
||||
|
||||
-- Player turn --
|
||||
- Player has 10 hit points, 0 armor, 250 mana
|
||||
- Boss has 13 hit points
|
||||
Player casts Poison.
|
||||
|
||||
-- Boss turn --
|
||||
- Player has 10 hit points, 0 armor, 77 mana
|
||||
- Boss has 13 hit points
|
||||
Poison deals 3 damage; its timer is now 5.
|
||||
Boss attacks for 8 damage.
|
||||
|
||||
-- Player turn --
|
||||
- Player has 2 hit points, 0 armor, 77 mana
|
||||
- Boss has 10 hit points
|
||||
Poison deals 3 damage; its timer is now 4.
|
||||
Player casts Magic Missile, dealing 4 damage.
|
||||
|
||||
-- Boss turn --
|
||||
- Player has 2 hit points, 0 armor, 24 mana
|
||||
- Boss has 3 hit points
|
||||
Poison deals 3 damage. This kills the boss, and the player wins.
|
||||
|
||||
Now, suppose the same initial conditions, except that the boss has 14 hit points instead:
|
||||
|
||||
-- Player turn --
|
||||
- Player has 10 hit points, 0 armor, 250 mana
|
||||
- Boss has 14 hit points
|
||||
Player casts Recharge.
|
||||
|
||||
-- Boss turn --
|
||||
- Player has 10 hit points, 0 armor, 21 mana
|
||||
- Boss has 14 hit points
|
||||
Recharge provides 101 mana; its timer is now 4.
|
||||
Boss attacks for 8 damage!
|
||||
|
||||
-- Player turn --
|
||||
- Player has 2 hit points, 0 armor, 122 mana
|
||||
- Boss has 14 hit points
|
||||
Recharge provides 101 mana; its timer is now 3.
|
||||
Player casts Shield, increasing armor by 7.
|
||||
|
||||
-- Boss turn --
|
||||
- Player has 2 hit points, 7 armor, 110 mana
|
||||
- Boss has 14 hit points
|
||||
Shield's timer is now 5.
|
||||
Recharge provides 101 mana; its timer is now 2.
|
||||
Boss attacks for 8 - 7 = 1 damage!
|
||||
|
||||
-- Player turn --
|
||||
- Player has 1 hit point, 7 armor, 211 mana
|
||||
- Boss has 14 hit points
|
||||
Shield's timer is now 4.
|
||||
Recharge provides 101 mana; its timer is now 1.
|
||||
Player casts Drain, dealing 2 damage, and healing 2 hit points.
|
||||
|
||||
-- Boss turn --
|
||||
- Player has 3 hit points, 7 armor, 239 mana
|
||||
- Boss has 12 hit points
|
||||
Shield's timer is now 3.
|
||||
Recharge provides 101 mana; its timer is now 0.
|
||||
Recharge wears off.
|
||||
Boss attacks for 8 - 7 = 1 damage!
|
||||
|
||||
-- Player turn --
|
||||
- Player has 2 hit points, 7 armor, 340 mana
|
||||
- Boss has 12 hit points
|
||||
Shield's timer is now 2.
|
||||
Player casts Poison.
|
||||
|
||||
-- Boss turn --
|
||||
- Player has 2 hit points, 7 armor, 167 mana
|
||||
- Boss has 12 hit points
|
||||
Shield's timer is now 1.
|
||||
Poison deals 3 damage; its timer is now 5.
|
||||
Boss attacks for 8 - 7 = 1 damage!
|
||||
|
||||
-- Player turn --
|
||||
- Player has 1 hit point, 7 armor, 167 mana
|
||||
- Boss has 9 hit points
|
||||
Shield's timer is now 0.
|
||||
Shield wears off, decreasing armor by 7.
|
||||
Poison deals 3 damage; its timer is now 4.
|
||||
Player casts Magic Missile, dealing 4 damage.
|
||||
|
||||
-- Boss turn --
|
||||
- Player has 1 hit point, 0 armor, 114 mana
|
||||
- Boss has 2 hit points
|
||||
Poison deals 3 damage. This kills the boss, and the player wins.
|
||||
|
||||
You start with 50 hit points and 500 mana points. The boss's actual stats are in your puzzle
|
||||
input. What is the least amount of mana you can spend and still win the fight? (Do not include
|
||||
mana recharge effects as "spending" negative mana.)
|
||||
|
||||
To begin, get your puzzle input.
|
||||
|
||||
Answer: _____________________ [ [Submit] ]
|
||||
|
||||
You can also [Shareon Twitter Google+ Reddit] this puzzle.
|
||||
|
||||
References
|
||||
|
||||
Visible links
|
||||
. http://adventofcode.com/
|
||||
. http://adventofcode.com/about
|
||||
. http://adventofcode.com/stats
|
||||
. http://adventofcode.com/leaderboard
|
||||
. http://adventofcode.com/settings
|
||||
. http://adventofcode.com/auth/logout
|
||||
. http://adventofcode.com/day/21
|
||||
. http://adventofcode.com/day/22/input
|
||||
. https://twitter.com/intent/tweet?text=%22Wizard+Simulator+20XX%22+%2D+Day+22+%2D+Advent+of+Code&url=http%3A%2F%2Fadventofcode%2Ecom%2Fday%2F22&related=ericwastl&hashtags=AdventOfCode
|
||||
. https://plus.google.com/share?url=http%3A%2F%2Fadventofcode%2Ecom%2Fday%2F22
|
||||
. http://www.reddit.com/submit?url=http%3A%2F%2Fadventofcode%2Ecom%2Fday%2F22&title=%22Wizard+Simulator+20XX%22+%2D+Day+22+%2D+Advent+of+Code
|
Reference in New Issue
Block a user