day 4 part 1 (in Rust)

This commit is contained in:
Andy Teijelo 2023-12-04 15:53:15 -05:00
parent 8ff5e7f9c9
commit 7d234e0fc2

View file

@ -1,86 +1,29 @@
use anyhow::Result; use anyhow::Result;
use fancy_regex::Regex; use std::{collections::HashSet, io::stdin};
use std::{collections::HashMap, io::stdin};
fn is_gear(x: i32, y: i32, lines: &[&[u8]]) -> bool {
if x < 0 {
return false;
}
if y < 0 {
return false;
}
if y as usize >= lines.len() {
return false;
}
let line = &lines[y as usize];
if x as usize >= line.len() {
return false;
}
if line[x as usize] == b'*' {
return true;
}
false
}
fn find_gears(x: i32, y: i32, len: i32, lines: &[&[u8]]) -> Vec<(i32, i32)> {
let mut v = vec![];
for cx in (x - 1)..(x + len) {
if is_gear(cx, y - 1, lines) {
v.push((cx, y - 1));
}
}
for cy in (y - 1)..=y {
if is_gear(x + len, cy, lines) {
v.push((x + len, cy));
}
}
for cx in x..=(x + len) {
if is_gear(cx, y + 1, lines) {
v.push((cx, y + 1));
}
}
for cy in y..=(y + 1) {
if is_gear(x - 1, cy, lines) {
v.push((x - 1, cy));
}
}
v
}
fn main() -> Result<()> { fn main() -> Result<()> {
let num_re = Regex::new(r"(\d+)")?;
let mut sum = 0; let mut sum = 0;
let lines: Vec<String> = stdin().lines().map_while(Result::ok).collect();
let raw_lines: Vec<&[u8]> = lines.iter().map(|s| s.as_bytes()).collect();
let mut gear_map: HashMap<(i32, i32), Vec<i32>> = HashMap::new(); for line in stdin().lines().map_while(Result::ok) {
let p: Vec<_> = line.split(':').collect();
let nums: Vec<_> = p[1].split('|').collect();
for (lineno, line) in lines.iter().enumerate() { let winning: HashSet<i32> = nums[0]
for m in num_re.captures_iter(line) { .split_whitespace()
let m = m?; .map(str::parse)
let num_match = m.get(1).unwrap(); .map_while(Result::ok)
let num_text = num_match.as_str(); .collect();
let num: i32 = num_text.parse()?;
let gears = find_gears( let mine: HashSet<i32> = nums[1]
num_match.start() as i32, .split_whitespace()
lineno as i32, .map(str::parse)
num_text.len() as i32, .map_while(Result::ok)
&raw_lines, .collect();
);
for gear in gears { let both = winning.intersection(&mine);
let e = gear_map.entry(gear).or_default(); let c = both.count();
e.push(num); sum += if c > 0 { 2i32.pow(c as u32 - 1) } else { 0 };
}
}
} }
for v in gear_map.values() {
if v.len() == 2 {
sum += v.iter().product::<i32>();
}
}
println!("{sum}"); println!("{sum}");
Ok(()) Ok(())
} }