From 659a9ce482e18dde568fa864dbba3ca7200557c3 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Sun, 3 Dec 2023 13:05:05 -0500 Subject: [PATCH] Rename Addr to Part and create a new Addr struct --- 2023/src/day3.rs | 315 +++++++++++++++++++++++------------------------ 1 file changed, 157 insertions(+), 158 deletions(-) diff --git a/2023/src/day3.rs b/2023/src/day3.rs index eeb383d..e2dc2d8 100644 --- a/2023/src/day3.rs +++ b/2023/src/day3.rs @@ -16,17 +16,27 @@ pub fn day3b() -> String { ) } -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] struct Addr { + row: usize, + col: usize, +} + +#[derive(Clone, Debug, PartialEq)] +struct Part { + value: u32, row: usize, start: usize, end: usize, } -impl Addr { - fn span(&self) -> Vec<(usize, usize)> { +impl Part { + fn span(&self) -> Vec { (self.start..self.end + 1) - .map(|addr| (self.row, addr)) + .map(|addr| Addr { + row: self.row, + col: addr, + }) .collect() } } @@ -41,19 +51,21 @@ impl Gear { } fn sum_parts(schematic: String) -> u32 { - parts(schematic).into_iter().fold(0, |acc, val| acc + val.0) + parts(schematic) + .into_iter() + .fold(0, |acc, val| acc + val.value) } -fn parts(schematic: String) -> Vec<(u32, Addr)> { +fn parts(schematic: String) -> Vec { let sc = schematic .lines() .map(|l| l.to_owned()) .collect::>(); - let numbers = find_numbers(schematic.clone()); - numbers + let parts = find_numbers(schematic.clone()); + parts .into_iter() - .filter(|number| is_part(&sc, number)) - .collect::>() + .filter(|part| is_part(&sc, part.clone())) + .collect::>() } fn find_gears(schematic: String) -> Vec { @@ -66,56 +78,52 @@ fn find_gears(schematic: String) -> Vec { let parts = parts(schematic); let splats = find_splats(sc) .into_iter() - .map(|(row, col)| { + .map(|addr| { halo( - Addr { - row, - start: col, - end: col, + Part { + value: 0, + row: addr.row, + start: addr.col, + end: addr.col, }, max_row - 1, max_col - 1, ) }) - .collect::>>(); + .collect::>>(); let mut gears = vec![]; for splat in splats { let overlap = parts .iter() - .filter(|part| part_within_halo(splat.clone(), part.1.clone())) - .map(|part| part.0) - .collect::>(); + .filter(|part| part_within_halo(splat.clone(), (*part).clone())) + .map(|part| part.clone()) + .collect::>(); if overlap.len() == 2 { - gears.push(Gear(overlap[0], overlap[1])); + gears.push(Gear(overlap[0].value, overlap[1].value)); } } gears } -fn part_within_halo(halo1: Vec<(usize, usize)>, part: Addr) -> bool { - let halo1: HashSet<(usize, usize)> = halo1.into_iter().collect::>(); - let halo2: HashSet<(usize, usize)> = - part.span().into_iter().collect::>(); +fn part_within_halo(halo1: Vec, part: Part) -> bool { + let halo1: HashSet = halo1.into_iter().collect::>(); + let halo2: HashSet = part.span().into_iter().collect::>(); halo1.intersection(&halo2).count() > 0 } -fn is_part(schematic: &Vec, number: &(u32, Addr)) -> bool { - halo( - number.1.clone(), - schematic.len() - 1, - schematic[0].len() - 1, - ) - .into_iter() - .any(|(row, col)| { - let cell = schematic[row].chars().nth(col).unwrap(); - !cell.is_digit(10) && cell != '.' - }) +fn is_part(schematic: &Vec, part: Part) -> bool { + halo(part.clone(), schematic.len() - 1, schematic[0].len() - 1) + .into_iter() + .any(|addr| { + let cell = schematic[addr.row].chars().nth(addr.col).unwrap(); + !cell.is_digit(10) && cell != '.' + }) } -fn halo(addr: Addr, max_row: usize, max_col: usize) -> Vec<(usize, usize)> { +fn halo(addr: Part, max_row: usize, max_col: usize) -> Vec { let mut halo: Vec<(i32, i32)> = vec![]; for r in addr.start..addr.end + 1 { @@ -134,26 +142,25 @@ fn halo(addr: Addr, max_row: usize, max_col: usize) -> Vec<(usize, usize)> { .filter(|(row, col)| { *row >= 0 && *row <= max_row as i32 && *col >= 0 && *col <= max_col as i32 }) - .map(|(row, col)| (row as usize, col as usize)) + .map(|(row, col)| Addr { + row: row as usize, + col: col as usize, + }) .collect() } -fn find_numbers(schematic: String) -> Vec<(u32, Addr)> { +fn find_numbers(schematic: String) -> Vec { let mut result = vec![]; for (idx, line) in schematic.lines().enumerate() { let mut numbers = find_numbers_in_line(line) .into_iter() - .map(|(number, start, len)| { - ( - number, - Addr { - row: idx, - start, - end: start + len - 1, - }, - ) + .map(|(value, start, len)| Part { + value: value, + row: idx, + start, + end: start + len - 1, }) - .collect::>(); + .collect::>(); result.append(&mut numbers); } result @@ -193,7 +200,7 @@ fn find_numbers_in_line(line: &str) -> Vec<(u32, usize, usize)> { .collect() } -fn find_splats(schematic: Vec) -> Vec<(usize, usize)> { +fn find_splats(schematic: Vec) -> Vec { schematic .into_iter() .enumerate() @@ -202,15 +209,18 @@ fn find_splats(schematic: Vec) -> Vec<(usize, usize)> { .enumerate() .filter_map(|(col_idx, c)| { if is_splat(c) { - Some((row_idx, col_idx)) + Some(Addr { + row: row_idx, + col: col_idx, + }) } else { None } }) - .collect::>() + .collect::>() }) .flatten() - .collect::>() + .collect::>() } fn is_symbol(c: char) -> bool { @@ -241,7 +251,7 @@ mod test { assert_eq!( parts(INPUT.to_owned()) .into_iter() - .map(|part| part.0) + .map(|part| part.value) .collect::>(), vec![467, 35, 633, 617, 592, 755, 664, 598] ); @@ -255,86 +265,66 @@ mod test { assert_eq!( find_numbers(INPUT.to_owned()), vec![ - ( - 467, - Addr { - row: 0, - start: 0, - end: 2 - } - ), - ( - 114, - Addr { - row: 0, - start: 5, - end: 7 - } - ), - ( - 35, - Addr { - row: 2, - start: 2, - end: 3 - } - ), - ( - 633, - Addr { - row: 2, - start: 6, - end: 8 - } - ), - ( - 617, - Addr { - row: 4, - start: 0, - end: 2 - } - ), - ( - 58, - Addr { - row: 5, - start: 7, - end: 8, - } - ), - ( - 592, - Addr { - row: 6, - start: 2, - end: 4, - } - ), - ( - 755, - Addr { - row: 7, - start: 6, - end: 8, - } - ), - ( - 664, - Addr { - row: 9, - start: 1, - end: 3, - } - ), - ( - 598, - Addr { - row: 9, - start: 5, - end: 7, - } - ) + Part { + value: 467, + row: 0, + start: 0, + end: 2 + }, + Part { + value: 114, + row: 0, + start: 5, + end: 7 + }, + Part { + value: 35, + row: 2, + start: 2, + end: 3 + }, + Part { + value: 633, + row: 2, + start: 6, + end: 8 + }, + Part { + value: 617, + row: 4, + start: 0, + end: 2 + }, + Part { + value: 58, + row: 5, + start: 7, + end: 8, + }, + Part { + value: 592, + row: 6, + start: 2, + end: 4, + }, + Part { + value: 755, + row: 7, + start: 6, + end: 8, + }, + Part { + value: 664, + row: 9, + start: 1, + end: 3, + }, + Part { + value: 598, + row: 9, + start: 5, + end: 7, + } ] ); } @@ -358,19 +348,27 @@ mod test { #[test] fn test_halo() { let schematic = INPUT.lines().map(|l| l.to_owned()).collect::>(); - let number = Addr { + let part = Part { + value: 0, row: 0, start: 0, end: 2, }; assert_eq!( - halo(number, schematic.len() - 1, schematic[0].len() - 1), - vec![(1, 0), (1, 1), (1, 2), (0, 3), (1, 3)] + halo(part, schematic.len() - 1, schematic[0].len() - 1), + vec![ + Addr { row: 1, col: 0 }, + Addr { row: 1, col: 1 }, + Addr { row: 1, col: 2 }, + Addr { row: 0, col: 3 }, + Addr { row: 1, col: 3 } + ] ); assert_eq!( halo( - Addr { + Part { + value: 0, row: 1, start: 1, end: 1 @@ -379,19 +377,20 @@ mod test { schematic[0].len() - 1 ), vec![ - (0, 1), - (2, 1), - (0, 0), - (1, 0), - (2, 0), - (0, 2), - (1, 2), - (2, 2) + Addr { row: 0, col: 1 }, + Addr { row: 2, col: 1 }, + Addr { row: 0, col: 0 }, + Addr { row: 1, col: 0 }, + Addr { row: 2, col: 0 }, + Addr { row: 0, col: 2 }, + Addr { row: 1, col: 2 }, + Addr { row: 2, col: 2 } ] ); assert_eq!( halo( - Addr { + Part { + value: 0, row: 6, start: 2, end: 4, @@ -400,18 +399,18 @@ mod test { schematic[0].len() - 1 ), vec![ - (5, 2), - (7, 2), - (5, 3), - (7, 3), - (5, 4), - (7, 4), - (5, 1), - (6, 1), - (7, 1), - (5, 5), - (6, 5), - (7, 5), + Addr { row: 5, col: 2 }, + Addr { row: 7, col: 2 }, + Addr { row: 5, col: 3 }, + Addr { row: 7, col: 3 }, + Addr { row: 5, col: 4 }, + Addr { row: 7, col: 4 }, + Addr { row: 5, col: 1 }, + Addr { row: 6, col: 1 }, + Addr { row: 7, col: 1 }, + Addr { row: 5, col: 5 }, + Addr { row: 6, col: 5 }, + Addr { row: 7, col: 5 }, ] ); }