Work on day22

This commit is contained in:
Malte Tammena 2022-12-23 23:22:26 +01:00
parent 7a214d2591
commit 592da7e185
2 changed files with 42 additions and 27 deletions

View file

@ -15,13 +15,15 @@ enum SolvePuzzle {
} }
fn solve_first_puzzle<R: BufRead>(reader: R) -> usize { fn solve_first_puzzle<R: BufRead>(reader: R) -> usize {
let map = Map::parse(reader); let map = Map::<false, 1>::parse(reader);
map.display(); map.display();
map.crack_password() map.crack_password()
} }
fn solve_second_puzzle<R: BufRead>(reader: R) -> usize { fn solve_second_puzzle<const CUBE_EDGE_WIDTH: usize, R: BufRead>(reader: R) -> usize {
todo!() let map = Map::<true, CUBE_EDGE_WIDTH>::parse(reader);
map.display();
map.crack_password()
} }
fn main() { fn main() {
@ -38,7 +40,7 @@ fn main() {
let file = BufReader::new(File::open(file).expect("Opening file")); let file = BufReader::new(File::open(file).expect("Opening file"));
match solve { match solve {
SolvePuzzle::First => println!("{}", solve_first_puzzle(file)), SolvePuzzle::First => println!("{}", solve_first_puzzle(file)),
SolvePuzzle::Second => println!("{}", solve_second_puzzle(file)), SolvePuzzle::Second => println!("{}", solve_second_puzzle::<50, _>(file)),
}; };
} }
@ -51,12 +53,12 @@ mod tests {
#[test] #[test]
fn example_on_first() { fn example_on_first() {
let reader = Cursor::new(include_str!("../input.test")); let reader = Cursor::new(include_str!("../input.test"));
assert_eq!(solve_first_puzzle(reader), 152); assert_eq!(solve_first_puzzle(reader), 6032);
} }
#[test] #[test]
fn example_on_second() { fn example_on_second() {
let reader = Cursor::new(include_str!("../input.test")); let reader = Cursor::new(include_str!("../input.test"));
assert_eq!(solve_second_puzzle(reader), 301); assert_eq!(solve_second_puzzle::<4, _>(reader), 5031);
} }
} }

View file

@ -7,6 +7,7 @@ pub enum Facing {
South, South,
West, West,
} }
impl Facing { impl Facing {
fn turn_left(&mut self) { fn turn_left(&mut self) {
*self = match self { *self = match self {
@ -26,15 +27,6 @@ impl Facing {
} }
} }
fn opposite(&self) -> Self {
match self {
Facing::North => Facing::South,
Facing::East => Facing::West,
Facing::South => Facing::North,
Facing::West => Facing::East,
}
}
fn to_number(&self) -> usize { fn to_number(&self) -> usize {
match self { match self {
Facing::North => 3, Facing::North => 3,
@ -99,13 +91,13 @@ impl Action {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Map { pub struct Map<const IS_CUBE: bool, const CUBE_EDGE_WIDTH: usize> {
tiles: Vec<Tile>, tiles: Vec<Tile>,
width: usize, width: usize,
actions: Vec<Action>, actions: Vec<Action>,
} }
impl Map { impl<const IS_CUBE: bool, const CUBE_EDGE_WIDTH: usize> Map<IS_CUBE, CUBE_EDGE_WIDTH> {
pub fn parse<R: BufRead>(reader: R) -> Self { pub fn parse<R: BufRead>(reader: R) -> Self {
let mut lines: Vec<String> = reader.lines().map(Result::unwrap).collect(); let mut lines: Vec<String> = reader.lines().map(Result::unwrap).collect();
let instructions = lines.pop().expect("Instructions on the last line"); let instructions = lines.pop().expect("Instructions on the last line");
@ -153,28 +145,37 @@ impl Map {
pub fn crack_password(&self) -> usize { pub fn crack_password(&self) -> usize {
let (mut x, mut y) = self.first_position(); let (mut x, mut y) = self.first_position();
println!("-- ({:>2}, {:>2})", x + 1, y + 1);
let mut facing = Facing::East; let mut facing = Facing::East;
'label: for action in &self.actions { let width = self.width;
let height = self.tiles.len() / self.width;
for action in &self.actions {
println!("DIR : {facing:?}");
println!("ACTION: {action:?}");
match action { match action {
Action::Move(amount) => { Action::Move(amount) => {
for _step in 0..*amount { for _step in 0..*amount {
let raw_potential_new_position = match facing { let raw_potential_new_position = match facing {
Facing::North => (x, y - 1), Facing::North => (x, if y == 0 { height - 1 } else { y - 1 }),
Facing::East => (x + 1, y), Facing::East => (x + 1, y),
Facing::South => (x, y + 1), Facing::South => (x, y + 1),
Facing::West => (x - 1, y), Facing::West => (if x == 0 { width - 1 } else { x - 1 }, y),
}; };
let potential_new_position = let potential_new_position =
self.wrap_position(raw_potential_new_position, facing); self.wrap_position(raw_potential_new_position, facing);
if self[potential_new_position] == Tile::Solid { if self[potential_new_position] == Tile::Solid {
break 'label; break;
} }
x = potential_new_position.0;
y = potential_new_position.1;
println!("-> ({:>2}, {:>2})", x + 1, y + 1);
} }
} }
Action::Left => facing.turn_left(), Action::Left => facing.turn_left(),
Action::Right => facing.turn_right(), Action::Right => facing.turn_right(),
} }
} }
println!("> {} {} {}", x + 1, y + 1, facing.to_number());
1000 * (y + 1) + 4 * (x + 1) + facing.to_number() 1000 * (y + 1) + 4 * (x + 1) + facing.to_number()
} }
@ -192,12 +193,22 @@ impl Map {
let wrap_array = |x: usize, y: usize| (x % self.width, y % height); let wrap_array = |x: usize, y: usize| (x % self.width, y % height);
let (x, y) = wrap_array(x, y); let (x, y) = wrap_array(x, y);
if self[(x, y)] == Tile::Void { if self[(x, y)] == Tile::Void {
let mut next = (x, y);
loop { loop {
let next = match facing { next = match facing {
Facing::North => wrap_array(x, if y == 0 { height - 1 } else { y - 1 }), Facing::North => {
Facing::East => wrap_array(x + 1, y), wrap_array(next.0, if next.1 == 0 { height - 1 } else { next.1 - 1 })
Facing::South => wrap_array(x, y + 1), }
Facing::West => wrap_array(if x == 0 { self.width - 1 } else { x - 1 }, y), Facing::East => wrap_array(next.0 + 1, next.1),
Facing::South => wrap_array(next.0, next.1 + 1),
Facing::West => wrap_array(
if next.0 == 0 {
self.width - 1
} else {
next.0 - 1
},
next.1,
),
}; };
if self[next] != Tile::Void { if self[next] != Tile::Void {
break next; break next;
@ -209,7 +220,9 @@ impl Map {
} }
} }
impl Index<(usize, usize)> for Map { impl<const IS_CUBE: bool, const CUBE_EDGE_WIDTH: usize> Index<(usize, usize)>
for Map<IS_CUBE, CUBE_EDGE_WIDTH>
{
type Output = Tile; type Output = Tile;
fn index(&self, (x, y): (usize, usize)) -> &Self::Output { fn index(&self, (x, y): (usize, usize)) -> &Self::Output {