day15 part 2

This commit is contained in:
Johannes
2018-12-18 22:20:03 +01:00
parent 3f2ff6e5a2
commit cef96d55be
2 changed files with 48 additions and 6 deletions

View File

@@ -1,4 +1,4 @@
fn main() { fn main() {
aoc_2018::tasks::day15::task1(); // aoc_2018::tasks::day15::task1();
// aoc_2018::tasks::day15::task2(); aoc_2018::tasks::day15::task2();
} }

View File

@@ -4,17 +4,17 @@ use std::collections::HashSet;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::fmt::Display; use std::fmt::Display;
const ATTACK_POWER: i32 = 3;
const HEALTH: i32 = 200; const HEALTH: i32 = 200;
pub fn task1() { pub fn task1() {
let input = utils::read_file("input/day15.txt"); let input = utils::read_file("input/day15.txt");
let mut game = Game::from_input(input.lines().collect()); let mut game = Game::from_input(input.lines().collect(), 3, 8);
println!("{}", game); println!("{}", game);
let mut round = 0; let mut round = 0;
while game.round() { while game.round() {
round += 1; round += 1;
} }
println!("{:?}", game.units);
println!("Final full round was {}", round); println!("Final full round was {}", round);
println!( println!(
"Result: {}", "Result: {}",
@@ -22,6 +22,44 @@ pub fn task1() {
); );
} }
pub fn task2() {
let input = utils::read_file("input/day15.txt");
let mut highest_fail = 3;
let mut lowest_win = None::<i32>;
while lowest_win.is_none() || lowest_win.unwrap() - 1 > highest_fail {
let attack = match lowest_win {
Some(upper) => highest_fail + (upper - highest_fail) / 2,
None => 2 * highest_fail,
};
let mut game = Game::from_input(input.lines().collect(), 3, attack);
let initial_elve_count = game
.units
.iter()
.filter(|unit| unit.warrior_type == WarriorType::Elve)
.count();
let mut round = 0;
while game.round() {
round += 1;
}
if game
.units
.iter()
.filter(|unit| unit.warrior_type == WarriorType::Elve)
.count()
== initial_elve_count
{
lowest_win = Some(attack);
} else {
highest_fail = attack;
}
println!(
"Result: {}",
game.units.iter().map(|it| it.health).sum::<i32>() * round as i32
);
}
println!("Searching stopped with lowest win {:?}", lowest_win); // 7169 too low
}
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
enum Tile { enum Tile {
Empty, Empty,
@@ -101,6 +139,7 @@ struct Warrior {
warrior_type: WarriorType, warrior_type: WarriorType,
position: Position, position: Position,
health: i32, health: i32,
attack: i32,
} }
struct Game { struct Game {
@@ -219,8 +258,9 @@ impl Game {
{ {
panic!("Distance WTF") panic!("Distance WTF")
} }
let attack = self.units[curr].attack;
let enemy = &mut self.units[*closest_index]; let enemy = &mut self.units[*closest_index];
enemy.health -= ATTACK_POWER; enemy.health -= attack;
if enemy.health <= 0 { if enemy.health <= 0 {
let enemy = self.units.remove(*closest_index); let enemy = self.units.remove(*closest_index);
if *closest_index < curr { if *closest_index < curr {
@@ -234,7 +274,7 @@ impl Game {
return true; return true;
} }
fn from_input(input: Vec<&str>) -> Self { fn from_input(input: Vec<&str>, goblin_attack: i32, elve_attack: i32) -> Self {
use self::Tile::*; use self::Tile::*;
use self::WarriorType::*; use self::WarriorType::*;
let width = input[0].len(); let width = input[0].len();
@@ -255,6 +295,7 @@ impl Game {
warrior_type: Elve, warrior_type: Elve,
position: Position(x, y), position: Position(x, y),
health: HEALTH, health: HEALTH,
attack: elve_attack,
}); });
Empty Empty
} }
@@ -263,6 +304,7 @@ impl Game {
warrior_type: Goblin, warrior_type: Goblin,
position: Position(x, y), position: Position(x, y),
health: HEALTH, health: HEALTH,
attack: goblin_attack,
}); });
Empty Empty
} }