day10-11
This commit is contained in:
parent
f96ab9d93b
commit
a576f4712f
|
@ -0,0 +1,133 @@
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
use hashbrown::HashSet;
|
||||||
|
|
||||||
|
type Input = (usize, usize, Vec<Vec<u8>>);
|
||||||
|
|
||||||
|
#[aoc_generator(day10)]
|
||||||
|
fn parse(input: &str) -> Input {
|
||||||
|
let map = input
|
||||||
|
.lines()
|
||||||
|
.map(|line| line.chars().map(|c| c as u8 - 48).collect())
|
||||||
|
.collect::<Vec<Vec<u8>>>();
|
||||||
|
let w = map[0].len();
|
||||||
|
let h = map.len();
|
||||||
|
(w, h, map)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day10, part1)]
|
||||||
|
fn part1(input: &Input) -> usize {
|
||||||
|
let mut queue = VecDeque::new();
|
||||||
|
let mut paths = HashSet::new();
|
||||||
|
let (w, h, map) = input;
|
||||||
|
let h = *h;
|
||||||
|
let w = *w;
|
||||||
|
(0..h).for_each(|y| {
|
||||||
|
(0..w).for_each(|x| {
|
||||||
|
if map[y][x] == 0 {
|
||||||
|
queue.push_back(((x, y), (x, y)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
while !queue.is_empty() {
|
||||||
|
let (begin, (x, y)) = queue.pop_front().unwrap();
|
||||||
|
let val = map[y][x];
|
||||||
|
if val == 9 {
|
||||||
|
paths.insert((begin, (x, y)));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if x > 0 && map[y][x - 1] == val + 1 {
|
||||||
|
queue.push_back((begin, (x - 1, y)));
|
||||||
|
}
|
||||||
|
if x < h - 1 && map[y][x + 1] == val + 1 {
|
||||||
|
queue.push_back((begin, (x + 1, y)));
|
||||||
|
}
|
||||||
|
if y > 0 && map[y - 1][x] == val + 1 {
|
||||||
|
queue.push_back((begin, (x, y - 1)));
|
||||||
|
}
|
||||||
|
if y < h - 1 && map[y + 1][x] == val + 1 {
|
||||||
|
queue.push_back((begin, (x, y + 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paths.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day10, part2)]
|
||||||
|
fn part2(input: &Input) -> u64 {
|
||||||
|
let mut queue = VecDeque::new();
|
||||||
|
let mut starts = Vec::new();
|
||||||
|
let (w, h, map) = input;
|
||||||
|
let h = *h;
|
||||||
|
let w = *w;
|
||||||
|
(0..h).for_each(|y| {
|
||||||
|
(0..w).for_each(|x| {
|
||||||
|
if map[y][x] == 0 {
|
||||||
|
starts.push((x, y));
|
||||||
|
} else if map[y][x] == 9 {
|
||||||
|
queue.push_back((x, y));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut sum = 0;
|
||||||
|
|
||||||
|
while !queue.is_empty() {
|
||||||
|
let (x, y) = queue.pop_front().unwrap();
|
||||||
|
let val = map[y][x];
|
||||||
|
if val == 0 {
|
||||||
|
sum += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if x > 0 && map[y][x - 1] == val - 1 {
|
||||||
|
queue.push_back((x - 1, y));
|
||||||
|
}
|
||||||
|
if x < h - 1 && map[y][x + 1] == val - 1 {
|
||||||
|
queue.push_back((x + 1, y));
|
||||||
|
}
|
||||||
|
if y > 0 && map[y - 1][x] == val - 1 {
|
||||||
|
queue.push_back((x, y - 1));
|
||||||
|
}
|
||||||
|
if y < h - 1 && map[y + 1][x] == val - 1 {
|
||||||
|
queue.push_back((x, y + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sum
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_example() {
|
||||||
|
assert_eq!(part1(&parse("0123\n1234\n8765\n9876")), 1);
|
||||||
|
assert_eq!(
|
||||||
|
part1(&parse(
|
||||||
|
"89010123\n78121874\n87430965\n96549874\n45678903\n32019012\n01329801\n10456732"
|
||||||
|
)),
|
||||||
|
36
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_example() {
|
||||||
|
assert_eq!(
|
||||||
|
part2(&parse(
|
||||||
|
";;;;;0;\n;;4321;\n;;5;;2;\n;;6543;\n;;7;;4;\n;;8765;\n;;9;;;;"
|
||||||
|
)),
|
||||||
|
3
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
part2(&parse(
|
||||||
|
"89010123\n78121874\n87430965\n96549874\n45678903\n32019012\n01329801\n10456732"
|
||||||
|
)),
|
||||||
|
81
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
use hashbrown::{hash_map::Entry, HashMap};
|
||||||
|
use nom::{
|
||||||
|
character::complete::{space1, u64 as parse_usize},
|
||||||
|
error::Error,
|
||||||
|
multi::separated_list1,
|
||||||
|
};
|
||||||
|
use rayon::prelude::*;
|
||||||
|
|
||||||
|
type Input = Vec<usize>;
|
||||||
|
|
||||||
|
#[aoc_generator(day11)]
|
||||||
|
fn parse(input: &str) -> Input {
|
||||||
|
separated_list1(space1::<&str, Error<&str>>, parse_usize)(input)
|
||||||
|
.unwrap()
|
||||||
|
.1
|
||||||
|
.into_iter()
|
||||||
|
.map(|v| v as usize)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day11, part1)]
|
||||||
|
fn part1(input: &Input) -> usize {
|
||||||
|
blink(25, input.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day11, part2)]
|
||||||
|
fn part2(input: &Input) -> usize {
|
||||||
|
blink(75, input.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn blink(blinks: usize, input: Vec<usize>) -> usize {
|
||||||
|
let mut stones = HashMap::new();
|
||||||
|
for stone in input {
|
||||||
|
*stones.entry(stone).or_insert(0) += 1;
|
||||||
|
}
|
||||||
|
for _ in 0..blinks {
|
||||||
|
stones = single_blink(stones);
|
||||||
|
}
|
||||||
|
stones.values().sum::<usize>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn single_blink(stones: HashMap<usize, usize>) -> HashMap<usize, usize> {
|
||||||
|
let mut new_stones = HashMap::with_capacity(2 << 12);
|
||||||
|
|
||||||
|
for (stone, count) in stones {
|
||||||
|
if stone == 0 {
|
||||||
|
*new_stones.entry(1).or_insert(0) += count;
|
||||||
|
} else {
|
||||||
|
let digits = stone.ilog10() + 1;
|
||||||
|
if digits % 2 == 0 {
|
||||||
|
let left = stone / 10usize.pow(digits / 2);
|
||||||
|
let right = stone % 10usize.pow(digits / 2);
|
||||||
|
*new_stones.entry(left).or_insert(0) += count;
|
||||||
|
*new_stones.entry(right).or_insert(0) += count;
|
||||||
|
} else {
|
||||||
|
*new_stones.entry(stone * 2024).or_insert(0) += count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new_stones
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_example() {
|
||||||
|
assert_eq!(
|
||||||
|
part1(&parse(include_str!("../input/2024/day11.txt").trim_end())),
|
||||||
|
203609
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_example() {
|
||||||
|
assert_eq!(
|
||||||
|
part2(&parse(include_str!("../input/2024/day11.txt").trim_end())),
|
||||||
|
240954878211138
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
mod day1;
|
mod day1;
|
||||||
|
mod day10;
|
||||||
|
mod day11;
|
||||||
mod day2;
|
mod day2;
|
||||||
mod day3;
|
mod day3;
|
||||||
mod day4;
|
mod day4;
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
|
||||||
|
type Input = ();
|
||||||
|
|
||||||
|
#[aoc_generator(day)]
|
||||||
|
fn parse(input: &str) -> Input {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day, part1)]
|
||||||
|
fn part1(input: &Input) -> usize {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[aoc(day, part2)]
|
||||||
|
// fn part2(input: &Input) -> usize {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_example() {
|
||||||
|
assert_eq!(part1(&parse("<EXAMPLE>")), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
// fn part2_example() {
|
||||||
|
// assert_eq!(part2(&parse("<EXAMPLE>")), 0);
|
||||||
|
// }
|
||||||
|
}
|
Loading…
Reference in New Issue