Skip to content

Commit d696730

Browse files
committed
Day 19 solutions
1 parent 3669226 commit d696730

File tree

5 files changed

+519
-4
lines changed

5 files changed

+519
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,4 @@ This should start the server at `localhost:8080`.
104104
❄️ [Day 16](aoc-solver/src/y2024/day16.rs)
105105
❄️ [Day 17](aoc-solver/src/y2024/day17.rs)
106106
❄️ [Day 18](aoc-solver/src/y2024/day18.rs)
107+
❄️ [Day 19](aoc-solver/src/y2024/day19.rs)

aoc-solver/src/y2024/day19.rs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
use std::collections::HashMap;
2+
3+
use crate::solution::{AocError, Solution};
4+
5+
fn parse(input: &str) -> Result<(Vec<String>, Vec<String>), AocError> {
6+
let (towels, designs) = input
7+
.split_once("\n\n")
8+
.ok_or_else(|| AocError::parse(input, "Missing towel and designs sections"))?;
9+
10+
let towels: Vec<String> = towels.split(", ").map(|towel| towel.to_owned()).collect();
11+
let designs: Vec<String> = designs.lines().map(|towel| towel.to_owned()).collect();
12+
13+
Ok((towels, designs))
14+
}
15+
16+
fn count_possible(towels: &[String], design: &str, cache: &mut HashMap<String, usize>) -> usize {
17+
if design.is_empty() {
18+
return 1;
19+
}
20+
21+
if let Some(&count) = cache.get(design) {
22+
return count;
23+
}
24+
25+
let possible = towels
26+
.iter()
27+
.filter_map(|towel| design.strip_suffix(towel))
28+
.map(|remaining| count_possible(towels, remaining, cache))
29+
.sum();
30+
31+
cache.insert(design.to_owned(), possible);
32+
33+
possible
34+
}
35+
36+
pub struct Day19;
37+
impl Solution for Day19 {
38+
type A = usize;
39+
type B = usize;
40+
41+
fn default_input(&self) -> &'static str {
42+
include_str!("../../../inputs/2024/day19.txt")
43+
}
44+
45+
fn part_1(&self, input: &str) -> Result<usize, AocError> {
46+
let (towels, designs) = parse(input)?;
47+
48+
let mut cache = HashMap::new();
49+
let possible = designs
50+
.iter()
51+
.filter(|design| count_possible(&towels, design, &mut cache) > 0)
52+
.count();
53+
54+
Ok(possible)
55+
}
56+
57+
fn part_2(&self, input: &str) -> Result<usize, AocError> {
58+
let (towels, designs) = parse(input)?;
59+
60+
let mut cache = HashMap::new();
61+
let possible = designs
62+
.iter()
63+
.map(|design| count_possible(&towels, design, &mut cache))
64+
.sum();
65+
66+
Ok(possible)
67+
}
68+
}
69+
70+
#[cfg(test)]
71+
mod tests {
72+
use super::*;
73+
74+
#[test]
75+
fn it_solves_part1_example() {
76+
assert_eq!(
77+
Day19.part_1(
78+
"r, wr, b, g, bwu, rb, gb, br\n\
79+
\n\
80+
brwrr\n\
81+
bggr\n\
82+
gbbr\n\
83+
rrbgbr\n\
84+
ubwu\n\
85+
bwurrg\n\
86+
brgr\n\
87+
bbrgwb"
88+
),
89+
Ok(6)
90+
);
91+
}
92+
93+
#[test]
94+
fn it_solves_part2_example() {
95+
assert_eq!(
96+
Day19.part_2(
97+
"r, wr, b, g, bwu, rb, gb, br\n\
98+
\n\
99+
brwrr\n\
100+
bggr\n\
101+
gbbr\n\
102+
rrbgbr\n\
103+
ubwu\n\
104+
bwurrg\n\
105+
brgr\n\
106+
bbrgwb"
107+
),
108+
Ok(16)
109+
);
110+
}
111+
}

aoc-solver/src/y2024/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ pub mod day15;
1818
pub mod day16;
1919
pub mod day17;
2020
pub mod day18;
21-
// pub mod day19;
21+
pub mod day19;
2222
// pub mod day20;
2323
// pub mod day21;
2424
// pub mod day22;
2525
// pub mod day23;
2626
// pub mod day24;
2727
// pub mod day25;
2828

29-
pub const MAX_DAYS: u8 = 18;
29+
pub const MAX_DAYS: u8 = 19;
3030

3131
pub struct Y2024;
3232

@@ -51,7 +51,7 @@ impl Solver for Y2024 {
5151
16 => day16::Day16.run(input, 16, 2024),
5252
17 => day17::Day17.run(input, 17, 2024),
5353
18 => day18::Day18.run(input, 18, 2024),
54-
// 19 => day19::Day19.run(input, 19, 2024),
54+
19 => day19::Day19.run(input, 19, 2024),
5555
// 20 => day20::Day20.run(input, 20, 2024),
5656
// 21 => day21::Day21.run(input, 21, 2024),
5757
// 22 => day22::Day22.run(input, 22, 2024),
@@ -93,7 +93,7 @@ impl Solver for Y2024 {
9393
16 => include_str!("./day16.rs"),
9494
17 => include_str!("./day17.rs"),
9595
18 => include_str!("./day18.rs"),
96-
// 19 => include_str!("./day19.rs"),
96+
19 => include_str!("./day19.rs"),
9797
// 20 => include_str!("./day20.rs"),
9898
// 21 => include_str!("./day21.rs"),
9999
// 22 => include_str!("./day22.rs"),

aoc-web/src/header.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub fn header(props: &HeaderProps) -> Html {
3939
<NavLink route={Route::Solution { year: 2024, day: 16 }} current={props.route.clone()} text={"16"}/>
4040
<NavLink route={Route::Solution { year: 2024, day: 17 }} current={props.route.clone()} text={"17"}/>
4141
<NavLink route={Route::Solution { year: 2024, day: 18 }} current={props.route.clone()} text={"18"}/>
42+
<NavLink route={Route::Solution { year: 2024, day: 19 }} current={props.route.clone()} text={"19"}/>
4243
</>
4344
}
4445
},

0 commit comments

Comments
 (0)