solution: day 4

This commit is contained in:
YK 2024-12-04 20:08:17 +03:00
parent 49650c8a28
commit 3a9a75558b
2 changed files with 119 additions and 1 deletions

View File

@ -1,7 +1,7 @@
pub mod d1;
pub mod d2;
pub mod d3;
// pub mod d4;
pub mod d4;
// pub mod d5;
// pub mod d6;
// pub mod d7;

118
src/days/d4.rs Normal file
View File

@ -0,0 +1,118 @@
#![allow(non_upper_case_globals)]
use crate::prelude::*;
pub type I = Vec<Vec<char>>;
pub type O = usize;
fn _parse (data: &str) -> I {
data.lines().map(|line| line.chars().collect()).collect()
}
fn _raycast ((y, x): (usize, usize), rows: usize, cols: usize) -> Vec<Vec<(usize, usize)>> {
const r: [[(isize, isize); 3]; 8] = [
[(-1, -1), (-2, -2), (-3, -3)], // UL
[(-1, 0), (-2, 0), (-3, 0)], // U
[(-1, 1), (-2, 2), (-3, 3)], // UR
[(0, -1), (0, -2), (0, -3)], // L
[(0, 1), (0, 2), (0, 3)], // R
[(1, -1), (2, -2), (3, -3)], // DL
[(1, 0), (2, 0), (3, 0)], // D
[(1, 1), (2, 2), (3, 3)], // DR
];
r.into_iter().filter_map(|e| {
let new = e.into_iter().filter_map(|(dy, dx)| {
let ny = y.checked_add_signed(dy)?;
let nx = x.checked_add_signed(dx)?;
if ny >= rows || nx >= cols { return None; }
Some((ny, nx))
}).collect_vec();
if new.len() != 3 { return None }
Some(new)
}).collect()
}
fn _raycast_2 ((y, x): (usize, usize), rows: usize, cols: usize) -> Vec<(usize, usize)> {
const r: [(isize, isize); 4] = [
(-1, -1), // UL
(-1, 1), // UR
(1, -1), // DL
(1, 1), // DR
];
let v: Vec<(usize, usize)> = r.into_iter().filter_map(|(dy, dx)| {
let ny = y.checked_add_signed(dy)?;
let nx = x.checked_add_signed(dx)?;
if ny >= rows || nx >= cols { return None; }
Some((ny, nx))
}).collect();
if v.len() != r.len() { vec![] } else { v }
}
fn _silver (data: I) -> O {
let rows = data.len();
let mut count = 0;
for (y, row) in data.iter().enumerate() {
let cols = row.len();
for (x, &cell) in row.iter().enumerate() {
if cell == 'X' {
count += _raycast((y, x), rows, cols).into_iter().map(|e| format!("X{}", e.iter().map(|&(y, x)| data[y][x]).collect::<String>())).filter(|s| s == "XMAS").count();
}
}
}
count
}
fn _gold (data: I) -> O {
let rows = data.len();
let mut count = 0;
for (y, row) in data.iter().enumerate() {
let cols = row.len();
for (x, &cell) in row.iter().enumerate() {
if cell == 'A' {
let rays = _raycast_2((y, x), rows, cols).into_iter().map(|(y, x)| (data[y][x], (y, x))).collect_vec();
let ms = rays.iter().filter(|(c, _)| *c == 'M').collect_vec();
if ms.len() == 2 &&
rays.iter().filter(|(c, _)| *c == 'S').count() == 2 &&
(ms[0].1.0 == ms[1].1.0 || ms[0].1.1 == ms[1].1.1) {
count += 1;
}
}
}
}
count
}
#[cfg(test)]
mod test {
use super::*;
fn read () -> I {
let data = inc!(4);
_parse(data)
}
#[test]
fn silver () {
let data = read();
let ans = _silver(data);
assert_eq!(ans, 2603)
}
#[test]
fn gold () {
let data = read();
let ans = _gold(data);
assert_eq!(ans, 1965)
}
}