generated from janezicmatej/aoc-template
Compare commits
2 Commits
00000140ae
...
0000015022
Author | SHA1 | Date |
---|---|---|
Matej Janezic | 0000015022 | |
Matej Janezic | 000001408c |
|
@ -0,0 +1,8 @@
|
||||||
|
89010123
|
||||||
|
78121874
|
||||||
|
87430965
|
||||||
|
96549874
|
||||||
|
45678903
|
||||||
|
32019012
|
||||||
|
01329801
|
||||||
|
10456732
|
|
@ -0,0 +1 @@
|
||||||
|
125 17
|
|
@ -0,0 +1,89 @@
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
fn score_trailhead(
|
||||||
|
acc: &mut HashMap<(usize, usize), usize>,
|
||||||
|
grid: &[Vec<usize>],
|
||||||
|
start: (usize, usize),
|
||||||
|
) {
|
||||||
|
let (i, j) = start;
|
||||||
|
let n = grid[i][j];
|
||||||
|
|
||||||
|
if n == 9 {
|
||||||
|
*acc.entry((i, j)).or_default() += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let dirs = [(-1, 0), (0, -1), (1, 0), (0, 1)];
|
||||||
|
|
||||||
|
for (di, dj) in dirs {
|
||||||
|
let (ni, nj) = (i.wrapping_add(di as usize), j.wrapping_add(dj as usize));
|
||||||
|
if let Some(nn) = grid.get(ni).and_then(|row| row.get(nj)) {
|
||||||
|
if *nn == n + 1 {
|
||||||
|
score_trailhead(acc, grid, (ni, nj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_grid(input: &str) -> Vec<Vec<usize>> {
|
||||||
|
input
|
||||||
|
.lines()
|
||||||
|
.map(|x| {
|
||||||
|
x.chars()
|
||||||
|
.map(|y| y.to_digit(10).unwrap_or(11) as usize)
|
||||||
|
.collect_vec()
|
||||||
|
})
|
||||||
|
.collect_vec()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_one(input: &str) -> Option<usize> {
|
||||||
|
let grid = parse_grid(input);
|
||||||
|
|
||||||
|
let mut score = 0;
|
||||||
|
let mut acc = HashMap::new();
|
||||||
|
|
||||||
|
for (i, row) in grid.iter().enumerate() {
|
||||||
|
for (j, _) in row.iter().copied().enumerate().filter(|x| x.1 == 0) {
|
||||||
|
acc.clear();
|
||||||
|
score_trailhead(&mut acc, &grid, (i, j));
|
||||||
|
score += acc.len();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
score.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two(input: &str) -> Option<usize> {
|
||||||
|
let grid = parse_grid(input);
|
||||||
|
|
||||||
|
let mut acc = HashMap::new();
|
||||||
|
|
||||||
|
for (i, row) in grid.iter().enumerate() {
|
||||||
|
for (j, _) in row.iter().copied().enumerate().filter(|x| x.1 == 0) {
|
||||||
|
score_trailhead(&mut acc, &grid, (i, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
acc.values().sum::<usize>().into()
|
||||||
|
}
|
||||||
|
|
||||||
|
aoc::solution!(10);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
assert_eq!(
|
||||||
|
part_one(&aoc::template::read_file("examples", 10)),
|
||||||
|
Some(36)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_part_two() {
|
||||||
|
assert_eq!(
|
||||||
|
part_two(&aoc::template::read_file("examples", 10)),
|
||||||
|
Some(81)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
use std::mem::swap;
|
||||||
|
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
fn blink(map: &HashMap<usize, usize>, nmap: &mut HashMap<usize, usize>) {
|
||||||
|
for (&k, &v) in map.iter() {
|
||||||
|
match k {
|
||||||
|
0 => *nmap.entry(1).or_default() += v,
|
||||||
|
x if (x.ilog10() + 1) % 2 == 0 => {
|
||||||
|
let xlen = x.ilog10() + 1;
|
||||||
|
let xhalf = 10_usize.pow(xlen / 2);
|
||||||
|
|
||||||
|
*nmap.entry(x / xhalf).or_default() += v;
|
||||||
|
*nmap.entry(x % xhalf).or_default() += v;
|
||||||
|
}
|
||||||
|
x => *nmap.entry(x * 2024).or_default() += v,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn solve(input: &str, blinks: usize) -> usize {
|
||||||
|
let v = input
|
||||||
|
.split(" ")
|
||||||
|
.filter_map(|x| x.parse().ok())
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
let mut map = HashMap::<usize, usize>::new();
|
||||||
|
|
||||||
|
for vv in v {
|
||||||
|
*map.entry(vv).or_default() += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut nmap = HashMap::<usize, usize>::new();
|
||||||
|
|
||||||
|
for _ in 0..blinks {
|
||||||
|
blink(&map, &mut nmap);
|
||||||
|
map.clear();
|
||||||
|
swap(&mut map, &mut nmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
map.values().sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_one(input: &str) -> Option<usize> {
|
||||||
|
solve(input, 25).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two(input: &str) -> Option<usize> {
|
||||||
|
solve(input, 75).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
aoc::solution!(11);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
assert_eq!(
|
||||||
|
part_one(&aoc::template::read_file("examples", 11)),
|
||||||
|
Some(55312)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_part_two() {
|
||||||
|
assert_eq!(
|
||||||
|
part_two(&aoc::template::read_file("examples", 11)),
|
||||||
|
Some(65601038650482)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue