Solving Problems in Clojure

Just a few little functional adventures.

October 14, 2021

What follows are little mini problems I solved in order to finished Day 2, 2018 of The Advent of Code.

Problem 1

Identify strings that have n instances of any character.


  1. abcdef has no repeated characters.
  2. abcdee has 2 e.


  1. Sort the input
  2. Partition the input by character
  3. Remove the partitions of incorrect length
  4. Are any partitions remaining?
(defn has-n-repeats? [n input]
  (as-> (sort input) $
        (partition-by char $)
        (filter #(= n (count %)) $)
        (not (empty? $))))

Problem 2

Count differences at corresponding positions between two strings.


  1. abcde and fghij differ at all five locations.
  2. fghij and fguij differ at one location.

Naive Solution: use set operations (union, intersection) to see how different the strings are.

Advanced Case:

  1. xrecqmdonskvzupalfkwhjctdb and xrlgqmavnskvzupalfiwhjctdb differ at five positions


In the advanced case, both strings have repeated characters, so sets aren't helpful.


  1. Interleave the two strings
  2. Partition the interleaved strings in character pairs
  3. remove pairs that are equal
  4. count the remaining pairs

Data Flow for fghij and fguij:

  1. (f f g g h u i i j j)
  2. ((f f) (g g) (h u) (i i) (j j))
  3. ((h u))
  4. 1

Implentation 1:

(->> (interleave a b)
     (partition 2)
     (remove #(= (first %) (second %)))

Implementation 2:

(->> (interleave a b)
     (partition 2)
     (remove #(apply = %))

Implementation 3:

(def equal? (partial apply =))

(->> (interleave a b)
     (partition 2)
     (remove equal?)

Problem 3:

List characters that are equal at corresponding positions between two strings (preserving order of appearance).


  1. fghij and fguij share fgij.


  1. Interleave the two strings
  2. Partition the interleaved strings in character pairs
  3. filter for pairs that are equal
  4. take the first of each pair
  5. concatenate a string
(defn common-chars [a b]
  (->> (interleave a b)
       (partition 2)
       (filter equal?)
       (map first)
       (apply str)))

Problem 4:

Among a list of strings, find the two that differ by one character at a single character position and return the common characters.


  1. List comprehension of the diff-count between every combination of strings
  2. Limit result where diff-count result is 1
  3. Return the common-chars of that combination.
(defn common-between-diff-by-one [inputs]
    (for [x inputs
          y inputs
          :when (= (diff-count x y) 1)]
      (common-chars x y))))

-Michael Whatcott