Skip to content

Commit

Permalink
d4p1 solution (not working)
Browse files Browse the repository at this point in the history
  • Loading branch information
SOF3 committed Dec 7, 2024
1 parent 9bcbf9f commit 9475ba2
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 8 deletions.
10 changes: 10 additions & 0 deletions input/d4.sample.input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX
5 changes: 5 additions & 0 deletions src/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,9 @@ main! {
"jq" => jq!("d3.jq", "d3q2"),
}
}
day 4 {
part 1 {
"brute" => d4::p1_brute,
}
}
}
12 changes: 5 additions & 7 deletions src/all/d2.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::fmt;
use std::{cmp, fmt};

use itertools::Itertools;

Expand Down Expand Up @@ -92,12 +92,10 @@ pub fn p2_vec(input: Input) -> impl fmt::Display {
line.0.iter().tuple_windows().map(|(&left, &right)| compare(left, right)).collect();

let increase_count = directions.iter().filter(|&&d| d == Direction::Increase).count();
let dominants = if increase_count * 2 > directions.len() {
&[Direction::Increase][..]
} else if increase_count * 2 == directions.len() {
&[Direction::Increase, Direction::Decrease][..]
} else {
&[Direction::Decrease][..]
let dominants = match (increase_count * 2).cmp(&directions.len()) {
cmp::Ordering::Greater => &[Direction::Increase][..],
cmp::Ordering::Equal => &[Direction::Increase, Direction::Decrease][..],
cmp::Ordering::Less => &[Direction::Decrease][..],
};

dominants.iter().any(|&dominant| {
Expand Down
2 changes: 1 addition & 1 deletion src/all/d3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ fn strip_prefix_str_mut(input: &mut &str, prefix: &str) -> bool {

fn parse_int(input: &mut &str) -> Option<Sum> {
let bytes = input.as_bytes();
if bytes.get(0).is_some_and(u8::is_ascii_digit) {
if bytes.first().is_some_and(u8::is_ascii_digit) {
let value = Sum::from(bytes[0] - b'0');
if bytes.get(1).is_some_and(u8::is_ascii_digit) {
let value = value * 10 + Sum::from(bytes[1] - b'0');
Expand Down
23 changes: 23 additions & 0 deletions src/all/d4.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std::array;

use crate::util::{DirectDiagonal, GridView};

pub fn p1_brute(input: String) -> u32 {
let grid = GridView::new(&input);

let mut count = 0;

for (index, _) in input.match_indices('X') {
let loc = grid.index_to_loc(index).unwrap();
for dir in DirectDiagonal::ALL {
let mut iter = loc.direct_diagonal_iter(dir, grid).skip(1).take(3).map(|loc| grid.get(loc));
let chars: [_; 3] = array::from_fn(|_| iter.next().flatten());
if chars == [Some(b'M'), Some(b'A'), Some(b'S')] {
println!("Match: {dir:?} {loc:?}");
count += 1;
}
}
}

count
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod all;
use all::Parse;
pub use all::{bench, run};

mod util;
146 changes: 146 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#![allow(dead_code)]

use std::iter;

#[derive(Clone, Copy)]
pub struct GridView<'a> {
input: &'a [u8],
width: u32,
height: u32,
}

impl<'a> GridView<'a> {
pub fn new(input: &'a impl AsRef<[u8]>) -> Self {
let input = input.as_ref();
let width= input.iter().position(|&b| b == b'\n').unwrap() as u32+1;
Self {
input,
width,
height: (input.len() as u32).div_ceil(width),
}
}

pub fn get(&self, loc: GridLoc) -> Option<u8> {
self.input.get((loc.y * self.width + loc.x) as usize).copied()
}

pub fn index_to_loc(&self, index: usize) -> Option<GridLoc> {
let y = index as u32 / self.width;
let x = index as u32 % self.width;
if x < self.width - 1 && y < self.height {
Some(GridLoc { x, y })
} else {
None
}
}
}

#[derive(Debug, Clone, Copy)]
pub struct GridLoc {
x: u32,
y: u32,
}

impl GridLoc {
pub fn left(self) -> Option<Self> {
Some(Self {
x: self.x.checked_sub(1)?,
y: self.y,
})
}
pub fn right(self, grid: GridView) -> Option<Self> {
Some(Self {
x: match self.x.checked_add(1)? {
x if x < grid.width - 1 => x,
_ => return None,
},
y: self.y,
})
}
pub fn up(self) -> Option<Self> {
Some(Self {
x: self.x,
y: self.y.checked_sub(1)?,
})
}
pub fn down(self, grid: GridView) -> Option<Self> {
Some(Self {
x: self.x,
y: match self.y.checked_add(1)? {
y if y < grid.height - 1 => y,
_ => return None,
},
})
}

pub fn direct(self, direct: Direct, grid: GridView) -> Option<Self> {
match direct {
Direct::Left => self.left(),
Direct::Right => self.right(grid),
Direct::Up => self.up(),
Direct::Down => self.down(grid),
}
}

pub fn direct_diagonal(self, direct: DirectDiagonal, grid: GridView) -> Option<Self> {
match direct {
DirectDiagonal::Left => self.left(),
DirectDiagonal::Right => self.right(grid),
DirectDiagonal::Up => self.up(),
DirectDiagonal::Down => self.down(grid),
DirectDiagonal::LeftUp => self.left().and_then(Self::up),
DirectDiagonal::RightUp => self.right(grid).and_then(Self::up),
DirectDiagonal::LeftDown => self.left().and_then(|loc| loc.down(grid)),
DirectDiagonal::RightDown => self.right(grid).and_then(|loc| loc.down(grid)),
}
}

fn direct_any_iter<F>(self, mutate: F, grid: GridView) -> impl Iterator<Item = Self> + use<'_, F>
where F: Fn(GridLoc, GridView) -> Option<GridLoc>{
let mut loc = Some(self);
iter::from_fn(move || {
let output = loc?;
loc = mutate(output, grid);
Some(output)
})
}

pub fn direct_iter(self, direct: Direct, grid: GridView) -> impl Iterator<Item = Self> + use<'_> {
self.direct_any_iter(move |loc, grid| loc.direct(direct, grid), grid)
}

pub fn direct_diagonal_iter(self, direct: DirectDiagonal, grid: GridView) -> impl Iterator<Item = Self> + use<'_> {
self.direct_any_iter(move |loc, grid| loc.direct_diagonal(direct, grid), grid)
}
}

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

impl Direct {
pub const ALL: [Self; 4] = [Self::Left, Self::Right, Self::Up, Self::Down];
}

#[derive(Debug, Clone, Copy)]
pub enum DirectDiagonal {
Left,
Right,
Up,
Down,
LeftUp,
RightUp,
LeftDown,
RightDown,
}

impl DirectDiagonal {
pub const ALL: [Self; 8] = [
Self::Left, Self::Right, Self::Up, Self::Down,
Self::LeftUp, Self::RightUp, Self::LeftDown, Self::RightDown,
];
}

0 comments on commit 9475ba2

Please sign in to comment.