Initial commit
This commit is contained in:
commit
2c4abe0078
|
@ -0,0 +1,20 @@
|
||||||
|
pom.xml
|
||||||
|
pom.xml.asc
|
||||||
|
*.jar
|
||||||
|
*.class
|
||||||
|
**/lib/
|
||||||
|
**/classes/
|
||||||
|
**/target/
|
||||||
|
**/checkouts/
|
||||||
|
.lein-deps-sum
|
||||||
|
.lein-repl-history
|
||||||
|
.lein-plugins/
|
||||||
|
.lein-failures
|
||||||
|
.nrepl-port
|
||||||
|
.cpcache/
|
||||||
|
|
||||||
|
**/.clj-kondo/
|
||||||
|
**/.calva
|
||||||
|
input.*
|
||||||
|
sample.*
|
||||||
|
output.*
|
|
@ -0,0 +1,13 @@
|
||||||
|
/target
|
||||||
|
/classes
|
||||||
|
/checkouts
|
||||||
|
profiles.clj
|
||||||
|
pom.xml
|
||||||
|
pom.xml.asc
|
||||||
|
*.jar
|
||||||
|
*.class
|
||||||
|
/.lein-*
|
||||||
|
/.nrepl-port
|
||||||
|
/.prepl-port
|
||||||
|
.hgignore
|
||||||
|
.hg/
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,9 @@
|
||||||
|
(defproject day-one "0.1.0-SNAPSHOT"
|
||||||
|
:description "FIXME: write description"
|
||||||
|
:url "http://example.com/FIXME"
|
||||||
|
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
|
||||||
|
:url "https://www.eclipse.org/legal/epl-2.0/"}
|
||||||
|
:dependencies [[org.clojure/clojure "1.11.1"]]
|
||||||
|
:repl-options {:init-ns day-one.core}
|
||||||
|
:main day-one.core/-main
|
||||||
|
:plugins [[cider/cider-nrepl "0.42.1"]])
|
|
@ -0,0 +1,50 @@
|
||||||
|
(ns day-one.core
|
||||||
|
(:require
|
||||||
|
[clojure.string :as str]))
|
||||||
|
|
||||||
|
(defn no-text-digits
|
||||||
|
"Convert text digits to number digits"
|
||||||
|
[text]
|
||||||
|
[text
|
||||||
|
(-> text
|
||||||
|
(str/replace "one" "o1e")
|
||||||
|
(str/replace "two" "t2o")
|
||||||
|
(str/replace "three" "t3e")
|
||||||
|
(str/replace "four" "f4r")
|
||||||
|
(str/replace "five" "f5e")
|
||||||
|
(str/replace "six" "s6x")
|
||||||
|
(str/replace "seven" "s7n")
|
||||||
|
(str/replace "eight" "e8t")
|
||||||
|
(str/replace "nine" "n9e")
|
||||||
|
(str/replace "zero" "z0o"))])
|
||||||
|
|
||||||
|
(defn digits-from-regex
|
||||||
|
[match first-digit last-digit & {:keys [debug]}]
|
||||||
|
(let [num (Integer. (str first-digit last-digit))]
|
||||||
|
(when debug (printf "%-50s\t%d\n" match num))
|
||||||
|
num))
|
||||||
|
|
||||||
|
(defn parse-digits
|
||||||
|
"Parse the first and last digit of a line and combine them"
|
||||||
|
[[orig new] & {:keys [debug]}]
|
||||||
|
(if-some [[match first last] (re-matches #"^\D*?(\d).*(\d)\D*?$" new)]
|
||||||
|
(do (when debug (printf "%-50s\t" orig))
|
||||||
|
(digits-from-regex match first last
|
||||||
|
:debug debug))
|
||||||
|
(if-some [[match only] (re-matches #"^\D*?(\d)\D*$" new)]
|
||||||
|
(do (when debug (printf "%-50s\t" orig))
|
||||||
|
(digits-from-regex match only only
|
||||||
|
:debug debug))
|
||||||
|
0)))
|
||||||
|
|
||||||
|
(defn -main []
|
||||||
|
(as-> "input.txt" data
|
||||||
|
(slurp data)
|
||||||
|
(str/split data #"\n")
|
||||||
|
|
||||||
|
(map no-text-digits data)
|
||||||
|
|
||||||
|
(map #(parse-digits % :debug true) data)
|
||||||
|
(reduce + data)
|
||||||
|
(printf "----------\n%d\n" data)))
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
/target
|
||||||
|
/classes
|
||||||
|
/checkouts
|
||||||
|
profiles.clj
|
||||||
|
pom.xml
|
||||||
|
pom.xml.asc
|
||||||
|
*.jar
|
||||||
|
*.class
|
||||||
|
/.lein-*
|
||||||
|
/.nrepl-port
|
||||||
|
/.prepl-port
|
||||||
|
.hgignore
|
||||||
|
.hg/
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,9 @@
|
||||||
|
(defproject day-two "0.1.0-SNAPSHOT"
|
||||||
|
:description "FIXME: write description"
|
||||||
|
:url "http://example.com/FIXME"
|
||||||
|
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
|
||||||
|
:url "https://www.eclipse.org/legal/epl-2.0/"}
|
||||||
|
:main day-two.core/-main
|
||||||
|
:dependencies [[org.clojure/clojure "1.11.1"]]
|
||||||
|
:repl-options {:init-ns day-two.core}
|
||||||
|
:plugins [[cider/cider-nrepl "0.42.1"]])
|
|
@ -0,0 +1,82 @@
|
||||||
|
(ns day-two.core
|
||||||
|
(:require
|
||||||
|
[clojure.string :as str]))
|
||||||
|
|
||||||
|
(defn parse-subset
|
||||||
|
[subset]
|
||||||
|
(let [[_ nums colour] (re-matches #"(\d+)\s*(\w+)" subset)]
|
||||||
|
(list (Integer. nums) colour)))
|
||||||
|
|
||||||
|
(defn- to-hashmap
|
||||||
|
[xs]
|
||||||
|
(let [base (reduce (fn [m [k v]] (assoc m (keyword v) k)) {} xs)
|
||||||
|
with-red (if (:red base) base (assoc base :red 0))
|
||||||
|
with-green (if (:green with-red) with-red (assoc with-red :green 0))
|
||||||
|
with-blue (if (:blue with-green) with-green (assoc with-green :blue 0))]
|
||||||
|
with-blue))
|
||||||
|
|
||||||
|
(defn parse-sets
|
||||||
|
[[set & sets]]
|
||||||
|
(conj (if sets (parse-sets sets) (list))
|
||||||
|
(to-hashmap
|
||||||
|
(map parse-subset
|
||||||
|
(str/split set #", ")))))
|
||||||
|
|
||||||
|
(defn parse-game
|
||||||
|
"Parse a game line"
|
||||||
|
[text]
|
||||||
|
(let [[_ game-num sets]
|
||||||
|
(re-matches #"^Game (\d+):\s(.*)" text)]
|
||||||
|
(list (Integer. game-num) (parse-sets (str/split sets #"; ")))))
|
||||||
|
|
||||||
|
(defn parse-games [lines] (map parse-game (str/split lines #"\n")))
|
||||||
|
|
||||||
|
;;; PART 1
|
||||||
|
|
||||||
|
(def max-map {:red 12 :green 13 :blue 14})
|
||||||
|
|
||||||
|
(defn- valid-set?
|
||||||
|
"Given a map of keys and their max values, determine if the set is valid"
|
||||||
|
[maxes set]
|
||||||
|
(every? true? (list (<= (:red set) (:red maxes))
|
||||||
|
(<= (:green set) (:green maxes))
|
||||||
|
(<= (:blue set) (:blue maxes)))))
|
||||||
|
|
||||||
|
(defn- valid-game?
|
||||||
|
"Given a map of keys and their max values, determine if the game is valid"
|
||||||
|
[m [_ sets]]
|
||||||
|
(every? true?
|
||||||
|
(map #(valid-set? m %) sets)))
|
||||||
|
|
||||||
|
(defn- valid-game-id [[id _ :as game]] (if (valid-game? max-map game) id 0))
|
||||||
|
(defn- sum-games [games] (reduce + (map valid-game-id games)))
|
||||||
|
|
||||||
|
;;; PART 2
|
||||||
|
|
||||||
|
(defn- min-cubes
|
||||||
|
"Determine the minimum number of cubes of each colour for the game to be successful"
|
||||||
|
[xs]
|
||||||
|
(reduce (fn [prev cur]
|
||||||
|
{:red (max (:red prev) (:red cur))
|
||||||
|
:green (max (:green prev) (:green cur))
|
||||||
|
:blue (max (:blue prev) (:blue cur))})
|
||||||
|
{:red 0 :green 0 :blue 0}
|
||||||
|
xs))
|
||||||
|
|
||||||
|
(defn- rgb-map-to-list [m] (list (:red m) (:green m) (:blue m)))
|
||||||
|
|
||||||
|
(defn- game-cube-power
|
||||||
|
"Get the power of the minimum cubes"
|
||||||
|
[[_ xs]]
|
||||||
|
(reduce * (->> xs
|
||||||
|
(min-cubes)
|
||||||
|
(rgb-map-to-list))))
|
||||||
|
|
||||||
|
(defn- sum-games-power [games] (reduce + (map game-cube-power games)))
|
||||||
|
|
||||||
|
(defn -main
|
||||||
|
"Main entry point of the program"
|
||||||
|
[]
|
||||||
|
(let [games (parse-games (slurp "input.txt"))]
|
||||||
|
(printf "Sum of valid game IDs: %s\n" (sum-games games))
|
||||||
|
(printf "Sum of cube powers: %s\n" (sum-games-power games))))
|
Loading…
Reference in New Issue