Couple of small tweaks and added missing test
This commit is contained in:
parent
b1e04efaf9
commit
21fff6a4e7
|
@ -33,6 +33,10 @@ mod tests {
|
||||||
fn part2_test2() -> Result<()> {
|
fn part2_test2() -> Result<()> {
|
||||||
Day::test(Day::part2, "test-2", 20)
|
Day::test(Day::part2, "test-2", 20)
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn part2_solution() -> Result<()> {
|
||||||
|
Day::test(Day::part2, "input", 995)
|
||||||
|
}
|
||||||
|
|
||||||
// Benchmarks
|
// Benchmarks
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
@ -67,12 +71,11 @@ impl Vec2 {
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
struct Elf {
|
struct Elf {
|
||||||
considering: Vec2,
|
considering: Vec2,
|
||||||
offset: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Elf {
|
impl Elf {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self { considering: Vec2::new(0, 0), offset: 0 }
|
Self { considering: Vec2::new(0, 0) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +83,7 @@ impl Elf {
|
||||||
struct Map {
|
struct Map {
|
||||||
elves: HashMap<Vec2, Elf>,
|
elves: HashMap<Vec2, Elf>,
|
||||||
considered: HashMap<Vec2, usize>,
|
considered: HashMap<Vec2, usize>,
|
||||||
|
offset: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for Map {
|
impl FromStr for Map {
|
||||||
|
@ -99,7 +103,7 @@ impl FromStr for Map {
|
||||||
})
|
})
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
Ok(Self { elves, considered: HashMap::new()})
|
Ok(Self { elves, considered: HashMap::new(), offset: 0})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,22 +116,19 @@ impl Map {
|
||||||
|
|
||||||
let moves = [north, south, west, east];
|
let moves = [north, south, west, east];
|
||||||
|
|
||||||
for (pos, elf) in self.elves.clone() {
|
for pos in self.elves.clone().keys() {
|
||||||
// Default action is to stay in place
|
// Default action is to stay in place
|
||||||
let mut next = pos;
|
let mut next = *pos;
|
||||||
|
|
||||||
if self.need_to_move(&pos) {
|
if self.need_to_move(&pos) {
|
||||||
for m in moves.iter().cycle().skip(elf.offset).take(4) {
|
for m in moves.iter().cycle().skip(self.offset).take(4) {
|
||||||
if !self.occupied(pos.offset(&m.0[0])) && !self.occupied(pos.offset(&m.0[1])) && !self.occupied(pos.offset(&m.0[2])) {
|
if !self.elves.contains_key(&pos.offset(&m.0[0])) && !self.elves.contains_key(&pos.offset(&m.0[1])) && !self.elves.contains_key(&pos.offset(&m.0[2])) {
|
||||||
next = pos.offset(&m.1);
|
next = pos.offset(&m.1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The offset is updated every round for all elves
|
|
||||||
self.elves.get_mut(&pos).unwrap().offset += 1;
|
|
||||||
|
|
||||||
// Set the position that the elf is considering
|
// Set the position that the elf is considering
|
||||||
self.elves.get_mut(&pos).unwrap().considering = next;
|
self.elves.get_mut(&pos).unwrap().considering = next;
|
||||||
|
|
||||||
|
@ -136,11 +137,8 @@ impl Map {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn occupied(&self, pos: Vec2) -> bool {
|
|
||||||
self.elves.contains_key(&pos)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn need_to_move(&self, pos: &Vec2) -> bool {
|
fn need_to_move(&self, pos: &Vec2) -> bool {
|
||||||
|
// Check all the spaces around the elf to determine if we need to move
|
||||||
for y in -1..2 {
|
for y in -1..2 {
|
||||||
for x in -1..2 {
|
for x in -1..2 {
|
||||||
if x == 0 && y == 0 {
|
if x == 0 && y == 0 {
|
||||||
|
@ -157,18 +155,18 @@ impl Map {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_moves(&mut self) -> bool {
|
fn make_moves(&mut self) -> bool {
|
||||||
// New hashmap that is going to contain the updated values
|
|
||||||
let mut elves = HashMap::new();
|
let mut elves = HashMap::new();
|
||||||
|
|
||||||
let mut moved = false;
|
let mut moved = false;
|
||||||
|
|
||||||
for (pos, elf) in &self.elves {
|
for (pos, elf) in &self.elves {
|
||||||
|
// Check if the move is a valid move
|
||||||
if *self.considered.get(&elf.considering).unwrap() == 1 {
|
if *self.considered.get(&elf.considering).unwrap() == 1 {
|
||||||
|
// Check if the position of the elf has actually changed
|
||||||
if elf.considering.x != pos.x || elf.considering.y != pos.y {
|
if elf.considering.x != pos.x || elf.considering.y != pos.y {
|
||||||
moved = true;
|
moved = true;
|
||||||
}
|
}
|
||||||
// If only one elf is considering the new location, insert the elf into the new
|
|
||||||
// HashMap at the new location
|
// Insert the elf with the updated position
|
||||||
elves.insert(elf.considering, *elf);
|
elves.insert(elf.considering, *elf);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise the elf will not move and stay at its old position
|
// Otherwise the elf will not move and stay at its old position
|
||||||
|
@ -176,14 +174,14 @@ impl Map {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the hashmap
|
|
||||||
self.elves = elves;
|
self.elves = elves;
|
||||||
// Clear the map tracking considered moves
|
|
||||||
self.considered.clear();
|
self.considered.clear();
|
||||||
|
self.offset += 1;
|
||||||
|
|
||||||
return moved;
|
return moved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gives the min and max of the smallest rectangle containing all the elves
|
||||||
fn get_size(&self) -> (Vec2, Vec2) {
|
fn get_size(&self) -> (Vec2, Vec2) {
|
||||||
let mut min = Vec2::new(isize::MAX, isize::MAX);
|
let mut min = Vec2::new(isize::MAX, isize::MAX);
|
||||||
let mut max = Vec2::new(0, 0);
|
let mut max = Vec2::new(0, 0);
|
||||||
|
@ -199,25 +197,26 @@ impl Map {
|
||||||
(min, max)
|
(min, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate the amount of empty tiles in the smallest rectangle containing all the elves
|
||||||
fn empty_tiles(&self) -> isize {
|
fn empty_tiles(&self) -> isize {
|
||||||
let (min, max) = self.get_size();
|
let (min, max) = self.get_size();
|
||||||
(max.x - min.x) * (max.y - min.y) - self.elves.len() as isize
|
(max.x - min.x) * (max.y - min.y) - self.elves.len() as isize
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print(&self) {
|
// fn print(&self) {
|
||||||
let (min, max) = self.get_size();
|
// let (min, max) = self.get_size();
|
||||||
for y in min.y..max.y {
|
// for y in min.y..max.y {
|
||||||
for x in min.x..max.x {
|
// for x in min.x..max.x {
|
||||||
if self.elves.contains_key(&Vec2::new(x, y)) {
|
// if self.elves.contains_key(&Vec2::new(x, y)) {
|
||||||
print!("#");
|
// print!("#");
|
||||||
} else {
|
// } else {
|
||||||
print!(".");
|
// print!(".");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
println!("");
|
// println!("");
|
||||||
}
|
// }
|
||||||
println!("");
|
// println!("");
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- Solution --
|
// -- Solution --
|
||||||
|
|
Loading…
Reference in New Issue
Block a user