You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/2024/puzzles/day25.md
+74Lines changed: 74 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -2,10 +2,84 @@ import Solver from "../../../../../website/src/components/Solver.js"
2
2
3
3
# Day 25: Code Chronicle
4
4
5
+
by [@merlinorg](https://github.com/merlinorg)
6
+
5
7
## Puzzle description
6
8
7
9
https://adventofcode.com/2024/day/25
8
10
11
+
## Solution summary
12
+
13
+
1. Parse and partition the locks and keys.
14
+
2. Find all lock and key combinations that could fit.
15
+
3. Return the count of potential matches.
16
+
17
+
## Parsing
18
+
19
+
It's the last day of Advent of Code so we'll keep it simple. The input consists
20
+
of a sequence of grids, separated by blank lines. Each grid is a sequence of lines
21
+
consisting of the `#` and `.` characters. Locks have `#` characters in the first
22
+
row, where keys have `.` characters. To parse this we'll just use simple string
23
+
splitting.
24
+
25
+
First, we split the input into grids by matching on the blank lines. This gives us
26
+
an array of strings, each grid represented by a single string. Then we partition
27
+
this into two arrays; one the keys, and the other locks. For this, we use the
28
+
`partition` method that takes a predicate; every grid that matches this predicate
29
+
will be placed in the first array of the resulting tuple, the rest in the second.
30
+
31
+
```scala 3
32
+
val (locks, keys) = input.split("\n\n").partition(_.startsWith("#"))
33
+
```
34
+
35
+
In general, arrays are not the most ergonomic data structures to use, but for
36
+
this final puzzle they are more than sufficient.
37
+
38
+
## Matching
39
+
40
+
To find all potential matches we will use a for comprehension to loop through
41
+
all the locks, and then for each lock, through all the keys. For each pair of
42
+
a lock and key, we want to determine whether there is any overlap that would
43
+
prevent the key fitting the lock.
44
+
We can perform this test by simply zipping the key and the lock strings; this
45
+
gives us a collection of every corresponding character from each string. The
46
+
key can fit the lock if there is no location containing a `#` character in
47
+
both grids.
48
+
49
+
```scala 3
50
+
valmatches=for
51
+
lock <- locks
52
+
key <- keys
53
+
if lock.zip(key).forall: (lockChar, keyChar) =>
54
+
lockChar !='#'|| keyChar !='#'
55
+
yield lock -> key
56
+
```
57
+
58
+
This returns all of the matching lock and key combinations; the solution to
59
+
the puzzle is the size of this array.
60
+
61
+
## Final code
62
+
63
+
```scala 3
64
+
defpart1(input: String):Int=
65
+
val (locks, keys) = input.split("\n\n").partition(_.startsWith("#"))
66
+
67
+
valmatches=for
68
+
lock <- locks
69
+
key <- keys
70
+
if lock.zip(key).forall: (lockChar, keyChar) =>
71
+
lockChar !='#'|| keyChar !='#'
72
+
yield lock -> key
73
+
74
+
matches.length
75
+
```
76
+
77
+
### Run it in the browser
78
+
79
+
#### Part 1
80
+
81
+
<Solverpuzzle="day25-part1"year="2024"/>
82
+
9
83
## Solutions from the community
10
84
11
85
-[Solution](https://github.com/Philippus/adventofcode/blob/main/src/main/scala/adventofcode2024/Day25.scala) by [Philippus Baalman](https://github.com/philippus)
0 commit comments