Skip to content

Commit 187ca22

Browse files
committed
2024/19
1 parent f53642b commit 187ca22

File tree

8 files changed

+522
-15
lines changed

8 files changed

+522
-15
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
![rust v1.83](https://shields.io/badge/rust-1.82-blue?logo=rust)
44
![build](https://img.shields.io/github/actions/workflow/status/tbali0524/advent-of-code-rust/qa.yml)
5-
![AoC stars](https://img.shields.io/badge/total%20AoC%20⭐-204-green)
5+
![AoC stars](https://img.shields.io/badge/total%20AoC%20⭐-206-green)
66
![license](https://img.shields.io/github/license/tbali0524/advent-of-code-rust)
77

88
* [AoC website](https://adventofcode.com/)

input/2024/Aoc2024Day19.txt

Lines changed: 402 additions & 0 deletions
Large diffs are not rendered by default.

input/2024/Aoc2024Day19ex1.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
r, wr, b, g, bwu, rb, gb, br
2+
3+
brwrr
4+
bggr
5+
gbbr
6+
rrbgbr
7+
ubwu
8+
bwurrg
9+
brgr
10+
bbrgwb

puzzles.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
|[2021](#2021)|![-](https://img.shields.io/badge/stars%20⭐-2-red) |
1414
|[2022](#2022)|![-](https://img.shields.io/badge/stars%20⭐-2-red) |
1515
|[2023](#2023)|![-](https://img.shields.io/badge/stars%20⭐-50-green) |
16-
|[2024](#2024)|![-](https://img.shields.io/badge/stars%20⭐-36-yellow) |
17-
|__Total__ |![total](https://img.shields.io/badge/stars%20⭐-204-green) |
16+
|[2024](#2024)|![-](https://img.shields.io/badge/stars%20⭐-38-yellow) |
17+
|__Total__ |![total](https://img.shields.io/badge/stars%20⭐-206-green) |
1818

1919
## Puzzles
2020

@@ -328,7 +328,7 @@ Hint from `subreddit` was used for Day 12 part 2, Day 24 part 2 and Day 25.
328328
| + |2024| 16|Reindeer Maze |Dijkstra, priority queue |
329329
| + |2024| 17|Chronospatial Computer |assembly simulation, reverse engineering |
330330
| + |2024| 18|RAM Run |BFS |
331-
| - |2024| 19| | |
331+
| + |2024| 19|Linen Layout |BinaryHeap |
332332
| - |2024| 20| | |
333333
| - |2024| 21| | |
334334
| - |2024| 22| | |

results.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,13 @@ Advent of Code - solutions in Rust, (c) 2024 by TBali
697697
[ OK ] Puzzle part #1 : 322
698698
[ OK ] Puzzle part #2 : 60,21
699699
700-
=================== [Total time: 10287 ms] : [11 seasons, 102 puzzles, 144 examples]
700+
=== AoC 2024 Day 19 ===== [time: 8 ms] : Linen Layout
701+
[ OK ] Example #1 part #1 : 6
702+
[ OK ] Example #1 part #2 : 16
703+
[ OK ] Puzzle part #1 : 247
704+
[ OK ] Puzzle part #2 : 692596560138745
705+
706+
=================== [Total time: 9709 ms] : [10 seasons, 103 puzzles, 145 examples]
701707
702708
[ OK ] All tests passed.
703709
```

src/aoc2024.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub mod aoc2024day15;
1818
pub mod aoc2024day16;
1919
pub mod aoc2024day17;
2020
pub mod aoc2024day18;
21-
// pub mod aoc2024day19;
21+
pub mod aoc2024day19;
2222
// pub mod aoc2024day20;
2323
// pub mod aoc2024day21;
2424
// pub mod aoc2024day22;
@@ -46,7 +46,7 @@ pub const PUZZLES: crate::aoc::Season = [
4646
Some((aoc2024day16::metadata, aoc2024day16::solve)),
4747
Some((aoc2024day17::metadata, aoc2024day17::solve)),
4848
Some((aoc2024day18::metadata, aoc2024day18::solve)),
49-
None, // Some((aoc2024day19::metadata, aoc2024day19::solve)),
49+
Some((aoc2024day19::metadata, aoc2024day19::solve)),
5050
None, // Some((aoc2024day20::metadata, aoc2024day20::solve)),
5151
None, // Some((aoc2024day21::metadata, aoc2024day21::solve)),
5252
None, // Some((aoc2024day22::metadata, aoc2024day22::solve)),

src/aoc2024/aoc2024day18.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,13 @@ pub fn solve(input: PuzzleInput) -> PuzzleResult {
5252
for &byte in bytes.iter().take(max_bytes) {
5353
has_byte.insert(byte);
5454
}
55-
let ans1 = if let Some(step) = bfs(&has_byte, max_x, max_y) {
56-
step
57-
} else {
58-
0
59-
};
55+
let ans1 = bfs(&has_byte, max_x, max_y).unwrap_or_default();
6056
// ---------- Part 2
6157
let mut ans2 = "0".to_string();
62-
for i in max_bytes..bytes.len() {
63-
has_byte.insert(bytes[i]);
58+
for &byte in bytes.iter().skip(max_bytes) {
59+
has_byte.insert(byte);
6460
if bfs(&has_byte, max_x, max_y).is_none() {
65-
ans2 = format!("{},{}", bytes[i].0, bytes[i].1).to_string();
61+
ans2 = format!("{},{}", byte.0, byte.1).to_string();
6662
break;
6763
}
6864
}

src/aoc2024/aoc2024day19.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//! [aoc](https://adventofcode.com/2024/day/19)
2+
3+
use crate::aoc::{PuzzleInput, PuzzleMetaData, PuzzleResult};
4+
use core::cmp::Reverse;
5+
use std::cmp::min;
6+
use std::collections::{BinaryHeap, HashMap, HashSet};
7+
8+
pub fn metadata() -> PuzzleMetaData<'static> {
9+
PuzzleMetaData {
10+
year: 2024,
11+
day: 19,
12+
title: "Linen Layout",
13+
solution: ("247", "692596560138745"),
14+
example_solutions: vec![("6", "16")],
15+
}
16+
}
17+
18+
type ItemType = i64;
19+
20+
pub fn solve(input: PuzzleInput) -> PuzzleResult {
21+
// ---------- Parse and Check input
22+
if input.len() < 3 || !input[1].is_empty() {
23+
Err("patterns and designs must be separated by an empty line")?;
24+
}
25+
let patterns = input[0].split(", ").collect::<Vec<_>>();
26+
let max_pattern = patterns.iter().map(|&x| x.len()).max().unwrap();
27+
let designs = &input[2..];
28+
// ---------- Part 1 + 2
29+
let mut lookup = HashSet::new();
30+
for &pattern in &patterns {
31+
lookup.insert(pattern.to_owned());
32+
}
33+
let mut ans1 = 0;
34+
let mut ans2 = 0;
35+
for &design in designs {
36+
let mut found_sol = false;
37+
let mut has_partial = HashMap::<usize, ItemType>::new();
38+
let mut q = BinaryHeap::new();
39+
has_partial.insert(0, 1);
40+
q.push(Reverse(0));
41+
while let Some(Reverse(pos)) = q.pop() {
42+
let prev_sols = *has_partial.get(&pos).unwrap_or(&1);
43+
if pos == design.len() {
44+
if !found_sol {
45+
ans1 += 1;
46+
found_sol = true;
47+
}
48+
ans2 += *has_partial.get(&pos).unwrap_or(&1);
49+
continue;
50+
}
51+
let max_to_pos = min(design.len(), pos + max_pattern);
52+
for to_pos in (pos + 1)..=max_to_pos {
53+
if !lookup.contains(&design[pos..to_pos]) {
54+
continue;
55+
}
56+
if !has_partial.contains_key(&to_pos) {
57+
q.push(Reverse(to_pos));
58+
}
59+
has_partial
60+
.entry(to_pos)
61+
.and_modify(|counter| *counter += prev_sols)
62+
.or_insert(prev_sols);
63+
}
64+
}
65+
}
66+
Ok((ans1.to_string(), ans2.to_string()))
67+
}
68+
69+
// ------------------------------------------------------------
70+
#[cfg(test)]
71+
mod tests {
72+
use super::*;
73+
use crate::aoc::runner::tests::*;
74+
75+
#[test]
76+
fn example1() {
77+
test_case(metadata, solve, 1);
78+
}
79+
80+
#[test]
81+
fn puzzle() {
82+
test_case(metadata, solve, 0);
83+
}
84+
85+
#[test]
86+
fn invalid_single_line() {
87+
test_invalid_msg(
88+
&[&"a, b", &"a", &"ab"],
89+
solve,
90+
"patterns and designs must be separated by an empty line",
91+
);
92+
}
93+
}

0 commit comments

Comments
 (0)