This commit is contained in:
timeshifter committed 2024-02-02 15:14:46 +01:00
1 parent d49022f310
commit 331f16786c
6 files changed
+428

No files matched your search

+229
View File
@@ -0,0 +1,229 @@
use itertools::Itertools;
use aoc::read_grid;
const WIDTH: usize = 140;
const HEIGHT: usize = 140;
fn main() {
let content = read_grid("input.txt");
println!("{} x {}", content[0].len(), content.len());
part_a(&content);
part_b(&content);
}
fn part_a(grid: &[Vec<char>]) {
// let mut sum = 0;
let coordinates: Vec<_> = find_symbol_coordinates(grid)
.into_iter()
.flat_map(get_adjacent_coordinates)
.unique()
.collect();
let numbers = find_numbers_with_coordinates(grid);
let mut sum = 0;
for number in numbers {
'inner: for coordinate in &coordinates {
if number.contains(*coordinate) {
sum += number.value;
break 'inner;
}
}
}
println!("{sum}");
}
fn part_b(grid: &[Vec<char>]) {
let coordinates = find_star_coordinates(grid);
let numbers = find_numbers_with_coordinates(grid);
let mut result = 0;
let mut adjacent_numbers = vec![];
for coordinate in coordinates {
adjacent_numbers.clear();
let adjacent = get_adjacent_coordinates(coordinate);
for number in &numbers {
'outer: for coordinate in &adjacent {
if number.contains(*coordinate) {
adjacent_numbers.push(number);
break 'outer;
}
}
}
if adjacent_numbers.len() == 2 {
result += adjacent_numbers[0].value * adjacent_numbers[1].value;
}
}
println!("{result}");
}
fn is_symbol(c: char) -> bool {
!(c.is_ascii_digit() || c == '.')
}
fn find_symbol_coordinates(grid: &[Vec<char>]) -> Vec<(usize, usize)> {
let mut result = vec![];
for (y, line) in grid.iter().enumerate() {
for (x, character) in line.iter().enumerate() {
if is_symbol(*character) {
result.push((x, y));
}
}
}
result
}
#[derive(Debug)]
struct Number {
value: usize,
x_min: usize,
x_max: usize,
y: usize,
}
impl Number {
fn new(value: usize, x_min: usize, x_max: usize, y: usize) -> Self {
Self {
value,
x_min,
x_max,
y,
}
}
fn contains(&self, (x, y): (usize, usize)) -> bool {
self.y == y && self.x_min <= x && self.x_max + 1 > x
}
}
fn find_numbers_with_coordinates(grid: &[Vec<char>]) -> Vec<Number> {
let mut result = vec![];
let mut in_number;
let mut accum = vec![];
for (y, line) in grid.iter().enumerate() {
in_number = false;
accum.clear();
for (x, character) in line.iter().enumerate() {
if character.is_ascii_digit() {
in_number = true;
accum.push(character);
if last_digit_in_line(x) {
let number = build_number(&accum, x, y);
result.push(number);
}
} else if in_number {
in_number = false;
let number = build_number(&accum, x, y);
result.push(number);
accum.clear();
}
}
}
result
}
fn last_digit_in_line(x: usize) -> bool {
x == WIDTH - 1
}
fn build_number(accum: &Vec<&char>, x: usize, y: usize) -> Number {
Number::new(
accum.iter().cloned().collect::<String>().parse().unwrap(),
x - (accum.len()),
x - 1,
y,
)
}
#[rustfmt::skip]
fn get_adjacent_coordinates((x, y): (usize, usize)) -> Vec<(usize, usize)> {
if x == 0 {
vec![
(x , y - 1),
(x + 1, y - 1),
(x + 1, y ),
(x , y + 1),
(x + 1, y + 1),
]
} else if y == 0 {
vec![
(x - 1, y ),
(x + 1, y ),
(x - 1, y + 1),
(x , y + 1),
(x + 1, y + 1),
]
} else if x == 0 && y == 0 {
vec![
(x + 1, y ),
(x , y + 1),
(x + 1, y + 1),
]
} else if x == 0 && y-1 == HEIGHT {
vec![
(x , y - 1),
(x + 1, y - 1),
(x + 1, y ),
]
} else if x - 1 == WIDTH {
vec![
(x - 1, y - 1),
(x , y - 1),
(x - 1, y ),
(x - 1, y + 1),
(x , y + 1),
]
} else if x - 1 == WIDTH && y == 0 {
vec![
(x - 1, y ),
(x - 1, y + 1),
(x , y + 1),
]
} else if x - 1 == WIDTH && y - 1 == HEIGHT {
vec![
(x - 1, y - 1),
(x , y - 1),
(x - 1, y ),
]
} else if y - 1 == HEIGHT {
vec![
(x - 1, y - 1),
(x , y - 1),
(x + 1, y - 1),
(x - 1, y ),
(x + 1, y ),
]
} else {
vec![
(x - 1, y - 1),
(x , y - 1),
(x + 1, y - 1),
(x - 1, y ),
(x + 1, y ),
(x - 1, y + 1),
(x , y + 1),
(x + 1, y + 1),
]
}
}
fn find_star_coordinates(grid: &[Vec<char>]) -> Vec<(usize, usize)> {
let mut result = vec![];
for (y, line) in grid.iter().enumerate() {
for (x, character) in line.iter().enumerate() {
if *character == '*' {
result.push((x, y));
}
}
}
result
}