# 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.

Cases:

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

Solution:

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.

Cases:

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.

1. `xrecqmdonskvzupalfkwhjctdb` and `xrlgqmavnskvzupalfiwhjctdb` differ at five positions

Solution:

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

Description:

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 %)))
(count))
``````

Implementation 2:

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

Implementation 3:

``````(def equal? (partial apply =))

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

### Problem 3:

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

Cases:

1. `fghij` and `fguij` share `fgij`.

Solution:

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.

Solution:

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]
(first
(for [x inputs
y inputs
:when (= (diff-count x y) 1)]
(common-chars x y))))
``````

-Michael Whatcott