Advent of Code 2022 - Day 03

1 minute read

Day 03

The algorithm for this challenge is pretty straightforward:

  1. Parse the input into list of string
  2. Split each string in the middle
  3. Find the letter that occurs in both string
  4. Convert the letter to a number using the provided method
  5. 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 +)))