mirror of
https://github.com/Noratrieb/advent-of-code.git
synced 2026-01-14 09:35:01 +01:00
stuff
This commit is contained in:
parent
e9a6c19c2e
commit
bd111795df
2 changed files with 118 additions and 16 deletions
|
|
@ -5,6 +5,9 @@ members = ["day*"]
|
|||
[profile.release]
|
||||
debug = 1
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
|
||||
[workspace.dependencies]
|
||||
helper = { path = "../helper" }
|
||||
nom = "7.1.3"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ helper::define_variants! {
|
|||
basic => crate::part1;
|
||||
}
|
||||
part2 {
|
||||
basic => crate::part2;
|
||||
brute_force => crate::part2, sample_count=2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -27,6 +27,14 @@ impl Day for Day06 {
|
|||
}
|
||||
|
||||
fn part1(input: &str) -> u64 {
|
||||
#[repr(u8)]
|
||||
enum GuardState {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
let input = input.as_bytes();
|
||||
|
||||
let width = input.iter().position(|&byte| byte == b'\n').unwrap() + 1; // account for newline
|
||||
|
|
@ -34,19 +42,25 @@ fn part1(input: &str) -> u64 {
|
|||
.iter()
|
||||
.position(|&byte| byte == b'^' || byte == b'>' || byte == b'<' || byte == b'v')
|
||||
.unwrap();
|
||||
let mut guard_state = input[guard_pos];
|
||||
let mut guard_state = match input[guard_pos] {
|
||||
b'^' => GuardState::Up,
|
||||
b'v' => GuardState::Down,
|
||||
b'<' => GuardState::Left,
|
||||
b'>' => GuardState::Right,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let mut reached_tiles = vec![false; input.len()];
|
||||
reached_tiles[guard_pos] = true;
|
||||
|
||||
loop {
|
||||
let new_pos = match guard_state {
|
||||
b'^' => guard_pos.checked_sub(width),
|
||||
b'v' => guard_pos.checked_add(width),
|
||||
b'<' => guard_pos.checked_sub(1),
|
||||
b'>' => guard_pos.checked_add(1),
|
||||
_ => unreachable!(),
|
||||
GuardState::Up => guard_pos.checked_sub(width),
|
||||
GuardState::Down => guard_pos.checked_add(width),
|
||||
GuardState::Left => guard_pos.checked_sub(1),
|
||||
GuardState::Right => guard_pos.checked_add(1),
|
||||
};
|
||||
|
||||
match new_pos {
|
||||
None => {
|
||||
break;
|
||||
|
|
@ -60,11 +74,10 @@ fn part1(input: &str) -> u64 {
|
|||
Some(new_pos) => {
|
||||
if input[new_pos] == b'#' {
|
||||
guard_state = match guard_state {
|
||||
b'^' => b'>',
|
||||
b'v' => b'<',
|
||||
b'<' => b'^',
|
||||
b'>' => b'v',
|
||||
_ => unreachable!(),
|
||||
GuardState::Up => GuardState::Right,
|
||||
GuardState::Down => GuardState::Left,
|
||||
GuardState::Left => GuardState::Up,
|
||||
GuardState::Right => GuardState::Down,
|
||||
}
|
||||
} else {
|
||||
reached_tiles[new_pos] = true;
|
||||
|
|
@ -77,8 +90,94 @@ fn part1(input: &str) -> u64 {
|
|||
reached_tiles.iter().filter(|reached| **reached).count() as u64
|
||||
}
|
||||
|
||||
fn part2(_input: &str) -> u64 {
|
||||
0
|
||||
fn part2(input: &str) -> u64 {
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
enum GuardState {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
let input = input.as_bytes();
|
||||
|
||||
fn check_if_stuck(input: &[u8], mut guard_pos: usize, width: usize) -> bool {
|
||||
let mut guard_state = match input[guard_pos] {
|
||||
b'^' => GuardState::Up,
|
||||
b'v' => GuardState::Down,
|
||||
b'<' => GuardState::Left,
|
||||
b'>' => GuardState::Right,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let mut reached_tiles = vec![false; input.len() * 4];
|
||||
let idx_reached =
|
||||
|guard_pos: usize, guard_state: GuardState| (guard_pos << 2) | guard_state as usize;
|
||||
|
||||
loop {
|
||||
if reached_tiles[idx_reached(guard_pos, guard_state)] {
|
||||
return true;
|
||||
}
|
||||
reached_tiles[idx_reached(guard_pos, guard_state)] = true;
|
||||
|
||||
let new_pos = match guard_state {
|
||||
GuardState::Up => guard_pos.checked_sub(width),
|
||||
GuardState::Down => guard_pos.checked_add(width),
|
||||
GuardState::Left => guard_pos.checked_sub(1),
|
||||
GuardState::Right => guard_pos.checked_add(1),
|
||||
};
|
||||
match new_pos {
|
||||
None => {
|
||||
break;
|
||||
}
|
||||
Some(new_pos) if input.len() <= new_pos => {
|
||||
break;
|
||||
}
|
||||
Some(new_pos) if input[new_pos] == b'\n' => {
|
||||
break;
|
||||
}
|
||||
Some(new_pos) => {
|
||||
if input[new_pos] == b'#' {
|
||||
guard_state = match guard_state {
|
||||
GuardState::Up => GuardState::Right,
|
||||
GuardState::Down => GuardState::Left,
|
||||
GuardState::Left => GuardState::Up,
|
||||
GuardState::Right => GuardState::Down,
|
||||
};
|
||||
} else {
|
||||
guard_pos = new_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
let initial_guard_pos = input
|
||||
.iter()
|
||||
.position(|&byte| byte == b'^' || byte == b'>' || byte == b'<' || byte == b'v')
|
||||
.unwrap();
|
||||
let width = input.iter().position(|&byte| byte == b'\n').unwrap() + 1; // account for newline
|
||||
|
||||
let mut count = 0;
|
||||
let mut modified_input = input.to_owned();
|
||||
for i in 0..input.len() {
|
||||
if input[i] == b'\n' || input[i] == b'#' || i == initial_guard_pos {
|
||||
continue;
|
||||
}
|
||||
let prev = modified_input[i];
|
||||
|
||||
modified_input[i] = b'#';
|
||||
if check_if_stuck(&modified_input, initial_guard_pos, width) {
|
||||
count += 1;
|
||||
}
|
||||
|
||||
modified_input[i] = prev;
|
||||
}
|
||||
|
||||
count
|
||||
}
|
||||
|
||||
helper::tests! {
|
||||
|
|
@ -88,8 +187,8 @@ helper::tests! {
|
|||
default => 4454;
|
||||
}
|
||||
part2 {
|
||||
small => 0;
|
||||
default => 0;
|
||||
small => 6;
|
||||
default => 1503;
|
||||
}
|
||||
}
|
||||
helper::benchmarks! {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue