day(03): refactor the solution
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
ea6275d9e5
commit
45b6f64a3e
1 changed files with 67 additions and 83 deletions
152
src/bin/day03.rs
152
src/bin/day03.rs
|
@ -5,19 +5,33 @@ use aoc_2023::*;
|
||||||
type Output1 = i32;
|
type Output1 = i32;
|
||||||
type Output2 = Output1;
|
type Output2 = Output1;
|
||||||
|
|
||||||
struct Day03 {
|
struct Number {
|
||||||
lines: Vec<String>,
|
y: usize,
|
||||||
|
x_min: usize,
|
||||||
|
x_max: usize,
|
||||||
|
value: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Number {
|
||||||
|
fn new(y: usize, x_min: usize, x_max: usize, value: i32) -> Number {
|
||||||
|
Number {
|
||||||
|
y,
|
||||||
|
x_min,
|
||||||
|
x_max,
|
||||||
|
value,
|
||||||
}
|
}
|
||||||
impl Solution<Output1, Output2> for Day03 {
|
|
||||||
fn new<P: AsRef<Path>>(pathname: P) -> Self {
|
|
||||||
Self {
|
|
||||||
lines: file_to_lines(pathname),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_1(&mut self) -> Output1 {
|
struct Day03 {
|
||||||
let symbols = self
|
symbols: HashMap<(usize, usize), char>,
|
||||||
.lines
|
numbers: Vec<Number>,
|
||||||
|
}
|
||||||
|
impl Solution<Output1, Output2> for Day03 {
|
||||||
|
fn new<P: AsRef<Path>>(pathname: P) -> Self {
|
||||||
|
let lines = file_to_lines(pathname);
|
||||||
|
|
||||||
|
let symbols = lines
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.flat_map(|(y, line)| {
|
.flat_map(|(y, line)| {
|
||||||
|
@ -30,72 +44,8 @@ impl Solution<Output1, Output2> for Day03 {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<HashMap<(usize, usize), char>>();
|
.collect::<HashMap<(usize, usize), char>>();
|
||||||
let numbers = self
|
|
||||||
.lines
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.flat_map(|(y, line)| {
|
|
||||||
let mut nums = vec![];
|
|
||||||
|
|
||||||
let mut start = line.len();
|
let numbers = lines
|
||||||
let mut num = 0;
|
|
||||||
for (x, c) in line.chars().enumerate() {
|
|
||||||
if c.is_ascii_digit() {
|
|
||||||
start = cmp::min(start, x);
|
|
||||||
num = num * 10 + c.to_digit(10).unwrap() as i32;
|
|
||||||
} else {
|
|
||||||
nums.push((y + 1, start + 1, x + 1, num));
|
|
||||||
|
|
||||||
start = line.len();
|
|
||||||
num = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if start != line.len() {
|
|
||||||
nums.push((y + 1, start + 1, line.len() + 1, num));
|
|
||||||
}
|
|
||||||
|
|
||||||
nums
|
|
||||||
})
|
|
||||||
.collect_vec();
|
|
||||||
|
|
||||||
numbers
|
|
||||||
.iter()
|
|
||||||
.filter_map(|(y, start, x, num)| {
|
|
||||||
if symbols.contains_key(&(*y, start - 1))
|
|
||||||
|| symbols.contains_key(&(*y, *x))
|
|
||||||
|| (*start - 1..=*x).any(|xx| {
|
|
||||||
symbols.contains_key(&(y - 1, xx)) || symbols.contains_key(&(y + 1, xx))
|
|
||||||
})
|
|
||||||
{
|
|
||||||
Some(*num)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.sum()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn part_2(&mut self) -> Output2 {
|
|
||||||
let symbols = self
|
|
||||||
.lines
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.flat_map(|(y, line)| {
|
|
||||||
line.chars().enumerate().filter_map(move |(x, c)| {
|
|
||||||
if c == '*' {
|
|
||||||
Some(((y + 1, x + 1), c))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect::<HashMap<(usize, usize), char>>();
|
|
||||||
|
|
||||||
let mut symbol_counters: HashMap<(usize, usize), Vec<i32>> = HashMap::new();
|
|
||||||
|
|
||||||
let numbers = self
|
|
||||||
.lines
|
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.flat_map(|(y, line)| {
|
.flat_map(|(y, line)| {
|
||||||
|
@ -108,7 +58,7 @@ impl Solution<Output1, Output2> for Day03 {
|
||||||
start = cmp::min(start, x);
|
start = cmp::min(start, x);
|
||||||
num = num * 10 + c.to_digit(10).unwrap() as i32;
|
num = num * 10 + c.to_digit(10).unwrap() as i32;
|
||||||
} else if start != line.len() {
|
} else if start != line.len() {
|
||||||
nums.push((y + 1, start + 1, x + 1, num));
|
nums.push(Number::new(y + 1, start + 1, x + 1, num));
|
||||||
|
|
||||||
start = line.len();
|
start = line.len();
|
||||||
num = 0;
|
num = 0;
|
||||||
|
@ -116,25 +66,59 @@ impl Solution<Output1, Output2> for Day03 {
|
||||||
}
|
}
|
||||||
|
|
||||||
if start != line.len() {
|
if start != line.len() {
|
||||||
nums.push((y + 1, start + 1, line.len() + 1, num));
|
nums.push(Number::new(y + 1, start + 1, line.len() + 1, num));
|
||||||
}
|
}
|
||||||
|
|
||||||
nums
|
nums
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
numbers.iter().for_each(|(y, start, x, num)| {
|
Self { symbols, numbers }
|
||||||
let mut possible_gears = vec![(*y, start - 1), (*y, *x)];
|
}
|
||||||
|
|
||||||
(*start - 1..=*x).for_each(|xx: usize| {
|
fn part_1(&mut self) -> Output1 {
|
||||||
possible_gears.push((y - 1, xx));
|
self.numbers
|
||||||
possible_gears.push((y + 1, xx));
|
.iter()
|
||||||
|
.filter_map(|n| {
|
||||||
|
if self.symbols.contains_key(&(n.y, n.x_min - 1))
|
||||||
|
|| self.symbols.contains_key(&(n.y, n.x_max))
|
||||||
|
|| (n.x_min - 1..=n.x_max).any(|xx| {
|
||||||
|
self.symbols.contains_key(&(n.y - 1, xx))
|
||||||
|
|| self.symbols.contains_key(&(n.y + 1, xx))
|
||||||
|
})
|
||||||
|
{
|
||||||
|
Some(n.value)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part_2(&mut self) -> Output2 {
|
||||||
|
let mut symbol_counters: HashMap<(usize, usize), Vec<i32>> = self
|
||||||
|
.symbols
|
||||||
|
.iter()
|
||||||
|
.filter_map(|((y, x), s)| {
|
||||||
|
if *s == '*' {
|
||||||
|
Some(((*y, *x), vec![]))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.numbers.iter().for_each(|n| {
|
||||||
|
let mut possible_gears = vec![(n.y, n.x_min - 1), (n.y, n.x_max)];
|
||||||
|
|
||||||
|
(n.x_min - 1..=n.x_max).for_each(|xx: usize| {
|
||||||
|
possible_gears.push((n.y - 1, xx));
|
||||||
|
possible_gears.push((n.y + 1, xx));
|
||||||
});
|
});
|
||||||
|
|
||||||
for (y, x) in possible_gears {
|
for (y, x) in possible_gears {
|
||||||
if symbols.contains_key(&(y, x)) {
|
if let Some(nums) = symbol_counters.get_mut(&(y, x)) {
|
||||||
symbol_counters.entry((y, x)).or_default().push(*num);
|
nums.push(n.value);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue