1
0
Fork 0

day(03): add solution

Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
Matej Focko 2023-12-03 12:59:28 +01:00
parent 673c9299d5
commit ea6275d9e5
Signed by: mfocko
GPG key ID: 7C47D46246790496
2 changed files with 169 additions and 0 deletions

10
samples/day03.txt Normal file
View file

@ -0,0 +1,10 @@
467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..

159
src/bin/day03.rs Normal file
View file

@ -0,0 +1,159 @@
use std::{cmp, collections::HashMap};
use aoc_2023::*;
type Output1 = i32;
type Output2 = Output1;
struct Day03 {
lines: Vec<String>,
}
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 {
let symbols = self
.lines
.iter()
.enumerate()
.flat_map(|(y, line)| {
line.chars().enumerate().filter_map(move |(x, c)| {
if c != '.' && !c.is_ascii_digit() {
Some(((y + 1, x + 1), c))
} else {
None
}
})
})
.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 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()
.enumerate()
.flat_map(|(y, line)| {
let mut nums = vec![];
let mut start = line.len();
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 if start != line.len() {
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().for_each(|(y, start, x, num)| {
let mut possible_gears = vec![(*y, start - 1), (*y, *x)];
(*start - 1..=*x).for_each(|xx: usize| {
possible_gears.push((y - 1, xx));
possible_gears.push((y + 1, xx));
});
for (y, x) in possible_gears {
if symbols.contains_key(&(y, x)) {
symbol_counters.entry((y, x)).or_default().push(*num);
break;
}
}
});
symbol_counters
.values()
.filter_map(|nums| {
if nums.len() == 2 {
Some(nums.iter().product1::<i32>().unwrap())
} else {
None
}
})
.sum()
}
}
fn main() -> Result<()> {
Day03::main()
}
test_sample!(day_03, Day03, 4361, 467835);