mirror of
https://github.com/Rhelvetican/aoc2024.git
synced 2025-01-11 04:31:42 +00:00
Compare commits
No commits in common. "c38b6b608789f64137b222587a5a67a69c498f49" and "1e68c2ac05a1249a10e3d3db7396cda2f968bd05" have entirely different histories.
c38b6b6087
...
1e68c2ac05
5 changed files with 4 additions and 211 deletions
|
@ -2,7 +2,10 @@ 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;
|
||||||
|
@ -27,7 +30,6 @@ fn main() -> Result<()> {
|
||||||
3 => AocDayThreeSolution,
|
3 => AocDayThreeSolution,
|
||||||
4 => AocDayFourSolution,
|
4 => AocDayFourSolution,
|
||||||
5 => AocDayFiveSolution,
|
5 => AocDayFiveSolution,
|
||||||
6 => AocDaySixSolution,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,109 +1 @@
|
||||||
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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,6 @@
|
||||||
#[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)]
|
||||||
|
|
Loading…
Reference in a new issue