-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathday_21b.cpp
101 lines (94 loc) · 2.9 KB
/
day_21b.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <cmath>
#include <fstream>
#include <iostream>
#include <regex>
#include <string>
#include <string_view>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <limits>
struct Entity {
int hp;
int damage;
int armour;
};
int calculate_strikes(const Entity& striker, const Entity& struck) {
const int damage_dealt = std::max(1, striker.damage - struck.armour);
return std::ceil(static_cast<float>(struck.hp) / damage_dealt);
}
struct Item {
std::string name;
int cost;
int damage;
int armour;
};
std::vector<Item> weapons {
{"Dagger",8,4,0},
{"Shortsword",10,5,0},
{"Warhammer",25,6,0},
{"Longsword",40,7,0},
{"Greataxe",74,8,0},
};
std::vector<Item> armours {
{"Leather",13,0,1},
{"Chainmail",31,0,2},
{"Splintmail",53,0,3},
{"Bandedmail",75,0,4},
{"Platemail",102,0,5},
{"None",0,0,0},
};
std::vector<Item> rings {
{"Damage+1",25,1,0},
{"Damage+2",50,2,0},
{"Damage+3",100,3,0},
{"Defense+1",20,0,1},
{"Defense+2",40,0,2},
{"Defense+3",80,0,3},
{"None", 0,0,0},
};
int main(int argc, char * argv[]) {
std::string input = "../input/day_21_input";
if (argc > 1) {
input = argv[1];
}
std::ifstream file(input);
std::string line;
std::getline(file, line);
Entity enemy;
enemy.hp = std::stoi(line.substr(line.find(':') + 2, line.size()- line.find(':') - 2));
std::getline(file, line);
enemy.damage = std::stoi(line.substr(line.find(':') + 2, line.size()- line.find(':') - 2));
std::getline(file, line);
enemy.armour = std::stoi(line.substr(line.find(':') + 2, line.size()- line.find(':') - 2));
int max_cost = 0;
Entity player;
player.hp = 100;
for (const auto& weapon : weapons) {
for (const auto& armour : armours) {
{
// No rings
player.damage = weapon.damage;
player.armour = armour.armour;
if (calculate_strikes(player, enemy) > calculate_strikes(enemy, player)) {
int cost = weapon.cost + armour.cost;
max_cost = std::max(cost, max_cost);
}
}
for (int r1 = 0; r1 < rings.size(); r1++) {
for (int r2 = r1+1; r2 < rings.size(); r2++) {
player.damage = weapon.damage;
player.armour = armour.armour;
player.damage += rings[r1].damage + rings[r2].damage;
player.armour += rings[r1].armour + rings[r2].armour;
if (calculate_strikes(player, enemy) > calculate_strikes(enemy, player)) {
int cost = weapon.cost + armour.cost + rings[r1].cost + rings[r2].cost;
max_cost = std::max(cost, max_cost);
}
}
}
}
}
std::cout << max_cost << '\n';
}