add 03
This commit is contained in:
1 parent
d49022f310
commit
331f16786c
6 files changed
+428
No files matched your search
+229
@@ -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
|
||||
}
|
||||
Reference in new issue
Block a user