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 {
let map = Map::parse(reader);
let map = Map::<false, 1>::parse(reader);
map.display();
map.crack_password()
}
fn solve_second_puzzle<R: BufRead>(reader: R) -> usize {
todo!()
fn solve_second_puzzle<const CUBE_EDGE_WIDTH: usize, R: BufRead>(reader: R) -> usize {
let map = Map::<true, CUBE_EDGE_WIDTH>::parse(reader);
map.display();
map.crack_password()
}
fn main() {
@ -38,7 +40,7 @@ fn main() {
let file = BufReader::new(File::open(file).expect("Opening file"));
match solve {
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]
fn example_on_first() {
let reader = Cursor::new(include_str!("../input.test"));
assert_eq!(solve_first_puzzle(reader), 152);
assert_eq!(solve_first_puzzle(reader), 6032);
}
#[test]
fn example_on_second() {
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,
West,
}
impl Facing {
fn turn_left(&mut 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 {
match self {
Facing::North => 3,
@ -99,13 +91,13 @@ impl Action {
}
#[derive(Debug)]
pub struct Map {
pub struct Map<const IS_CUBE: bool, const CUBE_EDGE_WIDTH: usize> {
tiles: Vec<Tile>,
width: usize,
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 {
let mut lines: Vec<String> = reader.lines().map(Result::unwrap).collect();
let instructions = lines.pop().expect("Instructions on the last line");
@ -153,28 +145,37 @@ impl Map {
pub fn crack_password(&self) -> usize {
let (mut x, mut y) = self.first_position();
println!("-- ({:>2}, {:>2})", x + 1, y + 1);
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 {
Action::Move(amount) => {
for _step in 0..*amount {
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::South => (x, y + 1),
Facing::West => (x - 1, y),
Facing::West => (if x == 0 { width - 1 } else { x - 1 }, y),
};
let potential_new_position =
self.wrap_position(raw_potential_new_position, facing);
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::Right => facing.turn_right(),
}
}
println!("> {} {} {}", x + 1, y + 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 (x, y) = wrap_array(x, y);
if self[(x, y)] == Tile::Void {
let mut next = (x, y);
loop {
let next = match facing {
Facing::North => wrap_array(x, if y == 0 { height - 1 } else { y - 1 }),
Facing::East => wrap_array(x + 1, y),
Facing::South => wrap_array(x, y + 1),
Facing::West => wrap_array(if x == 0 { self.width - 1 } else { x - 1 }, y),
next = match facing {
Facing::North => {
wrap_array(next.0, if next.1 == 0 { height - 1 } else { next.1 - 1 })
}
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 {
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;
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {