Day3 Rust

This commit is contained in:
dobiadi
2023-12-03 18:44:27 +01:00
parent 7913dcea4a
commit 3410d1f611
4 changed files with 176 additions and 0 deletions

1
day3/rust/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
target

7
day3/rust/Cargo.lock generated Normal file
View File

@@ -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"

8
day3/rust/Cargo.toml Normal file
View File

@@ -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]

160
day3/rust/src/main.rs Normal file
View File

@@ -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<Tile>> = 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);
}