Advent of Code 2022 - Day 03
Day 03
The algorithm for this challenge is pretty straightforward:
- Parse the input into list of string
- Split each string in the middle
- Find the letter that occurs in both string
- Convert the letter to a number using the provided method
- Sum the numbers
This algorithm works for the first part, and needs a little change to solve the second part.
1(defn to-lines
2 "Splits the input into lines"
3 [s]
4 (string/split s #"\n *"))
5
6(defn split-middle
7 "Split a string in the middle"
8 [s]
9 (let [length (count s)
10 midpoint (quot length 2)
11 front (subs s 0 midpoint)
12 back (subs s midpoint length)]
13 [front back]))
14
15(defn appears-in-all
16 "Find a letter common to all strings"
17 [strings]
18 (first (apply set/intersection (map set strings))))
19
20(def priority (zipmap
21 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
22 (range 1 53)))
To find a common letter I converted strings into sets that contain only one occurance of each letter. Next I used
clojure.set/intersetion to find all the letters that are in both sets. Then with first I get the first one.
For converting a letter into a number I simply created a map that maps a letter into its value.
Part 1
For solving the first part we just need to combine all the functions we created and sum the result
1(defn part1
2 [s]
3 (->> (to-lines s)
4 (map split-middle)
5 (map appears-in-all)
6 (map priority)
7 (apply +)))
Part 2
For the second part instead of splitting in the middle we need to take triplets of lines and do the same procedure on them
1(defn part2
2 [s]
3 (->> (to-lines s)
4 (partition 3)
5 (map appears-in-all)
6 (map priority)
7 (apply +)))