|
1 | 1 | (ns advent-of-code.utils
|
2 | 2 | (:require [clojure.string :as str]
|
3 |
| - [clojure.java.io :as io])) |
| 3 | + [clojure.java.io :as io]) |
| 4 | + (:import (java.security MessageDigest) |
| 5 | + (java.math BigInteger))) |
4 | 6 |
|
5 | 7 | (defn read-input
|
6 | 8 | "Read in the content of the given day-file and return as a blob"
|
|
29 | 31 | [line]
|
30 | 32 | (map parse-long (re-seq #"[-+]?\d+" line)))
|
31 | 33 |
|
| 34 | +(defn parse-ranges |
| 35 | + "Parse each string of input as a range in the form 'M-N'" |
| 36 | + [ranges] |
| 37 | + (->> ranges |
| 38 | + (map #(str/replace % "-" " ")) |
| 39 | + (map parse-out-longs))) |
| 40 | + |
| 41 | +(defn manhattan-dist |
| 42 | + "Calculate the Manhattan Distance between two points." |
| 43 | + [p1 p2] |
| 44 | + (+ (abs (- (first p1) (first p2))) |
| 45 | + (abs (- (last p1) (last p2))))) |
| 46 | + |
| 47 | +(defn first-duplicate |
| 48 | + "Find first element of collection that is a duplicate" |
| 49 | + [coll] |
| 50 | + (reduce (fn [acc elt] |
| 51 | + (if (get acc elt) |
| 52 | + (reduced elt) |
| 53 | + (assoc acc elt true))) |
| 54 | + {} coll)) |
| 55 | + |
32 | 56 | ;; Like the core time macro, but rather than printing the elapsed time it
|
33 | 57 | ;; returns a list of (result, time). Returned value is in milliseconds.
|
34 | 58 | (defmacro time-it [expr]
|
|
73 | 97 | (defn factorize
|
74 | 98 | "Determine all prime factors of n"
|
75 | 99 | [n]
|
76 |
| - (loop [x n [p & ps] primes factors []] |
| 100 | + (loop [x n, [p & ps] primes, factors []] |
77 | 101 | (cond
|
78 | 102 | (= 1 x) factors
|
79 | 103 | (zero? (mod x p)) (recur (/ x p) primes (conj factors p))
|
|
94 | 118 | ([] 1)
|
95 | 119 | ([x] x)
|
96 | 120 | ([a b] (/ (* a b) (gcd a b))))
|
| 121 | + |
| 122 | +;; Taken from https://gist.github.com/jizhang/4325757?permalink_comment_id=2196746#gistcomment-2196746 |
| 123 | +(defn md5 [^String s] |
| 124 | + (let [algorithm (MessageDigest/getInstance "MD5") |
| 125 | + raw (.digest algorithm (.getBytes s))] |
| 126 | + (format "%032x" (BigInteger. 1 raw)))) |
| 127 | + |
| 128 | +(defn create-field |
| 129 | + "Create a NxM field as a matrix (vector of vectors). Fill with `with` or nil" |
| 130 | + [N M & [with]] |
| 131 | + (if (or (seq? with) (vector? with)) |
| 132 | + ;; Ignore N/M and treat each element of `with` as a row in the field |
| 133 | + (mapv vec with) |
| 134 | + ;; Otherwise, use the value of `with` itself (which may be nil) |
| 135 | + (vec (repeat M (vec (repeat N with)))))) |
| 136 | + |
| 137 | +(defn display |
| 138 | + "Display a matrix of characters, as if on a terminal or similar" |
| 139 | + [lines] |
| 140 | + (println (str/join "\n" (map #(str/join %) lines)))) |
0 commit comments