From 3410d1f611ae9f019b271ed8b80ab34ddfc37e31 Mon Sep 17 00:00:00 2001 From: dobiadi Date: Sun, 3 Dec 2023 18:44:27 +0100 Subject: [PATCH] Day3 Rust --- day3/rust/.gitignore | 1 + day3/rust/Cargo.lock | 7 ++ day3/rust/Cargo.toml | 8 +++ day3/rust/src/main.rs | 160 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 day3/rust/.gitignore create mode 100644 day3/rust/Cargo.lock create mode 100644 day3/rust/Cargo.toml create mode 100644 day3/rust/src/main.rs diff --git a/day3/rust/.gitignore b/day3/rust/.gitignore new file mode 100644 index 0000000..eb5a316 --- /dev/null +++ b/day3/rust/.gitignore @@ -0,0 +1 @@ +target diff --git a/day3/rust/Cargo.lock b/day3/rust/Cargo.lock new file mode 100644 index 0000000..b21cc6a --- /dev/null +++ b/day3/rust/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "rust" +version = "0.1.0" diff --git a/day3/rust/Cargo.toml b/day3/rust/Cargo.toml new file mode 100644 index 0000000..1ec6963 --- /dev/null +++ b/day3/rust/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day3/rust/src/main.rs b/day3/rust/src/main.rs new file mode 100644 index 0000000..b494390 --- /dev/null +++ b/day3/rust/src/main.rs @@ -0,0 +1,160 @@ +struct Number { + value: usize, +} + +enum Symbol { + Asterisk, + Other, +} + +enum Tile<'a> { + Number(&'a Number), + Symbol(Symbol), + Period, +} + +fn main() { + let stdin = std::io::stdin(); + + let mut map: Vec> = Vec::new(); + + for line in stdin.lines() { + let line = line.unwrap(); + + let mut num = Vec::new(); + let mut v = Vec::new(); + for char in line.chars() { + if !char.is_digit(10) && num.len() > 0 { + let s: String = num.iter().collect(); + + let number = Box::leak(Box::new(Number { + value: s.parse().unwrap(), + })); + + for _ in 0..s.len() { + v.push(Tile::Number(number)); + } + + num.clear(); + } + + if char == '.' { + v.push(Tile::Period); + } else if char == '*' { + v.push(Tile::Symbol(Symbol::Asterisk)); + } else if char.is_digit(10) { + num.push(char); + } else { + v.push(Tile::Symbol(Symbol::Other)); + } + } + + if num.len() > 0 { + let s: String = num.iter().collect(); + + let number = Box::leak(Box::new(Number { + value: s.parse().unwrap(), + })); + + for _ in 0..s.len() { + v.push(Tile::Number(number)); + } + } + map.push(v); + } + + // Part 1 + let mut part1 = 0; + + for (x, row) in map.iter().enumerate() { + let mut already_added = false; + for (y, tile) in row.iter().enumerate() { + match tile { + Tile::Number(number) => { + if already_added { + continue; + }; + + for dx in -1i32..=1 { + for dy in -1i32..=1 { + let ix = x.wrapping_add(dx as usize); + let iy = y.wrapping_add(dy as usize); + if let Some(v) = map.get(ix) { + if let Some(Tile::Symbol(_)) = v.get(iy) { + already_added = true; + part1 += number.value; + } + } + if already_added { + break; + }; + } + if already_added { + break; + }; + } + } + _ => { + if already_added { + already_added = false; + } + } + } + } + } + + println!("{}", part1); + + // Part 2 + let mut part2 = 0; + + for (x, row) in map.iter().enumerate() { + for (y, tile) in row.iter().enumerate() { + if let Tile::Symbol(Symbol::Asterisk) = tile { + let mut gears = [None; 2]; + let mut gear_num = 0; + let mut skip = false; + + for dx in -1i32..=1 { + for dy in -1i32..=1 { + let ix = x.wrapping_add(dx as usize); + let iy = y.wrapping_add(dy as usize); + if let Some(v) = map.get(ix) { + if let Some(Tile::Number(number)) = v.get(iy) { + if let Some(gear) = gears[0] { + if std::ptr::eq(gear, *number) { + continue; + } + } + if let Some(gear) = gears[1] { + if std::ptr::eq(gear, *number) { + continue; + } + } + + if gear_num == 2 { + skip = true; + break; + } + + gears[gear_num] = Some(*number); + gear_num += 1; + } + } + } + if skip { + break; + } + } + + if gear_num == 2 { + unsafe { + part2 += (*gears[0].unwrap()).value * (*gears[1].unwrap()).value; + } + } + } + } + } + + println!("{}", part2); +}