mirror of
https://github.com/anthonyoteri/advent-of-code-2023.git
synced 2026-06-05 18:56:53 -04:00
+81
-1
@@ -1,4 +1,4 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
enum Value {
|
enum Value {
|
||||||
@@ -75,6 +75,79 @@ fn part_1(input: &str) -> u32 {
|
|||||||
sum
|
sum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn part_2(input: &str) -> u32 {
|
||||||
|
let numbers = input
|
||||||
|
.lines()
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(row, line)| {
|
||||||
|
extract_numbers(line)
|
||||||
|
.into_iter()
|
||||||
|
.map(move |(col, len, number)| {
|
||||||
|
(
|
||||||
|
(col..col + len)
|
||||||
|
.map(|c| Address {
|
||||||
|
row: row as i32,
|
||||||
|
col: c as i32,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
number,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<Vec<(Vec<Address>, u32)>>();
|
||||||
|
|
||||||
|
let grid = input
|
||||||
|
.lines()
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(row, line)| {
|
||||||
|
line.chars().enumerate().map(move |(col, character)| {
|
||||||
|
(
|
||||||
|
Address {
|
||||||
|
row: row as i32,
|
||||||
|
col: col as i32,
|
||||||
|
},
|
||||||
|
match character {
|
||||||
|
'.' => None,
|
||||||
|
c if c.is_ascii_digit() => Some(Value::Digit(c.to_digit(10).unwrap())),
|
||||||
|
c => Some(Value::Symbol(c)),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<BTreeMap<Address, Option<Value>>>();
|
||||||
|
|
||||||
|
let gears: BTreeSet<Address> = grid
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(address, value)| match value {
|
||||||
|
Some(Value::Symbol('*')) => Some(address.clone()),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
dbg!(&gears);
|
||||||
|
|
||||||
|
let mut sum = 0;
|
||||||
|
for gear in gears {
|
||||||
|
let bounding_numbers = numbers
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(addresses, number)| {
|
||||||
|
if addresses.iter().flat_map(bounding_box).any(|a| a == gear) {
|
||||||
|
Some(number)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if bounding_numbers.len() == 2 {
|
||||||
|
println!("Including numbers {:?}", bounding_numbers);
|
||||||
|
sum += bounding_numbers.into_iter().product::<u32>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sum
|
||||||
|
}
|
||||||
|
|
||||||
fn extract_numbers(input: &str) -> Vec<(usize, usize, u32)> {
|
fn extract_numbers(input: &str) -> Vec<(usize, usize, u32)> {
|
||||||
let mut result = Vec::default();
|
let mut result = Vec::default();
|
||||||
let mut current_number = String::new();
|
let mut current_number = String::new();
|
||||||
@@ -145,6 +218,7 @@ fn bounding_box(address: &Address) -> Vec<Address> {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let input = include_str!("../input.txt");
|
let input = include_str!("../input.txt");
|
||||||
println!("Part 1: {}", part_1(input));
|
println!("Part 1: {}", part_1(input));
|
||||||
|
println!("Part 2: {}", part_2(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -166,4 +240,10 @@ mod test {
|
|||||||
let input = include_str!("../test-input.txt");
|
let input = include_str!("../test-input.txt");
|
||||||
assert_eq!(part_1(input), 4361);
|
assert_eq!(part_1(input), 4361);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part2() {
|
||||||
|
let input = include_str!("../test-input.txt");
|
||||||
|
assert_eq!(part_2(input), 467835);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user