summaryrefslogtreecommitdiff
path: root/2024_rust/src
diff options
context:
space:
mode:
authorGuillermo Ramos2024-12-04 16:37:39 +0100
committerGuillermo Ramos2024-12-04 17:48:39 +0100
commit127145ac655848edf81c901adf37e569efd0a50e (patch)
tree189ef835d123adc8905be13de3c80907efdf4ad1 /2024_rust/src
parent47282e65005c204344a9473adc319185606d4c65 (diff)
downloadAoC-127145ac655848edf81c901adf37e569efd0a50e.tar.gz
2024.4
Diffstat (limited to '2024_rust/src')
-rw-r--r--2024_rust/src/day4.rs134
-rw-r--r--2024_rust/src/main.rs6
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();