day15 part 2 optimized
instead of senselessly trying to find the best starting point, just rely on the order of neighbor point generation. Since we use a queue to manage open points and he neighbors are added in the correct order, they neighbor that has precedence due to reading order will automatically be the one to be predecessor on a final path, if he is on a shortest path.
This commit is contained in:
@@ -8,13 +8,14 @@ const HEALTH: i32 = 200;
|
||||
|
||||
pub fn task1() {
|
||||
let input = utils::read_file("input/day15.txt");
|
||||
let mut game = Game::from_input(input.lines().collect(), 3, 8);
|
||||
let mut game = Game::from_input(&input.lines().collect(), 3, 3);
|
||||
println!("{}", game);
|
||||
let mut round = 0;
|
||||
while game.round() {
|
||||
round += 1;
|
||||
// println!("{}", game);
|
||||
// println!("round was {}", round);
|
||||
}
|
||||
println!("{:?}", game.units);
|
||||
println!("Final full round was {}", round);
|
||||
println!(
|
||||
"Result: {}",
|
||||
@@ -24,6 +25,7 @@ pub fn task1() {
|
||||
|
||||
pub fn task2() {
|
||||
let input = utils::read_file("input/day15.txt");
|
||||
let input = input.lines().collect();
|
||||
let mut highest_fail = 3;
|
||||
let mut lowest_win = None::<i32>;
|
||||
while lowest_win.is_none() || lowest_win.unwrap() - 1 > highest_fail {
|
||||
@@ -31,7 +33,7 @@ pub fn task2() {
|
||||
Some(upper) => highest_fail + (upper - highest_fail) / 2,
|
||||
None => 2 * highest_fail,
|
||||
};
|
||||
let mut game = Game::from_input(input.lines().collect(), 3, attack);
|
||||
let mut game = Game::from_input(&input, 3, attack);
|
||||
let initial_elve_count = game
|
||||
.units
|
||||
.iter()
|
||||
@@ -175,25 +177,32 @@ impl Game {
|
||||
if from == to {
|
||||
return Some(from);
|
||||
}
|
||||
let input = vec![
|
||||
(1, Position(from.0, from.1 - 1)),
|
||||
(2, Position(from.0 - 1, from.1)),
|
||||
(3, Position(from.0 + 1, from.1)),
|
||||
(4, Position(from.0, from.1 + 1)),
|
||||
];
|
||||
if let Some((_, best)) = input
|
||||
.iter()
|
||||
.filter_map(|(delta, start)| {
|
||||
// let input = vec![
|
||||
// (1, Position(from.0, from.1 - 1)),
|
||||
// (2, Position(from.0 - 1, from.1)),
|
||||
// (3, Position(from.0 + 1, from.1)),
|
||||
// (4, Position(from.0, from.1 + 1)),
|
||||
// ];
|
||||
// if let Some((_, best)) = input
|
||||
// .iter()
|
||||
// .filter_map(|(delta, start)| {
|
||||
// let map = Map::from_game(&self, from);
|
||||
// if let Some(path) = map.shortest_path(*start, to) {
|
||||
// Some((delta + path.len() * 10, *path.first().unwrap_or(start)))
|
||||
// } else {
|
||||
// None
|
||||
// }
|
||||
// })
|
||||
// .min_by_key(|(d, _)| *d)
|
||||
// {
|
||||
// Some(best)
|
||||
// } else {
|
||||
// None
|
||||
// }
|
||||
let map = Map::from_game(&self, from);
|
||||
if let Some(path) = map.shortest_path(*start, to) {
|
||||
Some((delta + path.len() * 10, *path.first().unwrap_or(start)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.min_by_key(|(d, _)| *d)
|
||||
{
|
||||
Some(best)
|
||||
if let Some(path) = map.shortest_path(from, to) {
|
||||
// println!("{:?}", path);
|
||||
Some(*path.get(1).unwrap_or(&from))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -224,6 +233,10 @@ impl Game {
|
||||
if let Some(next_position) =
|
||||
self.next_position(self.units[curr].position, next_target_position)
|
||||
{
|
||||
// println!(
|
||||
// "{:?} moves to {:?} via {:?}",
|
||||
// self.units[curr].position, next_target_position, next_position
|
||||
// );
|
||||
self.units[curr].position = next_position;
|
||||
} else {
|
||||
panic!("We have a reachable target but no path to it! {:?} wants to go to {:?}", self.units[curr], next_target_position);
|
||||
@@ -274,7 +287,7 @@ impl Game {
|
||||
return true;
|
||||
}
|
||||
|
||||
fn from_input(input: Vec<&str>, goblin_attack: i32, elve_attack: i32) -> 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();
|
||||
@@ -433,6 +446,7 @@ impl Map {
|
||||
if let Some(Some(_)) = predecessors.get(&to) {
|
||||
let mut result: Vec<Position> = Vec::new();
|
||||
let mut current = to;
|
||||
result.push(current);
|
||||
while let Some(Some(predecessor)) = predecessors.get(¤t) {
|
||||
result.push(*predecessor);
|
||||
current = *predecessor;
|
||||
|
||||
Reference in New Issue
Block a user