-
-
Save vanadium23/92208a48533a7c70100d74de257d3a55 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns advent-of-code.day05 | |
(:require [clojure.string :as str] | |
[clojure.java.io :as io] | |
[clojure.math.combinatorics :as combo])) | |
(defn read-input [file] | |
(str/trim (slurp file))) | |
(defn to-blocks | |
"Turn a blob (probably from `slurp`) into a seq of blocks" | |
[input] | |
(str/split input #"\n\n")) | |
(defn parse-out-longs | |
"Parse out all numbers in `line` that are integers (longs)" | |
[line] | |
(vec (map parse-long (re-seq #"[-+]?\d+" line)))) | |
(defn to-lines | |
"Turn a blob or block into a seq of lines" | |
[input] | |
(str/split-lines input)) | |
(defn parse-line | |
"Parse a line into a seq of strings" | |
[line] | |
(vec (map parse-long (str/split line #"\|")))) | |
(defn index-of [v n] | |
(first (keep-indexed (fn [i x] (when (= x n) i)) v))) | |
(defn apply-rule [nums [less great]] (let [less-index (index-of nums less) | |
great-index (index-of nums great)] | |
(if (and less-index great-index) | |
(if (< less-index great-index) true false) | |
true))) | |
(defn is-correct-nums [nums rules] (every? true? (map #(apply-rule nums %) rules))) | |
(defn middle-index [v] | |
(if (empty? v) | |
nil | |
(quot (count v) 2))) | |
(defn middle-value [v] | |
(when (seq v) | |
(nth v (middle-index v)))) | |
(defn part1 [input] (let [blocks (to-blocks input) | |
lines (to-lines (first blocks)) | |
parsed (map parse-line lines) | |
nums (map parse-out-longs (to-lines (second blocks))) | |
correct-nums (filter #(is-correct-nums % parsed) nums)] | |
(reduce + (map middle-value correct-nums)))) | |
;; brute force approach (21! permutations) | |
(defn correct-order [nums rules] | |
(let [combos (combo/permutations nums)] | |
(first (filter #(is-correct-nums % rules) combos)))) | |
(defn swap-by-values [vec [val1 val2]] | |
(let [idx1 (.indexOf vec val1) | |
idx2 (.indexOf vec val2)] | |
(if (and (not= idx1 -1) (not= idx2 -1)) | |
(-> vec | |
(assoc idx1 val2) | |
(assoc idx2 val1)) | |
vec))) | |
;; swap by values until right | |
(defn correct-order-optimized [nums rules] ( | |
loop [acc nums] | |
(if (is-correct-nums acc rules) | |
acc | |
(recur (swap-by-values acc (first (filter #(not (apply-rule acc %)) rules)))) | |
) | |
)) | |
(defn part2 [input] (let [blocks (to-blocks input) | |
lines (to-lines (first blocks)) | |
parsed (map parse-line lines) | |
nums (map parse-out-longs (to-lines (second blocks))) | |
incorrect-nums (filter #(not (is-correct-nums % parsed)) nums)] | |
(reduce + (map middle-value (map #(correct-order-optimized % parsed) incorrect-nums))))) | |
(def answer1example (part1 (read-input "05-example.txt"))) | |
(assert (= answer1example 143) answer1example) | |
(def answer1 (part1 (read-input "05.txt"))) | |
(assert (= answer1 5762) answer1) | |
(def answer2example (part2 (read-input "05-example.txt"))) | |
(assert (= answer2example 123) answer2example) | |
(def answer2 (part2 (read-input "05.txt"))) | |
(assert (= answer2 0) answer2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment