Solve 04
This commit is contained in:
parent
746b07dc83
commit
bfbe7ceb69
2 changed files with 109 additions and 0 deletions
9
justfile
9
justfile
|
@ -27,3 +27,12 @@ begin: _folders
|
||||||
# Makes sure that folders exist
|
# Makes sure that folders exist
|
||||||
_folders:
|
_folders:
|
||||||
mkdir -p input src/bin
|
mkdir -p input src/bin
|
||||||
|
|
||||||
|
# Creates all input files. Use this to start using the repo.
|
||||||
|
init: _folders
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
for i in $(seq -w 1 25);
|
||||||
|
do
|
||||||
|
touch input/$i
|
||||||
|
touch input/$i-test
|
||||||
|
done
|
||||||
|
|
100
src/bin/04.rs
Normal file
100
src/bin/04.rs
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
use aoc::*;
|
||||||
|
use glam::IVec2;
|
||||||
|
|
||||||
|
const INPUT: &str = include_str!("../../input/04");
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_example!(part1, "04-test", 18);
|
||||||
|
println!("Part 1: {}", part1(INPUT));
|
||||||
|
assert_example!(part2, "04-test", 9);
|
||||||
|
println!("Part 2: {}", part2(INPUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(input: &str) -> usize {
|
||||||
|
let field = parse(input);
|
||||||
|
count_over_field(&field, count_xmas_at)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(input: &str) -> usize {
|
||||||
|
let field = parse(input);
|
||||||
|
count_over_field(&field, check_x_mas)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_over_field(field: &Field, count_at: fn(IVec2, &Field) -> usize) -> usize {
|
||||||
|
let mut found = 0;
|
||||||
|
for y in 0..field.data.len() {
|
||||||
|
for x in 0..field.data[y].len() {
|
||||||
|
let start = IVec2::new(x as i32, y as i32);
|
||||||
|
found += count_at(start, field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_x_mas(start: IVec2, field: &Field) -> usize {
|
||||||
|
if field.get(start) != 'A' {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let up1 =
|
||||||
|
field.get(start + IVec2::new(-1, -1)) == 'M' && field.get(start + IVec2::new(1, 1)) == 'S';
|
||||||
|
let up2 =
|
||||||
|
field.get(start + IVec2::new(-1, -1)) == 'S' && field.get(start + IVec2::new(1, 1)) == 'M';
|
||||||
|
let up = up1 || up2;
|
||||||
|
|
||||||
|
let down1 =
|
||||||
|
field.get(start + IVec2::new(1, -1)) == 'M' && field.get(start + IVec2::new(-1, 1)) == 'S';
|
||||||
|
let down2 =
|
||||||
|
field.get(start + IVec2::new(1, -1)) == 'S' && field.get(start + IVec2::new(-1, 1)) == 'M';
|
||||||
|
let down = down1 || down2;
|
||||||
|
|
||||||
|
if up && down {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_xmas_at(start: IVec2, field: &Field) -> usize {
|
||||||
|
DIRECTIONS
|
||||||
|
.iter()
|
||||||
|
.filter(|&&dir| check_xmas(start, dir, field))
|
||||||
|
.count()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_xmas(start: IVec2, direction: IVec2, field: &Field) -> bool {
|
||||||
|
field.get(start) == 'X'
|
||||||
|
&& field.get(start + direction) == 'M'
|
||||||
|
&& field.get(start + direction * 2) == 'A'
|
||||||
|
&& field.get(start + direction * 3) == 'S'
|
||||||
|
}
|
||||||
|
|
||||||
|
const DIRECTIONS: [IVec2; 8] = [
|
||||||
|
IVec2::new(1, 0),
|
||||||
|
IVec2::new(1, 1),
|
||||||
|
IVec2::new(0, 1),
|
||||||
|
IVec2::new(-1, 1),
|
||||||
|
IVec2::new(-1, 0),
|
||||||
|
IVec2::new(-1, -1),
|
||||||
|
IVec2::new(0, -1),
|
||||||
|
IVec2::new(1, -1),
|
||||||
|
];
|
||||||
|
|
||||||
|
struct Field {
|
||||||
|
data: Vec<Vec<char>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Field {
|
||||||
|
fn get(&self, at: IVec2) -> char {
|
||||||
|
self.data
|
||||||
|
.get(at.y as usize)
|
||||||
|
.and_then(|row| row.get(at.x as usize))
|
||||||
|
.copied()
|
||||||
|
.unwrap_or('.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(input: &str) -> Field {
|
||||||
|
let data = input.lines().map(|l| l.chars().collect()).collect();
|
||||||
|
Field { data }
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue