Work on day22
This commit is contained in:
parent
7a214d2591
commit
592da7e185
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue