diff --git a/2024/04/p1/main.rs b/2024/04/p1/main.rs new file mode 100644 index 0000000..71c9eef --- /dev/null +++ b/2024/04/p1/main.rs @@ -0,0 +1,112 @@ +use std::{fs::File, io::Read}; + +fn main() -> std::io::Result<()> { + let args: Vec<_> = std::env::args().collect(); + let filename = &args[1]; + + let mut contents = String::new(); + let mut file = File::open(filename)?; + file.read_to_string(&mut contents)?; + + let lines: Vec<_> = contents.lines().collect(); + // let height = lines.len(); + // let width = lines[0].len(); + // let res_buf: Vec> = (0..height) + // .map(|_| (0..width).map(|_| '.').collect()) + // .collect(); + // _ = &res_buf; + + print_res( + &lines + .iter() + .map(|ln| ln.chars().collect::>()) + .collect::>(), + ); + + // let r = eq_in_dir( + // &lines + // .iter() + // .map(|ln| ln.chars().collect::>()) + // .collect::>(), + // (4, 0), + // (1, 1), + // "MAS".chars(), + // ); + // println!("{r:?}"); + // return Ok(()); + + let mut t = 0; + for (i, ln) in lines.iter().enumerate() { + for (j, ch) in ln.chars().enumerate() { + if ch == 'X' { + // println!("X found at ({j}, {i})"); + let map = [-1, 0, 1].map(|i| [-1, 0, 1].map(|j| (i, j))); + for dir in map.as_flattened() { + let r = eq_in_dir( + &lines + .iter() + .map(|ln| ln.chars().collect::>()) + .collect::>(), + (j, i), + *dir, + "MAS".chars(), + ); + if r { t += 1; } + // println!(" {dir:?}: {r:?}"); + } + } + } + } + + println!("total {t}"); + Ok(()) +} + +fn eq_in_dir( + buf: &[Vec], + pos: (usize, usize), + dir: (isize, isize), + matches: impl Iterator, +) -> bool { + opt_eq_in_dir(buf, pos, dir, matches).is_some() +} + +fn opt_eq_in_dir( + buf: &[Vec], + pos: (usize, usize), + dir: (isize, isize), + mut matches: impl Iterator, +) -> Option<()> { + + // println!(" {pos:?} {dir:?}"); + let Some(must_match) = matches.next() else { + return Some(()); + }; + // println!(" {must_match:?}"); + + let new_1 = do_the_thing(dir.1, pos.1)?; + let new_0 = do_the_thing(dir.0, pos.0)?; + let ln = buf.get(new_1)?; + let ch = ln.get(new_0)?; + // println!(" {ch:?}"); + + if must_match == *ch { + opt_eq_in_dir(buf, (new_0, new_1), dir, matches) + } else { + None + } +} + +fn do_the_thing(a: isize, b: usize) -> Option { + let r = b as isize + a; + if r < 0 { + return None; + } + Some(r as usize) +} + +fn print_res(buf: &[Vec]) { + for ln in buf.iter() { + println!("{}", ln.iter().collect::()) + } +} diff --git a/README.md b/README.md index 3cbb8aa..ab888dc 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ What is AOC??: [adventofcode](https://adventofcode.com) All this is a mix of langs, but in general: * `asm`: I use nasm, at least for now for assembly programs (linux, x86\_64), no special linking normallly, so just elf64 compile and link. -* `zig`: No need to set up a full project, simply `zig build-exe -fstrip -OReleaseFast main.zig` +* `zig`: No need to set up a full project, simply `zig build-exe -O ReleaseFast -fsingle-threaded -fno-unwind-tables -fno-error-tracing -fno-formatted-panics -fstrip -fno-stack-protector main.zig` for max performance. +* `rust`: No need for projects neither, also `rustc -Copt-level=3 -Ctarget-cpu=native -Cpanic=abort -Cstrip=symbols -Coverflow_checks=n -Clto=fat` for squeezing performance. I also tend to use `perf stat` to check their performance.