Skip to content

Commit fc68a0e

Browse files
committed
Year 2015 Day 21
1 parent dc61fc6 commit fc68a0e

File tree

8 files changed

+112
-0
lines changed

8 files changed

+112
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,4 @@ pie
256256
| 18 | [Like a GIF For Your Yard](https://adventofcode.com/2015/day/18) | [Source](src/year2015/day18.rs) | 161 |
257257
| 19 | [Medicine for Rudolph](https://adventofcode.com/2015/day/19) | [Source](src/year2015/day19.rs) | 188 |
258258
| 20 | [Infinite Elves and Infinite Houses](https://adventofcode.com/2015/day/20) | [Source](src/year2015/day20.rs) | 1671 |
259+
| 21 | [RPG Simulator 20XX](https://adventofcode.com/2015/day/21) | [Source](src/year2015/day21.rs) | 3 |

benches/benchmark.rs

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ mod year2015 {
5656
benchmark!(year2015, day18);
5757
benchmark!(year2015, day19);
5858
benchmark!(year2015, day20);
59+
benchmark!(year2015, day21);
5960
}
6061

6162
mod year2019 {

input/year2015/day21.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Hit Points: 100
2+
Damage: 8
3+
Armor: 2

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ pub mod year2015 {
180180
pub mod day18;
181181
pub mod day19;
182182
pub mod day20;
183+
pub mod day21;
183184
}
184185

185186
/// # Rescue Santa from deep space with a solar system adventure.

src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ fn all_solutions() -> Vec<Solution> {
9696
solution!(year2015, day18),
9797
solution!(year2015, day19),
9898
solution!(year2015, day20),
99+
solution!(year2015, day21),
99100
// 2019
100101
solution!(year2019, day01),
101102
solution!(year2019, day02),

src/year2015/day21.rs

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//! # RPG Simulator 20XX
2+
//!
3+
//! The trick to get the outcome of each battle quickly is to divide the hero's health by the
4+
//! boss's damage and vice-versa then find out how many turns each takes to win.
5+
use crate::util::iter::*;
6+
use crate::util::parse::*;
7+
use std::ops::Add;
8+
9+
#[derive(Clone, Copy)]
10+
struct Item {
11+
cost: i32,
12+
damage: i32,
13+
armor: i32,
14+
}
15+
16+
impl Add for Item {
17+
type Output = Self;
18+
19+
fn add(self, rhs: Self) -> Self {
20+
Item {
21+
cost: self.cost + rhs.cost,
22+
damage: self.damage + rhs.damage,
23+
armor: self.armor + rhs.armor,
24+
}
25+
}
26+
}
27+
28+
type Result = (bool, i32);
29+
30+
pub fn parse(input: &str) -> Vec<Result> {
31+
let [boss_health, boss_damage, boss_armor]: [i32; 3] =
32+
input.iter_signed().chunk::<3>().next().unwrap();
33+
34+
let weapon = [
35+
Item { cost: 8, damage: 4, armor: 0 },
36+
Item { cost: 10, damage: 5, armor: 0 },
37+
Item { cost: 25, damage: 6, armor: 0 },
38+
Item { cost: 40, damage: 7, armor: 0 },
39+
Item { cost: 74, damage: 8, armor: 0 },
40+
];
41+
42+
let armor = [
43+
Item { cost: 0, damage: 0, armor: 0 },
44+
Item { cost: 13, damage: 0, armor: 1 },
45+
Item { cost: 31, damage: 0, armor: 2 },
46+
Item { cost: 53, damage: 0, armor: 3 },
47+
Item { cost: 75, damage: 0, armor: 4 },
48+
Item { cost: 102, damage: 0, armor: 5 },
49+
];
50+
51+
let ring = [
52+
Item { cost: 25, damage: 1, armor: 0 },
53+
Item { cost: 50, damage: 2, armor: 0 },
54+
Item { cost: 100, damage: 3, armor: 0 },
55+
Item { cost: 20, damage: 0, armor: 1 },
56+
Item { cost: 40, damage: 0, armor: 2 },
57+
Item { cost: 80, damage: 0, armor: 3 },
58+
];
59+
60+
let mut combinations = Vec::with_capacity(22);
61+
combinations.push(Item { cost: 0, damage: 0, armor: 0 });
62+
63+
for i in 0..6 {
64+
combinations.push(ring[i]);
65+
for j in (i + 1)..6 {
66+
combinations.push(ring[i] + ring[j]);
67+
}
68+
}
69+
70+
let mut results = Vec::with_capacity(660);
71+
72+
for first in weapon {
73+
for second in armor {
74+
for &third in &combinations {
75+
let Item { cost, damage, armor } = first + second + third;
76+
77+
let hero_turns = boss_health / (damage - boss_armor).max(1);
78+
let boss_turns = 100 / (boss_damage - armor).max(1);
79+
let win = hero_turns <= boss_turns;
80+
81+
results.push((win, cost));
82+
}
83+
}
84+
}
85+
86+
results
87+
}
88+
89+
pub fn part1(input: &[Result]) -> i32 {
90+
*input.iter().filter_map(|(w, c)| w.then_some(c)).min().unwrap()
91+
}
92+
93+
pub fn part2(input: &[Result]) -> i32 {
94+
*input.iter().filter_map(|(w, c)| (!w).then_some(c)).max().unwrap()
95+
}

tests/test.rs

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ mod year2015 {
4949
mod day18_test;
5050
mod day19_test;
5151
mod day20_test;
52+
mod day21_test;
5253
}
5354

5455
mod year2019 {

tests/year2015/day21_test.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#[test]
2+
fn part1_test() {
3+
// No example data
4+
}
5+
6+
#[test]
7+
fn part2_test() {
8+
// No example data
9+
}

0 commit comments

Comments
 (0)