From cef96d55bef5c3ff85609a509e0db23bf3d45ef8 Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 18 Dec 2018 22:20:03 +0100 Subject: [PATCH] day15 part 2 --- src/main.rs | 4 ++-- src/tasks/day15.rs | 50 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index e1a63f5..6312093 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ fn main() { - aoc_2018::tasks::day15::task1(); - // aoc_2018::tasks::day15::task2(); + // aoc_2018::tasks::day15::task1(); + aoc_2018::tasks::day15::task2(); } diff --git a/src/tasks/day15.rs b/src/tasks/day15.rs index e7180cc..c06f4e2 100644 --- a/src/tasks/day15.rs +++ b/src/tasks/day15.rs @@ -4,17 +4,17 @@ use std::collections::HashSet; use std::collections::VecDeque; use std::fmt::Display; -const ATTACK_POWER: i32 = 3; const HEALTH: i32 = 200; pub fn task1() { 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); let mut round = 0; while game.round() { round += 1; } + println!("{:?}", game.units); println!("Final full round was {}", round); println!( "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::; + 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::() * round as i32 + ); + } + println!("Searching stopped with lowest win {:?}", lowest_win); // 7169 too low +} + #[derive(Clone, PartialEq)] enum Tile { Empty, @@ -101,6 +139,7 @@ struct Warrior { warrior_type: WarriorType, position: Position, health: i32, + attack: i32, } struct Game { @@ -219,8 +258,9 @@ impl Game { { panic!("Distance WTF") } + let attack = self.units[curr].attack; let enemy = &mut self.units[*closest_index]; - enemy.health -= ATTACK_POWER; + enemy.health -= attack; if enemy.health <= 0 { let enemy = self.units.remove(*closest_index); if *closest_index < curr { @@ -234,7 +274,7 @@ impl Game { 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::WarriorType::*; let width = input[0].len(); @@ -255,6 +295,7 @@ impl Game { warrior_type: Elve, position: Position(x, y), health: HEALTH, + attack: elve_attack, }); Empty } @@ -263,6 +304,7 @@ impl Game { warrior_type: Goblin, position: Position(x, y), health: HEALTH, + attack: goblin_attack, }); Empty }