diff --git a/src/main.rs b/src/main.rs index e328a79..ea38a9b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,86 +1,29 @@ use anyhow::Result; -use fancy_regex::Regex; -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 -} +use std::{collections::HashSet, io::stdin}; fn main() -> Result<()> { - let num_re = Regex::new(r"(\d+)")?; - let mut sum = 0; - let lines: Vec = 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> = 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() { - for m in num_re.captures_iter(line) { - let m = m?; - let num_match = m.get(1).unwrap(); - let num_text = num_match.as_str(); - let num: i32 = num_text.parse()?; - let gears = find_gears( - num_match.start() as i32, - lineno as i32, - num_text.len() as i32, - &raw_lines, - ); - for gear in gears { - let e = gear_map.entry(gear).or_default(); - e.push(num); - } - } + let winning: HashSet = nums[0] + .split_whitespace() + .map(str::parse) + .map_while(Result::ok) + .collect(); + + let mine: HashSet = nums[1] + .split_whitespace() + .map(str::parse) + .map_while(Result::ok) + .collect(); + + let both = winning.intersection(&mine); + let c = both.count(); + 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::(); - } - } - println!("{sum}"); - Ok(()) }