Solve 07
This commit is contained in:
parent
53e172f9c6
commit
2759b7e1f6
1 changed files with 95 additions and 0 deletions
95
src/bin/07.rs
Normal file
95
src/bin/07.rs
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
use aoc::*;
|
||||
use cached::{proc_macro::cached, stores::UnboundCache};
|
||||
use std::collections::HashSet;
|
||||
|
||||
const INPUT: &str = include_str!("../../input/07");
|
||||
|
||||
fn main() {
|
||||
println!("Part 1: {}", part1(INPUT));
|
||||
println!("Part 2: {}", part2(INPUT));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example() {
|
||||
assert_example!(part1, "07-test", 21);
|
||||
assert_example!(part2, "07-test", 40);
|
||||
}
|
||||
|
||||
fn part1(input: &str) -> usize {
|
||||
let (start, splitters) = parse_input(input);
|
||||
|
||||
let mut sum = 0;
|
||||
let mut beams = HashSet::from([start]);
|
||||
|
||||
for splitters in splitters {
|
||||
let (count, new) = split_count(&splitters, beams);
|
||||
beams = new;
|
||||
sum += count;
|
||||
}
|
||||
|
||||
sum
|
||||
}
|
||||
|
||||
fn part2(input: &str) -> usize {
|
||||
let (start, splitters) = parse_input(input);
|
||||
timelines(start, 0, &splitters)
|
||||
}
|
||||
|
||||
fn split_count(splitters: &HashSet<i32>, beams: HashSet<i32>) -> (usize, HashSet<i32>) {
|
||||
let mut result = HashSet::new();
|
||||
let mut count = 0;
|
||||
|
||||
for beam in beams {
|
||||
if splitters.contains(&beam) {
|
||||
result.insert(beam + 1);
|
||||
result.insert(beam - 1);
|
||||
count += 1;
|
||||
} else {
|
||||
result.insert(beam);
|
||||
}
|
||||
}
|
||||
|
||||
(count, result)
|
||||
}
|
||||
|
||||
#[cached(
|
||||
type = "UnboundCache<(i32, usize), usize>",
|
||||
create = "{ UnboundCache::new() }",
|
||||
convert = r#"{ (beam, depth) }"#
|
||||
)]
|
||||
fn timelines(beam: i32, depth: usize, splitters: &[HashSet<i32>]) -> usize {
|
||||
if depth >= splitters.len() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let splitter = &splitters[depth];
|
||||
|
||||
if splitter.contains(&beam) {
|
||||
timelines(beam - 1, depth + 1, splitters) + timelines(beam + 1, depth + 1, splitters)
|
||||
} else {
|
||||
timelines(beam, depth + 1, splitters)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns (start, lines of splitter positions)
|
||||
fn parse_input(input: &str) -> (i32, Vec<HashSet<i32>>) {
|
||||
let mut lines = input.lines();
|
||||
|
||||
let first_line = lines.next().unwrap();
|
||||
let start = first_line.chars().position(|c| c == 'S').unwrap() as i32;
|
||||
|
||||
let splitters = lines
|
||||
.map(parse_line)
|
||||
.filter(|line| !line.is_empty())
|
||||
.collect();
|
||||
|
||||
(start, splitters)
|
||||
}
|
||||
|
||||
fn parse_line(line: &str) -> HashSet<i32> {
|
||||
line.chars()
|
||||
.enumerate()
|
||||
.filter(|&(_, c)| c == '^')
|
||||
.map(|(i, _)| i as i32)
|
||||
.collect()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue