summaryrefslogtreecommitdiff
path: root/2024/day04.rs
diff options
context:
space:
mode:
authornekineki <nekineki@nekineki.net>2024-12-04 06:41:27 +0100
committernekineki <nekineki@nekineki.net>2024-12-04 06:41:27 +0100
commit69d80309cdf5ae70d3f0f72b3d10704352381a45 (patch)
treec67147cd42280e278417d7e7250dfc9f68a02a35 /2024/day04.rs
parentea583b8c165d9678e75c881e62beb828dac5dd5f (diff)
day04
Diffstat (limited to '2024/day04.rs')
-rw-r--r--2024/day04.rs145
1 files changed, 145 insertions, 0 deletions
diff --git a/2024/day04.rs b/2024/day04.rs
new file mode 100644
index 0000000..f4dc88f
--- /dev/null
+++ b/2024/day04.rs
@@ -0,0 +1,145 @@
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use std::env;
+use std::fs::File;
+use std::io::Read;
+
+fn horizontal(lx: usize, ly: usize, m: &Vec<Vec<char>>) -> usize {
+ let mut count = 0;
+ for y in 0..ly {
+ for x in 0..lx - 3 {
+ if m[y][x] == 'X' && m[y][x + 1] == 'M' && m[y][x + 2] == 'A' && m[y][x + 3] == 'S' {
+ count += 1;
+ }
+ if m[y][x] == 'S' && m[y][x + 1] == 'A' && m[y][x + 2] == 'M' && m[y][x + 3] == 'X' {
+ count += 1;
+ }
+ }
+ }
+ count
+}
+
+fn vertical(lx: usize, ly: usize, m: &Vec<Vec<char>>) -> usize {
+ let mut count = 0;
+ for y in 0..ly - 3 {
+ for x in 0..lx {
+ if m[y][x] == 'X' && m[y + 1][x] == 'M' && m[y + 2][x] == 'A' && m[y + 3][x] == 'S' {
+ count += 1;
+ }
+ if m[y][x] == 'S' && m[y + 1][x] == 'A' && m[y + 2][x] == 'M' && m[y + 3][x] == 'X' {
+ count += 1;
+ }
+ }
+ }
+ count
+}
+
+fn diag1(lx: usize, ly: usize, m: &Vec<Vec<char>>) -> usize {
+ let mut count = 0;
+ for y in 0..ly - 3 {
+ for x in 0..lx - 3 {
+ if m[y][x] == 'X'
+ && m[y + 1][x + 1] == 'M'
+ && m[y + 2][x + 2] == 'A'
+ && m[y + 3][x + 3] == 'S'
+ {
+ count += 1;
+ }
+ if m[y][x] == 'S'
+ && m[y + 1][x + 1] == 'A'
+ && m[y + 2][x + 2] == 'M'
+ && m[y + 3][x + 3] == 'X'
+ {
+ count += 1;
+ }
+ }
+ }
+ count
+}
+fn diag2(lx: usize, ly: usize, m: &Vec<Vec<char>>) -> usize {
+ let mut count = 0;
+ for y in 0..ly - 3 {
+ for x in 0..lx - 3 {
+ if m[y][x + 3] == 'X'
+ && m[y + 1][x + 2] == 'M'
+ && m[y + 2][x + 1] == 'A'
+ && m[y + 3][x] == 'S'
+ {
+ count += 1;
+ }
+ if m[y][x + 3] == 'S'
+ && m[y + 1][x + 2] == 'A'
+ && m[y + 2][x + 1] == 'M'
+ && m[y + 3][x] == 'X'
+ {
+ count += 1;
+ }
+ }
+ }
+ count
+}
+
+fn mas(lx: usize, ly: usize, m: &Vec<Vec<char>>) -> usize {
+ let mut count = 0;
+ for y in 1..ly - 1 {
+ for x in 1..lx - 1 {
+ if m[y][x] != 'A' {
+ continue;
+ }
+ let a = [
+ m[y - 1][x - 1],
+ m[y - 1][x + 1],
+ m[y + 1][x + 1],
+ m[y + 1][x - 1],
+ ];
+ if a == ['M', 'M', 'S', 'S']
+ || a == ['S', 'M', 'M', 'S']
+ || a == ['S', 'S', 'M', 'M']
+ || a == ['M', 'S', 'S', 'M']
+ {
+ count += 1;
+ }
+ }
+ }
+ count
+}
+
+fn main() {
+ let args: Vec<String> = env::args().collect();
+ let filename = if args.len() == 1 {
+ "in/".to_owned() + args[0].split('/').last().unwrap() + ".pzl"
+ } else {
+ args[1].clone()
+ };
+ let mut f = File::open(filename).expect("cannot open file");
+ let mut content = String::new();
+ f.read_to_string(&mut content).expect("cannot read file");
+ let lines = content.trim_end().split("\n");
+
+ let mut m: Vec<Vec<char>> = Vec::new();
+ for line in lines {
+ let mut l: Vec<char> = Vec::new();
+ for c in line.bytes() {
+ l.push(c as char)
+ }
+ m.push(l)
+ }
+ //println!("{:?}", m);
+
+ let ly = m.len();
+ let lx = m[0].len();
+
+ let mut res1 = 0;
+ res1 += horizontal(lx, ly, &m);
+ res1 += vertical(lx, ly, &m);
+ res1 += diag1(lx, ly, &m);
+ res1 += diag2(lx, ly, &m);
+
+ let res2 = mas(lx, ly, &m);
+
+ println!("res1: {}", res1);
+ println!("res2: {}", res2);
+ assert_eq!(res1, 2575);
+ assert_eq!(res2, 2041);
+}