This commit is contained in:
Rh4096 2024-12-06 23:23:27 +07:00
parent 1e68c2ac05
commit d5910b8bbd
6 changed files with 17117 additions and 4 deletions

16906
dump.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -2,10 +2,7 @@ use ansi_term::enable_ansi_support;
use aoc2024::{ use aoc2024::{
cli::AocCli, cli::AocCli,
map_solution, map_solution,
solutions::{ solutions::*,
AocDayFiveSolution, AocDayFourSolution, AocDayOneSolution, AocDayThreeSolution,
AocDayTwoSolution, AocSolution,
},
utils::{Error, Result}, utils::{Error, Result},
}; };
use clap::Parser; use clap::Parser;
@ -30,6 +27,7 @@ fn main() -> Result<()> {
3 => AocDayThreeSolution, 3 => AocDayThreeSolution,
4 => AocDayFourSolution, 4 => AocDayFourSolution,
5 => AocDayFiveSolution, 5 => AocDayFiveSolution,
6 => AocDaySixSolution,
}; };
Ok(()) Ok(())

View file

@ -1 +1,109 @@
use std::{
collections::{HashMap, HashSet},
fs::read_to_string,
path::Path,
};
use super::AocSolution;
use crate::utils::{coord::Coord, direction::Direction, Result};
#[derive(Debug, Clone)]
struct Guard {
dir: Direction,
cur: Coord,
grid: HashMap<Coord, bool>,
}
impl Guard {
fn new(src: &str) -> Self {
let (grid, cur) = src
.lines()
.zip(0..)
.flat_map(|(l, y)| {
l.chars()
.zip(0..)
.map(move |(ch, x)| (Coord::new(x, y), ch))
})
.fold(
(HashMap::new(), Coord::new(0, 0)),
|(mut map, coord), (crd, obs)| {
map.insert(crd, obs == '#');
let coord = if obs == '^' { crd } else { coord };
(map, coord)
},
);
Self {
dir: Direction::default(),
cur,
grid,
}
}
fn patrol(&mut self) -> (usize, bool) {
let mut repetition = 0u16;
let mut flag = false;
let mut patrolled = HashSet::new();
loop {
if repetition == 65535 {
flag = true;
break;
}
let lookahead = self.cur + self.dir;
if let Some(&obs) = self.grid.get(&lookahead) {
if obs {
self.dir.turn_right();
} else {
if !patrolled.insert(self.cur) {
repetition += 1;
};
self.cur = lookahead;
}
} else {
break;
}
}
(patrolled.len() + 1, flag)
}
fn loop_prank(&mut self) -> u64 {
let mut total = 0;
for &key in self.grid.keys() {
let mut tmp = self.clone();
if tmp.grid.get(&key).is_some_and(|cond| !*cond) {
tmp.grid.insert(key, true);
if tmp.patrol().1 {
total += 1;
}
};
}
total
}
}
#[derive(Clone, Copy)]
pub struct AocDaySixSolution; pub struct AocDaySixSolution;
impl AocSolution for AocDaySixSolution {
type Output = u64;
fn get_input(&self, path: Option<&Path>) -> Result<String> {
match path {
Some(p) => Ok(read_to_string(p)?),
None => Ok(read_to_string("./input/day_6.txt")?),
}
}
fn part_one(&self, input: &str) -> Result<Self::Output> {
let mut g = Guard::new(input);
Ok(g.patrol().0 as Self::Output)
}
fn part_two(&self, input: &str) -> Result<Self::Output> {
let mut g = Guard::new(input);
Ok(g.loop_prank())
}
}

32
src/utils/coord.rs Normal file
View file

@ -0,0 +1,32 @@
use std::ops::Add;
use super::direction::Direction;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Coord {
pub x: i16,
pub y: i16,
}
impl Coord {
pub fn new(x: i16, y: i16) -> Self {
Self { x, y }
}
}
impl Add for Coord {
type Output = Coord;
fn add(self, rhs: Self) -> Self::Output {
Self::new(self.x + rhs.x, self.y + rhs.y)
}
}
impl Add<Direction> for Coord {
type Output = Coord;
fn add(self, rhs: Direction) -> Self::Output {
let tmp = rhs.lookahead();
self + tmp
}
}

66
src/utils/direction.rs Normal file
View file

@ -0,0 +1,66 @@
use std::ops::{Neg, Not};
use super::coord::Coord;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Direction {
#[default]
Up,
Right,
Left,
Down,
}
impl Direction {
pub fn turn_right(&mut self) {
match self {
Self::Up => *self = Self::Right,
Self::Right => *self = Self::Down,
Self::Down => *self = Self::Left,
Self::Left => *self = Self::Up,
}
}
pub fn turn_left(&mut self) {
match self {
Self::Up => *self = Self::Left,
Self::Left => *self = Self::Down,
Self::Down => *self = Self::Right,
Self::Right => *self = Self::Up,
}
}
pub fn turn_back(&mut self) {
*self = !*self
}
pub fn lookahead(&self) -> Coord {
match self {
Self::Up => Coord::new(0, -1),
Self::Right => Coord::new(1, 0),
Self::Down => Coord::new(0, 1),
Self::Left => Coord::new(-1, 0),
}
}
}
impl Not for Direction {
type Output = Self;
fn not(self) -> Self::Output {
match self {
Self::Up => Self::Down,
Self::Left => Self::Right,
Self::Down => Self::Up,
Self::Right => Self::Left,
}
}
}
impl Neg for Direction {
type Output = Self;
fn neg(self) -> Self::Output {
!self
}
}

View file

@ -1,6 +1,9 @@
#[macro_use] #[macro_use]
pub mod macros; pub mod macros;
pub mod coord;
pub mod direction;
pub type Result<T> = std::result::Result<T, Error>; pub type Result<T> = std::result::Result<T, Error>;
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]