2016-12-09 Advent of Code in Clojure

I have had even less time for Advent of Code these days and I have fallen behind. Sadness! And yet, I wanted to try something new. A while ago I bought two Clojure books, *The Joy of Clojure* and *Practical Clojure*. And then I didn’t read them and it never went far. These simple coding exercises seem like a good opportunity to dig up these small half forgotten attempts at learning a language.

Advent of Code

Clojure it is! And I did suffer. Immutable data structures and no idea of how to do stuff, it was bad. But the miracle of Google, StackExchange and ClojureDocs allowed me to quickly get going.

Part 1: Given a list of input strings, find the solution which consists of the most common letter in each position. With the following input, the solution would be “alex”.

aeex
alrx
blet

Part 2: Given the same input, find the solution which consists of the *least* common letters. With the input above, the solution would be “bert”.

(ns day06.core
  (:gen-class)
  (:use [clojure.string :only [split join]])
  (:use [clojure.pprint :only [pprint]]))

(defn make-hashes
  [letters]
  (apply vector (map (fn [c] {}) letters)))

(defn read-lines
  []
  (map (fn [s] (split s #""))
       (line-seq (java.io.BufferedReader. *in*))))

(defn process-line
  [line hashes]
  (loop [[c & rest] line
         hashes hashes
         i 0]
    (if c
      (recur rest
             (update-in hashes [i c] (fn [v] (if v (+ v 1) 1)))
             (+ i 1))
      hashes)))

(defn process
  ([lines] (process lines (make-hashes (first lines))))
  ([lines hashes]
   (if hashes
     (let [line (first lines)]
       (if line
         (recur (rest lines)
                (process-line line hashes))
         hashes)))))

(defn result
  [hashes]
  (println "Most common letters: "
           (join (map (fn [hash]
                        (first (first (sort-by val > hash))))
                      hashes)))
  (println "Least common letters:"
           (join (map (fn [hash]
                        (first (last (sort-by val > hash))))
                      hashes))))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (result (process (read-lines))))

Run the example using `lein run < data`.

I even found the time to write some tests for the code on GitHub.

on GitHub

Since I haven’t written any Clojure code in ages, I’d love to heard about improvements or style issues!

​#Clojure ​#Advent of Code ​#Programming

Comments

(Please contact me if you want to remove your comment.)

I guess I should get rid of pprint.

– AlexSchroeder 2016-12-09 13:50 UTC