mirror of
https://github.com/Noratrieb/advent-of-code.git
synced 2026-01-14 17:45:02 +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]
|
[profile.release]
|
||||||
debug = 1
|
debug = 1
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = 1
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
helper = { path = "../helper" }
|
helper = { path = "../helper" }
|
||||||
nom = "7.1.3"
|
nom = "7.1.3"
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ helper::define_variants! {
|
||||||
basic => crate::part1;
|
basic => crate::part1;
|
||||||
}
|
}
|
||||||
part2 {
|
part2 {
|
||||||
basic => crate::part2;
|
brute_force => crate::part2, sample_count=2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,6 +27,14 @@ impl Day for Day06 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part1(input: &str) -> u64 {
|
fn part1(input: &str) -> u64 {
|
||||||
|
#[repr(u8)]
|
||||||
|
enum GuardState {
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
|
||||||
let input = input.as_bytes();
|
let input = input.as_bytes();
|
||||||
|
|
||||||
let width = input.iter().position(|&byte| byte == b'\n').unwrap() + 1; // account for newline
|
let width = input.iter().position(|&byte| byte == b'\n').unwrap() + 1; // account for newline
|
||||||
|
|
@ -34,19 +42,25 @@ fn part1(input: &str) -> u64 {
|
||||||
.iter()
|
.iter()
|
||||||
.position(|&byte| byte == b'^' || byte == b'>' || byte == b'<' || byte == b'v')
|
.position(|&byte| byte == b'^' || byte == b'>' || byte == b'<' || byte == b'v')
|
||||||
.unwrap();
|
.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()];
|
let mut reached_tiles = vec![false; input.len()];
|
||||||
reached_tiles[guard_pos] = true;
|
reached_tiles[guard_pos] = true;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let new_pos = match guard_state {
|
let new_pos = match guard_state {
|
||||||
b'^' => guard_pos.checked_sub(width),
|
GuardState::Up => guard_pos.checked_sub(width),
|
||||||
b'v' => guard_pos.checked_add(width),
|
GuardState::Down => guard_pos.checked_add(width),
|
||||||
b'<' => guard_pos.checked_sub(1),
|
GuardState::Left => guard_pos.checked_sub(1),
|
||||||
b'>' => guard_pos.checked_add(1),
|
GuardState::Right => guard_pos.checked_add(1),
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match new_pos {
|
match new_pos {
|
||||||
None => {
|
None => {
|
||||||
break;
|
break;
|
||||||
|
|
@ -60,11 +74,10 @@ fn part1(input: &str) -> u64 {
|
||||||
Some(new_pos) => {
|
Some(new_pos) => {
|
||||||
if input[new_pos] == b'#' {
|
if input[new_pos] == b'#' {
|
||||||
guard_state = match guard_state {
|
guard_state = match guard_state {
|
||||||
b'^' => b'>',
|
GuardState::Up => GuardState::Right,
|
||||||
b'v' => b'<',
|
GuardState::Down => GuardState::Left,
|
||||||
b'<' => b'^',
|
GuardState::Left => GuardState::Up,
|
||||||
b'>' => b'v',
|
GuardState::Right => GuardState::Down,
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reached_tiles[new_pos] = true;
|
reached_tiles[new_pos] = true;
|
||||||
|
|
@ -77,8 +90,94 @@ fn part1(input: &str) -> u64 {
|
||||||
reached_tiles.iter().filter(|reached| **reached).count() as u64
|
reached_tiles.iter().filter(|reached| **reached).count() as u64
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part2(_input: &str) -> u64 {
|
fn part2(input: &str) -> u64 {
|
||||||
0
|
#[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! {
|
helper::tests! {
|
||||||
|
|
@ -88,8 +187,8 @@ helper::tests! {
|
||||||
default => 4454;
|
default => 4454;
|
||||||
}
|
}
|
||||||
part2 {
|
part2 {
|
||||||
small => 0;
|
small => 6;
|
||||||
default => 0;
|
default => 1503;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
helper::benchmarks! {}
|
helper::benchmarks! {}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue