Skip to content

Commit

Permalink
feat: day06 part1
Browse files Browse the repository at this point in the history
  • Loading branch information
0xThemis committed Dec 6, 2024
1 parent d1a9fac commit 4044796
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 162 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
target/
**puzzle1.txt
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

271 changes: 111 additions & 160 deletions day06/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,146 +1,104 @@
use core::panic;
use std::usize;

use aoc_traits::AdventOfCodeDay;

const UP: usize = 0;
const RIGHT: usize = 1;
const DOWN: usize = 2;
const LEFT: usize = 3;
const NO_WALL: usize = usize::MAX;

#[derive(Default, Clone)]
pub struct Guard {
direction: usize,
position_x: usize,
position_y: usize,
#[derive(Clone, Copy)]
enum Field {
Obstacle,
Free,
Over,
}
pub struct Map {
up: Vec<usize>,
right: Vec<usize>,
down: Vec<usize>,
left: Vec<usize>,

guard: Guard,
impl std::fmt::Debug for Field {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Field::Obstacle => write!(f, "#"),
Field::Free => write!(f, "."),
Field::Over => write!(f, "o"),
}
}
}

#[derive(Clone, Debug, Copy)]
enum Direction {
Up,
Right,
Down,
Left,
}

impl Default for Direction {
fn default() -> Self {
Self::Up
}
}

#[derive(Debug, Default, Clone)]
struct Guard {
direction: Direction,
x: usize,
y: usize,
}

impl Guard {
fn new(direction: usize, position_x: usize, position_y: usize) -> Self {
Self {
direction,
position_x,
position_y,
pub fn new() -> Self {
Guard::default()
}

pub fn set_coords(&mut self, x: usize, y: usize) {
self.x = x;
self.y = y;
}
pub fn turn(&mut self) {
let direction = match self.direction {
Direction::Up => Direction::Right,
Direction::Right => Direction::Down,
Direction::Down => Direction::Left,
Direction::Left => Direction::Up,
};
self.direction = direction;
}

pub fn what_next_step(&mut self, map: &[Vec<Field>]) -> Field {
match self.direction {
Direction::Up => map[self.x - 1][self.y],
Direction::Right => map[self.x][self.y + 1],
Direction::Down => map[self.x + 1][self.y],
Direction::Left => map[self.x][self.y - 1],
}
}
pub fn go(&mut self) {
match self.direction {
Direction::Up => self.x -= 1,
Direction::Right => self.y += 1,
Direction::Down => self.x += 1,
Direction::Left => self.y -= 1,
}
}
}

pub struct Map {
map: Vec<Vec<Field>>,
guard: Guard,
}

impl Map {
fn solve_part1(&self) -> usize {
let mut visited = vec![vec![false; self.map[0].len()]; self.map.len()];
visited[self.guard.x][self.guard.y] = true;
let mut moving_guard = self.guard.clone();
let mut visited = vec![vec![false; 10]; 10];
loop {
match moving_guard.direction {
UP => {
println!(
"guard is at {},{} and looks up",
moving_guard.position_x, moving_guard.position_y
);
let max_steps = self.up[moving_guard.position_x];
let moving = max_steps - moving_guard.position_x;
for i in 0..moving {
visited[moving_guard.position_x][moving_guard.position_y - i] = true;
}
moving_guard.direction = RIGHT;
moving_guard.position_y = 9 - max_steps + 1;
println!(
"no she looks right and is at {}, {}",
moving_guard.position_x, moving_guard.position_y
);
}
RIGHT => {
println!(
"guard is at {},{} and looks right",
moving_guard.position_x, moving_guard.position_y
);
let max_steps = self.right[moving_guard.position_y] - 1;
let moving = max_steps - moving_guard.position_x;
for i in 0..moving {
visited[moving_guard.position_x + i][moving_guard.position_y] = true;
println!(
"she visiting {}, {}",
moving_guard.position_x + i,
moving_guard.position_y
);
}
moving_guard.direction = DOWN;
moving_guard.position_x = max_steps;
println!(
"no she looks down and is at {}, {}",
moving_guard.position_x, moving_guard.position_y
);
match moving_guard.what_next_step(&self.map) {
Field::Obstacle => {
visited[moving_guard.x][moving_guard.y] = true;
moving_guard.turn();
}
DOWN => {
println!(
"guard is at {},{} and looks down",
moving_guard.position_x, moving_guard.position_y
);
let mut max_steps = self.down[moving_guard.position_x];
if max_steps == NO_WALL {
break;
}
if max_steps <= moving_guard.position_y {
break;
}
max_steps -= 1;
let moving = max_steps - moving_guard.position_y;
for i in 0..moving {
visited[moving_guard.position_x][moving_guard.position_y + i] = true;
println!(
"she visiting {}, {}",
moving_guard.position_x,
moving_guard.position_y + i
);
}
moving_guard.direction = LEFT;
moving_guard.position_y = max_steps;
println!(
"no she looks left and is at {}, {}",
moving_guard.position_x, moving_guard.position_y
);
}
LEFT => {
println!(
"guard is at {},{} and looks left",
moving_guard.position_x, moving_guard.position_y
);
let mut max_steps = self.left[moving_guard.position_y];
if max_steps == NO_WALL {
panic!()
}
let moving = max_steps - (8 - moving_guard.position_x);
println!("she can go {moving} steps");
let moving = max_steps - moving_guard.position_y;
for i in 0..moving {
visited[moving_guard.position_x][moving_guard.position_y + i] = true;
println!(
"she visiting {}, {}",
moving_guard.position_x,
moving_guard.position_y + i
)
}
println!("max steps would be {max_steps}");
moving_guard.direction = UP;
moving_guard.position_x = 9 - max_steps;
println!(
"no she looks up and is at {}, {}",
moving_guard.position_x, moving_guard.position_y
);
}
_ => unreachable!(),
Field::Free => visited[moving_guard.x][moving_guard.y] = true,
Field::Over => break,
}
println!("======== result ");
moving_guard.go();
}
visited.into_iter().flatten().filter(|x| *x).count()
visited.into_iter().flatten().filter(|x| *x).count() + 1
}
}

Expand All @@ -164,52 +122,45 @@ impl AdventOfCodeDay for Solver {
}
}

fn parse_input(input: &str) -> Map {
let mut up = vec![NO_WALL; 10];
let mut right = vec![NO_WALL; 10];
let mut down = vec![NO_WALL; 10];
let mut left = vec![NO_WALL; 10];
let mut guard = Guard::default();

for (row, line) in input.lines().enumerate() {
for (column, char) in line.chars().enumerate() {
match char {
'#' => {
down[column] = row;
right[row] = column;
}
'^' => guard = Guard::new(UP, column, row),
'>' => guard = Guard::new(RIGHT, column, row),
'v' => guard = Guard::new(DOWN, column, row),
'<' => guard = Guard::new(LEFT, column, row),
'.' => continue,
_ => unreachable!(),
fn parse_line(line: &str, guard: &mut Guard, row: usize) -> Vec<Field> {
let mut current_row = Vec::with_capacity(line.len());
current_row.push(Field::Over);
for (col, char) in line.chars().enumerate() {
match char {
'#' => current_row.push(Field::Obstacle),
'^' => {
current_row.push(Field::Free);
guard.set_coords(row + 1, col + 1);
}
'.' => current_row.push(Field::Free),
_ => unreachable!(),
}
}
for idx in 0..10 {
if down[idx] != NO_WALL {
up[idx] = 9_usize.saturating_sub(down[idx]);
}
if right[idx] != NO_WALL {
left[idx] = 9_usize.saturating_sub(right[idx]);
}
}
Map {
up,
right,
down,
left,
guard,
current_row.push(Field::Over);
current_row
}

fn parse_input(input: &str) -> Map {
let mut map = vec![];
let mut guard = Guard::new();
let mut lines = input.lines();
let first_line = lines.next().unwrap();
let width = first_line.len();
map.push(vec![Field::Over; width]);
map.push(parse_line(first_line, &mut guard, 0));
for (row, line) in input.lines().enumerate() {
map.push(parse_line(line, &mut guard, row));
}
map.push(vec![Field::Over; width]);
Map { guard, map }
}

#[test]
fn day06() {
let root = std::env!("CARGO_MANIFEST_DIR");
let input = std::fs::read_to_string(format!("{root}/inputs/demo1.txt")).unwrap();
let input = std::fs::read_to_string(format!("{root}/inputs/puzzle1.txt")).unwrap();
let parsed = Solver::parse_input(input.trim());

assert_eq!(41, Solver::solve_part1(&parsed));
assert_eq!(6142, Solver::solve_part2(&parsed));
assert_eq!(4973, Solver::solve_part1(&parsed));
//assert_eq!(6142, Solver::solve_part2(&parsed));
}
2 changes: 1 addition & 1 deletion meta/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ day02 = { path = "../day02" }
day03 = { path = "../day03" }
day04 = { path = "../day04" }
day05 = { path = "../day05" }
# day06 = { path = "../day06" }
day06 = { path = "../day06" }
# day07 = { path = "../day07" }
# day08 = { path = "../day08" }
# day09 = { path = "../day09" }
Expand Down
2 changes: 1 addition & 1 deletion meta/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ impl AdventOfCodeSolutions for AoC2024 {

type Day05 = day05::Solver;

type Day06 = ();
type Day06 = day06::Solver;

type Day07 = ();

Expand Down

0 comments on commit 4044796

Please sign in to comment.