solution: day 4
This commit is contained in:
parent
49650c8a28
commit
3a9a75558b
@ -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
118
src/days/d4.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user