-
Notifications
You must be signed in to change notification settings - Fork 0
/
day_04.clj
53 lines (45 loc) · 2.1 KB
/
day_04.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
(ns day_04
(:require [clojure.string :as str]
[utils :refer [open-resource parse-int split-by-comma split-whitespace transpose]]))
(def input-file "day_04.txt")
(def data (let [lines (->> input-file open-resource)]
{:numbers (->> lines
first
split-by-comma
(map parse-int))
:boards (->> lines
rest
(remove str/blank?)
(map #(->> %
str/trim
split-whitespace
(map parse-int)))
(partition 5))}))
(defn all-marked? [v] (every? #(= "x" %) v))
(defn replace-number [v x] (map (fn [y] (map #(if (= % x) "x" %) y)) v))
(defn mark-number [v x] (map #(replace-number % x) v))
(defn winning-board? [b] (let [transposed (transpose b)]
(or
(some #(all-marked? %) b)
(some #(all-marked? %) transposed))))
(defn sum-remaining [b] (->> b flatten (remove #(= "x" %)) (reduce +)))
(defn part-01 [input]
(loop [boards (:boards input) numbers (:numbers input)]
(let [[current-number & remaining-numbers] numbers
updated-boards (mark-number boards current-number)
winning-boards (filter winning-board? updated-boards)]
(if (empty? winning-boards)
(recur updated-boards remaining-numbers)
(* (sum-remaining winning-boards) current-number)))))
(defn part-02 [input]
(loop [boards (:boards input) numbers (:numbers input)]
(let [[current-number & remaining-numbers] numbers
updated-boards (mark-number boards current-number)
boards-yet-to-win (remove winning-board? updated-boards)]
(if (empty? boards-yet-to-win)
(* (sum-remaining updated-boards) current-number)
(recur boards-yet-to-win remaining-numbers)))))
(defn -main [& _]
(println "Day 04:")
(println "\t-> Part 1: " (part-01 data))
(println "\t-> Part 2: " (part-02 data)))