diff options
author | Guillermo Ramos | 2024-12-04 16:37:39 +0100 |
---|---|---|
committer | Guillermo Ramos | 2024-12-04 17:48:39 +0100 |
commit | 127145ac655848edf81c901adf37e569efd0a50e (patch) | |
tree | 189ef835d123adc8905be13de3c80907efdf4ad1 /2024_rust/src | |
parent | 47282e65005c204344a9473adc319185606d4c65 (diff) | |
download | AoC-127145ac655848edf81c901adf37e569efd0a50e.tar.gz |
2024.4
Diffstat (limited to '2024_rust/src')
-rw-r--r-- | 2024_rust/src/day4.rs | 134 | ||||
-rw-r--r-- | 2024_rust/src/main.rs | 6 |
2 files changed, 137 insertions, 3 deletions
diff --git a/2024_rust/src/day4.rs b/2024_rust/src/day4.rs new file mode 100644 index 0000000..1ebe67b --- /dev/null +++ b/2024_rust/src/day4.rs @@ -0,0 +1,134 @@ +const XMAS: &str = "XMAS"; +const MAS: &str = "MAS"; + +type Matrix = Vec<Vec<char>>; +type Position = (usize, usize); +type RowXmas = [Position; XMAS.len()]; +type RowMas = [Position; MAS.len()]; + +fn check_xmas<'a, I>(m: &Matrix, it: I) -> bool +where + I: Iterator<Item = &'a Position>, +{ + for (c, (i, j)) in XMAS.chars().zip(it) { + if m[*i][*j] != c { + return false; + } + } + + true +} + +fn offplus(x: usize, y: isize) -> usize { + (x as isize + y) as usize +} + +fn rows_latdiag_from(p: Position, max_x: usize, max_y: usize) -> Vec<RowXmas> { + let mut rs: Vec<RowXmas> = vec![]; + + // Horizontal / vertical / diagonal + for (p0, (di, dj)) in [ + (p, (0, 1)), // horizontal, left-to-right + (p, (1, 0)), // vertical, top-down + (p, (1, 1)), // diag from p, top-down and left-to-right + ((p.0, p.1 + XMAS.len() - 1), (1, -1isize)), // the other diag, top-down and right-to-left + ] { + // Bounds check + let max_off = XMAS.len(); + if p0.0 + di * max_off > max_x + || (dj > 0 && offplus(p0.1, dj * max_off as isize) > max_y) + || p0.1 >= max_y + { + continue; + } + + let mut p_acc = p0; + let mut ps = [(0, 0); XMAS.len()]; + for idx in 0..ps.len() { + ps[idx].0 = p_acc.0; + ps[idx].1 = p_acc.1; + p_acc = (p_acc.0 + di, offplus(p_acc.1, dj)); + } + rs.push(ps); + } + + rs +} + +pub fn p1(input: &str) -> String { + let m: Matrix = input.lines().map(|row| row.chars().collect()).collect(); + let mut result = 0; + + for i in 0..m.len() { + for j in 0..m[i].len() { + let p = (i, j); + for row in rows_latdiag_from(p, m.len(), m[i].len()) { + if check_xmas(&m, row.iter()) || check_xmas(&m, row.iter().rev()) { + result += 1; + } + } + } + } + + result.to_string() +} + +fn check_mas<'a, I>(m: &Matrix, it: I) -> bool +where + I: Iterator<Item = &'a Position>, +{ + for (c, (i, j)) in MAS.chars().zip(it) { + if m[*i][*j] != c { + return false; + } + } + + true +} + +fn rows_diag_from(p: Position, max_x: usize, max_y: usize) -> Vec<RowMas> { + let mut rs: Vec<RowMas> = vec![]; + + // Horizontal / vertical / diagonal + for (p0, (di, dj)) in [ + (p, (1, 1)), // diag from p, top-down and left-to-right + ((p.0, p.1 + MAS.len() - 1), (1, -1isize)), // the other diag, top-down and right-to-left + ] { + // Bounds check + let max_off = MAS.len(); + if p0.0 + di * max_off > max_x + || (dj > 0 && offplus(p0.1, dj * max_off as isize) > max_y) + || p0.1 >= max_y + { + continue; + } + + let mut p_acc = p0; + let mut ps = [(0, 0); MAS.len()]; + for idx in 0..ps.len() { + ps[idx].0 = p_acc.0; + ps[idx].1 = p_acc.1; + p_acc = (p_acc.0 + di, offplus(p_acc.1, dj)); + } + rs.push(ps); + } + + rs +} + +pub fn p2(input: &str) -> String { + let m: Matrix = input.lines().map(|row| row.chars().collect()).collect(); + let mut result = 0; + + for i in 0..=m.len() - MAS.len() { + for j in 0..=m[i].len() - MAS.len() { + let p = (i, j); + let rows = rows_diag_from(p, m.len(), m[i].len()); + if rows.iter().all(|r| check_mas(&m, r.iter()) || check_mas(&m, r.iter().rev())) { + result += 1; + } + } + } + + result.to_string() +} diff --git a/2024_rust/src/main.rs b/2024_rust/src/main.rs index ed94ec2..2cc3786 100644 --- a/2024_rust/src/main.rs +++ b/2024_rust/src/main.rs @@ -1,6 +1,6 @@ -mod day3; -use day3 as current_day; -const INPUT_FILE: &str = "inputs/3"; +mod day4; +use day4 as current_day; +const INPUT_FILE: &str = "inputs/4"; fn main() { let input = std::fs::read_to_string(INPUT_FILE).unwrap(); |