Compare commits
36 Commits
37c2786336
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 56738fd7f9 | |||
|
|
b89c7ce3f2 | ||
|
|
a1db8ae128 | ||
|
|
e6357d9802 | ||
| b62c9346f5 | |||
| 505453974b | |||
| 0aed472a32 | |||
|
|
9703c017a9 | ||
|
|
733c833f66 | ||
| 1087a7649b | |||
| 5077215205 | |||
|
|
8ff632503f | ||
|
|
a889d088ae | ||
|
|
484e507af1 | ||
| 7057247936 | |||
| 52e2bf8202 | |||
| 0616318a09 | |||
| e851c41935 | |||
|
|
5a1773ca77 | ||
| db1a89199b | |||
| e51b3296d6 | |||
| 14ac947ae3 | |||
| 8fa11862e1 | |||
| d55ca4c019 | |||
| f88a28cad2 | |||
| d04209497b | |||
| 9ea11f35c9 | |||
| 50e6464eba | |||
| 56a1bed93d | |||
| d379c21296 | |||
| a2492b2b2a | |||
| d2e6f920f3 | |||
| aae7ad038b | |||
| 5ca7f15404 | |||
| c47c11a973 | |||
| 055a37a089 |
@@ -17,3 +17,6 @@ target/
|
||||
.cpcache
|
||||
.calva
|
||||
.nrepl-port
|
||||
|
||||
## intellij nonsense
|
||||
.idea
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
input/
|
||||
.lein-repl-history
|
||||
.idea/
|
||||
*.iml
|
||||
@@ -0,0 +1,15 @@
|
||||
(defproject org.ajet/advent-of-code "0.0.0-SNAPSHOT"
|
||||
:description "my 2017 advent of code solutions in clojure"
|
||||
:url "http://github.com/ajetski/advent-of-code"
|
||||
:min-lein-version "2.0.0"
|
||||
:jvm-opts ["-Xmx16g"]
|
||||
:plugins [[cider/cider-nrepl "0.57.0"]]
|
||||
:dependencies [[org.clojure/clojure "1.12.0"]
|
||||
[org.clojure/data.priority-map "1.2.0"]
|
||||
[org.clojure/math.combinatorics "0.3.0"]
|
||||
[babashka/fs "0.5.23"]
|
||||
[org.babashka/http-client "0.4.22"]
|
||||
[org.clojure/core.match "1.1.0"]
|
||||
[clj-python/libpython-clj "2.025"]
|
||||
[tools.aqua/z3-turnkey "4.14.1"]]
|
||||
:source-paths ["src" "../shared/clj/src"])
|
||||
@@ -0,0 +1,23 @@
|
||||
(ns day01
|
||||
(:require input-manager))
|
||||
|
||||
(defn to-digit [c] (Character/digit c 10))
|
||||
|
||||
(def input (mapv to-digit (input-manager/get-input-raw 2017 01)))
|
||||
|
||||
(defn solve [offset]
|
||||
(let [lookup (fn [idx]
|
||||
(input (mod idx (count input))))]
|
||||
(->> input
|
||||
(map-indexed vector)
|
||||
(filter (fn [[idx el]]
|
||||
(= el (lookup (+ offset idx)))))
|
||||
(map second)
|
||||
(apply +))))
|
||||
|
||||
;; part 1
|
||||
(solve 1)
|
||||
|
||||
;; part 2
|
||||
(solve (/ (count input) 2))
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
(ns day02
|
||||
(:require input-manager
|
||||
core))
|
||||
|
||||
(def input (mapv (comp #(mapv parse-long %)
|
||||
core/split-whitespace)
|
||||
(input-manager/get-input 2017 02)))
|
||||
|
||||
;; part 1
|
||||
(->> input
|
||||
(map (comp #(apply - %)
|
||||
(juxt #(apply max %)
|
||||
#(apply min %))))
|
||||
(apply +))
|
||||
|
||||
(defn find-divisible [l]
|
||||
(or (first
|
||||
(for [a (range (count l))
|
||||
b (range (count l))
|
||||
:when (and (not= a b)
|
||||
(= (mod (l a) (l b)) 0))]
|
||||
(/ (l a) (l b))))
|
||||
0))
|
||||
|
||||
(apply + (map find-divisible input))
|
||||
@@ -0,0 +1,18 @@
|
||||
(ns day04
|
||||
(:require input-manager
|
||||
core))
|
||||
|
||||
(def input (map core/split-whitespace (input-manager/get-input 2017 04)))
|
||||
|
||||
;; part 1
|
||||
(->> input
|
||||
(filter #(= (count %)
|
||||
(count (into #{} %))))
|
||||
count)
|
||||
|
||||
;; part 2
|
||||
(->> input
|
||||
(filter #(= (count (into #{} (map frequencies %)))
|
||||
(count %)))
|
||||
count)
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
(ns day05
|
||||
(:require input-manager))
|
||||
|
||||
(def input (->> (input-manager/get-input 2017 5)
|
||||
(mapv parse-long)))
|
||||
|
||||
(def MAX_IDX (count input))
|
||||
|
||||
;; part 1
|
||||
(loop [steps 0
|
||||
maze input
|
||||
idx 0]
|
||||
(let [maze' (update maze idx inc)
|
||||
idx' (+ (maze idx) idx)]
|
||||
(if (< -1 idx' MAX_IDX)
|
||||
(recur (inc steps) maze' idx')
|
||||
(inc steps))))
|
||||
|
||||
;; part 2
|
||||
(loop [steps 0
|
||||
maze input
|
||||
idx 0]
|
||||
(let [offset (maze idx)
|
||||
maze' (update maze idx (if (>= offset 3)
|
||||
dec
|
||||
inc))
|
||||
idx' (+ offset idx)]
|
||||
(if (< -1 idx' MAX_IDX)
|
||||
(recur (inc steps) maze' idx')
|
||||
(inc steps))))
|
||||
@@ -0,0 +1,26 @@
|
||||
(ns day06
|
||||
(:require [input-manager]
|
||||
[core :refer [split-whitespace]]))
|
||||
|
||||
(def input
|
||||
(->> (input-manager/get-input-raw 2017 6)
|
||||
split-whitespace
|
||||
(mapv parse-long)))
|
||||
|
||||
(loop [state input
|
||||
i 0
|
||||
seen {}]
|
||||
(if (contains? seen state)
|
||||
{:part-one i
|
||||
:part-two (- i (seen state))}
|
||||
(let [cnt (apply max state)
|
||||
idx (->> state
|
||||
(map-indexed vector)
|
||||
(filter #(= (second %) cnt))
|
||||
ffirst)]
|
||||
(recur (->> (range cnt)
|
||||
(map #(mod (+ idx 1 %) (count state)))
|
||||
(reduce #(update %1 %2 inc) (assoc state idx 0)))
|
||||
(inc i)
|
||||
(assoc seen state i)))))
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
(ns day07
|
||||
(:require
|
||||
[clojure.string :as str]
|
||||
[core :refer [split-whitespace]]
|
||||
[input-manager]))
|
||||
|
||||
(def input
|
||||
(->> (input-manager/get-input-raw 2017 7)
|
||||
str/split-lines
|
||||
(map (comp split-whitespace
|
||||
#(str/replace % #"," "")))))
|
||||
|
||||
;; part 1
|
||||
(def base-node
|
||||
(->> input
|
||||
(filter (fn [[_ _ _ & children]] children))
|
||||
(filter (fn [[node]]
|
||||
(empty? (filter (fn [[_ _ _ & children]]
|
||||
(some #(= % node) children))
|
||||
input))))
|
||||
ffirst))
|
||||
|
||||
(do
|
||||
(def get-depth
|
||||
(memoize (fn [node]
|
||||
(let [[_ w-str _ & children] (first (filter (fn [[n]] (= node n))
|
||||
input))
|
||||
w (parse-long (subs w-str 1 (dec (count w-str))))]
|
||||
(apply + w (map get-depth children))))))
|
||||
(def get-weight
|
||||
(memoize (fn [node]
|
||||
(let [w-str (->> input
|
||||
(filter (fn [[n]] (= node n)))
|
||||
first
|
||||
second)]
|
||||
(parse-long (subs w-str 1 (dec (count w-str))))))))
|
||||
(def get-children
|
||||
(memoize (fn [node] (->> input
|
||||
(filter (fn [[n]] (= node n)))
|
||||
first
|
||||
(drop 3))))))
|
||||
|
||||
(defn get-children-data [node]
|
||||
(map (juxt identity get-depth get-weight) (get-children node)))
|
||||
|
||||
(defn get-counts [data]
|
||||
(->> data
|
||||
(map second)
|
||||
frequencies
|
||||
(sort-by second)))
|
||||
|
||||
;; part 2
|
||||
(let [[bad-parent bad-node]
|
||||
(loop [parent nil
|
||||
node base-node]
|
||||
(let [data (get-children-data node)
|
||||
counts (get-counts data)
|
||||
row (first (filter #(= (second %) (ffirst counts)) data))]
|
||||
(if (= (count counts) 1)
|
||||
[parent node]
|
||||
(recur node (first row)))))
|
||||
diff (->> bad-parent
|
||||
get-children-data
|
||||
get-counts
|
||||
(map first)
|
||||
(apply -))]
|
||||
(- (get-weight bad-node) diff))
|
||||
@@ -0,0 +1,46 @@
|
||||
(ns day08
|
||||
(:require
|
||||
[clojure.string :as str]
|
||||
[core]
|
||||
[input-manager]))
|
||||
|
||||
(def op {"inc" +
|
||||
"dec" -})
|
||||
(def cond-op {"<" <
|
||||
"<=" <=
|
||||
">" >
|
||||
">=" >=
|
||||
"==" =
|
||||
"!=" not=})
|
||||
(def input (map (comp
|
||||
(fn [[name operation num _ cond-name cond-operation cond-val]]
|
||||
[name
|
||||
(op operation)
|
||||
(parse-long num)
|
||||
cond-name
|
||||
(cond-op cond-operation)
|
||||
(parse-long cond-val)])
|
||||
core/split-whitespace)
|
||||
(input-manager/get-input 2017 8)))
|
||||
|
||||
(defn compute [acc [reg reg-op val cond-reg cond-op cond-val]]
|
||||
(if (cond-op (acc cond-reg 0) cond-val)
|
||||
(assoc acc reg (reg-op (acc reg 0) val))
|
||||
acc))
|
||||
|
||||
;; part 1
|
||||
(->> input
|
||||
(reduce compute {})
|
||||
(sort-by second)
|
||||
last
|
||||
second)
|
||||
|
||||
;; part 2
|
||||
(->> input
|
||||
(reductions compute {})
|
||||
(mapcat identity)
|
||||
set
|
||||
(sort-by second)
|
||||
last
|
||||
second)
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
(ns day09
|
||||
(:require [clojure.string :as str]
|
||||
core
|
||||
input-manager))
|
||||
|
||||
(def input (input-manager/get-input-raw 2017 9))
|
||||
|
||||
(defn sum-recursive-depths [s sum idx depth]
|
||||
(if (>= idx (count s))
|
||||
sum
|
||||
(condp = (.charAt s idx)
|
||||
\, (recur s sum (inc idx) depth)
|
||||
\{ (recur s
|
||||
(+ sum depth)
|
||||
(inc idx)
|
||||
(inc depth))
|
||||
\} (recur s
|
||||
sum
|
||||
(inc idx)
|
||||
(max (dec depth) 0)))))
|
||||
|
||||
(defn exlam-canceler [s] (str/replace s #"!." ""))
|
||||
(def angle-bracket-regex #"<[^>]*>")
|
||||
|
||||
(-> input
|
||||
exlam-canceler
|
||||
(str/replace angle-bracket-regex "")
|
||||
(sum-recursive-depths 0 0 1))
|
||||
|
||||
(->> input
|
||||
exlam-canceler
|
||||
(re-seq angle-bracket-regex)
|
||||
(map #(- (count %) 2))
|
||||
(reduce +))
|
||||
@@ -0,0 +1,27 @@
|
||||
(ns day11
|
||||
(:require [core]
|
||||
input-manager
|
||||
[clojure.string :as str]))
|
||||
|
||||
(def input (-> (input-manager/get-input-raw 2017 11)
|
||||
(str/split #",")))
|
||||
|
||||
(def offsets {"n" [0 1]
|
||||
"ne" [0.5 0.5]
|
||||
"se" [0.5 -0.5]
|
||||
"s" [0 -1]
|
||||
"sw" [-0.5 -0.5]
|
||||
"nw" [-0.5 0.5]})
|
||||
|
||||
(defn distance-from-origin [pos]
|
||||
(let [[x y] (map abs pos)]
|
||||
(+ (* x 2) (- y x))))
|
||||
|
||||
|
||||
(->> input
|
||||
(map offsets)
|
||||
(reductions #(map + %1 %2) [0 0])
|
||||
(map distance-from-origin)
|
||||
((juxt last (partial apply max)))
|
||||
(zipmap [:part-one :part-two]))
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
(ns day12
|
||||
(:require
|
||||
[clojure.string :as str]
|
||||
core
|
||||
input-manager
|
||||
[clojure.set :refer [difference]]))
|
||||
|
||||
(def input (->> (input-manager/get-input 2017 12)
|
||||
(map #(str/replace % #"," ""))
|
||||
(map core/split-whitespace)
|
||||
(map (fn [[a _ & rst]]
|
||||
[(parse-long a) (mapv parse-long rst)]))
|
||||
(into {})))
|
||||
|
||||
(defn group-from-start [start]
|
||||
(loop [visited #{}
|
||||
queue [start]]
|
||||
(if-not (seq queue)
|
||||
visited
|
||||
(let [[curr & rst] queue
|
||||
ns (filter (complement visited) (input curr))]
|
||||
(recur (into visited ns)
|
||||
(concat rst ns))))))
|
||||
|
||||
;; part one
|
||||
(count (group-from-start 0))
|
||||
|
||||
;; part two
|
||||
(loop [ks (into #{} (keys input))
|
||||
i 0]
|
||||
(if-not (seq ks)
|
||||
i
|
||||
(recur (difference ks (group-from-start (first ks)))
|
||||
(inc i))))
|
||||
@@ -0,0 +1,58 @@
|
||||
(ns day13
|
||||
(:require
|
||||
[clojure.string :as str]
|
||||
[core]
|
||||
[input-manager]))
|
||||
|
||||
(def lengths (->> (input-manager/get-input 2017 13)
|
||||
(map (comp #(mapv parse-long %)
|
||||
#(str/split % #": ")))
|
||||
(into {})))
|
||||
|
||||
(defn move-sensor [{:keys [idx depth increasing-depth] :as sensor}]
|
||||
(let [[keep-moving reverse-step] (if increasing-depth [inc dec] [dec inc])
|
||||
depth' (keep-moving depth)]
|
||||
(if (or (> depth' (dec (lengths idx)))
|
||||
(< depth' 0))
|
||||
(-> sensor
|
||||
(update :depth reverse-step)
|
||||
(update :increasing-depth not))
|
||||
(assoc sensor :depth depth'))))
|
||||
|
||||
(def initial-sensors (->> lengths
|
||||
keys
|
||||
(map #(hash-map :depth 0
|
||||
:idx %
|
||||
:increasing-depth true))))
|
||||
|
||||
(defn is-spotted-by-sensors [acc pos]
|
||||
(some #(when (and (= (:idx %) pos)
|
||||
(= (:depth %) 0))
|
||||
%)
|
||||
(:sensors acc)))
|
||||
|
||||
(->> lengths keys (apply max) inc range
|
||||
(reduce (fn [acc pos]
|
||||
(let [spotted (is-spotted-by-sensors acc pos)]
|
||||
(-> acc
|
||||
(update :sensors (partial map move-sensor))
|
||||
(update :solution + (if spotted
|
||||
(* pos (lengths pos))
|
||||
0)))))
|
||||
{:sensors initial-sensors
|
||||
:solution 0})
|
||||
:solution)
|
||||
|
||||
(loop [i 0
|
||||
start-val initial-sensors]
|
||||
(if
|
||||
(= true
|
||||
(->> lengths keys (apply max) inc range
|
||||
(reduce (fn [acc pos]
|
||||
(let [spotted (is-spotted-by-sensors acc pos)]
|
||||
(if spotted
|
||||
(reduced true)
|
||||
(update acc :sensors (partial map move-sensor)))))
|
||||
{:sensors start-val})))
|
||||
(recur (inc i) (map move-sensor start-val))
|
||||
i))
|
||||
@@ -0,0 +1,11 @@
|
||||
(ns user
|
||||
(:require
|
||||
[clojure.pprint :as pprint]))
|
||||
|
||||
(defonce printer (bound-fn* pprint/pprint))
|
||||
(add-tap printer)
|
||||
|
||||
(comment
|
||||
;; tap debugging
|
||||
(remove-tap printer))
|
||||
|
||||
+19
-25
@@ -1,37 +1,31 @@
|
||||
(ns day03
|
||||
(:require [core :as c]
|
||||
[input-manager :refer [get-input]]
|
||||
(:require [input-manager]
|
||||
[clojure.string :as str]))
|
||||
|
||||
(def input (str/join (get-input 3)))
|
||||
(def input (input-manager/get-input-raw 2024 3))
|
||||
|
||||
(defn parse-muls
|
||||
"takes in a string containing mul instructions
|
||||
returns list of parsed integral multiplication results"
|
||||
[s]
|
||||
(->> (c/get-match-groups #"mul\((\d{1,3}),(\d{1,3})\)" s)
|
||||
(map #(map parse-long %))
|
||||
(map #(reduce * %))))
|
||||
(defn compute-muls [s]
|
||||
(map (comp #(reduce * %)
|
||||
#(map parse-long %)
|
||||
#(str/split % #",")
|
||||
#(subs % 4 (dec (count %)))) ;; remove `mul(` prefix and `)` suffix
|
||||
s))
|
||||
|
||||
(defn enforce-toggles [[el & rst]]
|
||||
(cond (= el "do()") (recur rst)
|
||||
(= el "don't()") (recur (drop-while #(not= % "do()") rst))
|
||||
el (conj (lazy-seq (enforce-toggles rst)) el)))
|
||||
|
||||
;; part 1
|
||||
(->> input
|
||||
parse-muls
|
||||
(re-seq #"mul\(\d{1,3},\d{1,3}\)")
|
||||
compute-muls
|
||||
(reduce +))
|
||||
|
||||
;; part 2
|
||||
(->> input
|
||||
(c/re-pos #"mul\((\d{1,3}),(\d{1,3})\)|(do\(\))|(don't\(\))")
|
||||
(sort-by key)
|
||||
(reduce
|
||||
(fn [acc [_idx instr]]
|
||||
(cond
|
||||
(.startsWith instr "mul") (if (:on acc)
|
||||
(update acc :val
|
||||
+ (->> instr parse-muls first))
|
||||
acc)
|
||||
(.startsWith instr "don't") (assoc acc :on false)
|
||||
(.startsWith instr "do") (assoc acc :on true)))
|
||||
{:on true
|
||||
:val 0})
|
||||
:val)
|
||||
(re-seq #"mul\(\d{1,3},\d{1,3}\)|do\(\)|don't\(\)")
|
||||
enforce-toggles
|
||||
compute-muls
|
||||
(reduce +))
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
input/
|
||||
.lein-repl-history
|
||||
.idea/
|
||||
*.iml
|
||||
+4
-2
@@ -9,5 +9,7 @@
|
||||
[org.clojure/math.combinatorics "0.3.0"]
|
||||
[babashka/fs "0.5.23"]
|
||||
[org.babashka/http-client "0.4.22"]
|
||||
[org.clojure/core.match "1.1.0"]]
|
||||
:source-paths ["src" "../shared/clj/src"])
|
||||
[org.clojure/core.match "1.1.0"]
|
||||
[clj-python/libpython-clj "2.025"]
|
||||
[tools.aqua/z3-turnkey "4.14.1"]]
|
||||
:source-paths ["src" "../shared/clj/src"])
|
||||
|
||||
+27
-32
@@ -1,56 +1,51 @@
|
||||
(ns day09
|
||||
(:require input-manager))
|
||||
(:require [input-manager]))
|
||||
|
||||
(def input (->> (input-manager/get-input 2025 9)
|
||||
(mapv #(mapv parse-long (re-seq #"\d+" %)))))
|
||||
|
||||
(defn area [[ax ay] [bx by]]
|
||||
(* (inc (abs (- ax bx)))
|
||||
(inc (abs (- ay by)))))
|
||||
(def furthest-points
|
||||
(->> (for [a input
|
||||
b input
|
||||
:when (not= a b)]
|
||||
#{a b})
|
||||
distinct
|
||||
(map vec)
|
||||
(sort-by #(apply area %))))
|
||||
|
||||
(def largest-rects (->> (for [a input
|
||||
b input
|
||||
:when (not= a b)]
|
||||
#{a b})
|
||||
distinct
|
||||
(map vec)
|
||||
(sort-by #(apply area %))))
|
||||
;; part 1
|
||||
(->> furthest-points
|
||||
(->> largest-rects
|
||||
last
|
||||
(apply area))
|
||||
|
||||
(defn normalize [x] (min 1 (max -1 x)))
|
||||
(defn orientation
|
||||
"returns a value indicating if point A is to the left, right, or on the line BC"
|
||||
"returns a value indicating if point B is to the left, right, or on the line AC"
|
||||
[[ax ay] [bx by] [cx cy]]
|
||||
(normalize (- (* (- by ay) (- cx bx))
|
||||
(* (- bx ax) (- cy by)))))
|
||||
|
||||
(defn intersect?
|
||||
"Lines AB and CD intersect if points A and B falls on different sides of CD
|
||||
and if C and D fall on different sides of AB"
|
||||
[[a b] [c d]]
|
||||
(let [o1 (orientation a b c)
|
||||
o2 (orientation a b d)
|
||||
o3 (orientation c d a)
|
||||
o4 (orientation c d b)]
|
||||
(let [o1 (orientation a c b)
|
||||
o2 (orientation a d b)
|
||||
o3 (orientation c a d)
|
||||
o4 (orientation c b d)]
|
||||
(and (not= o1 o2) (not= o3 o4))))
|
||||
(def line-segments (map vector input (rest input)))
|
||||
|
||||
;; part 2
|
||||
(def line-segments (map vector input (conj (vec (rest input)) (first input))))
|
||||
(->> furthest-points
|
||||
(filter (fn [[a b]]
|
||||
(let [segments (filter (fn [[seg-a seg-b]] (and (not= a seg-a)
|
||||
(not= a seg-b)
|
||||
(not= b seg-a)
|
||||
(not= b seg-b)))
|
||||
(->> largest-rects
|
||||
(filter (fn [[a b :as rect]]
|
||||
(let [segments (filter (fn overlapping? [[c d]]
|
||||
(and (not= a c) (not= a d)
|
||||
(not= b c) (not= b d))) ;; filter out segments that include points a or b
|
||||
line-segments)
|
||||
[[cx cy] [dx dy]] [a b]]
|
||||
(and (not (some #(intersect? [a b] %) segments))
|
||||
(not (some #(intersect? [[cx dy] [dx cy]] %) segments))))))
|
||||
(sort-by (partial apply area))
|
||||
last
|
||||
(apply area))
|
||||
|
||||
[[cx cy] [dx dy]] rect
|
||||
reverse-diag [[cx dy] [dx cy]]]
|
||||
(and (not (some #(intersect? rect %) segments))
|
||||
(not (some #(intersect? reverse-diag %) segments))))))
|
||||
(map (partial apply area))
|
||||
sort
|
||||
last)
|
||||
@@ -0,0 +1,71 @@
|
||||
(ns day10
|
||||
(:require [clojure.math.combinatorics :as combo]
|
||||
[input-manager])
|
||||
(:import (com.microsoft.z3 Context Expr IntNum Optimize Optimize$Handle)))
|
||||
|
||||
(defn parse-line [line]
|
||||
{:indicators (->> line
|
||||
(drop 1)
|
||||
(take-while (complement #{\]}))
|
||||
(mapv (partial = \#)))
|
||||
:buttons (->> line
|
||||
(re-seq #"\([\d,]+\)")
|
||||
(map #(map parse-long (re-seq #"\d+" %))))
|
||||
:joltages (->> line
|
||||
(drop-while #(not= % \{))
|
||||
(drop 1)
|
||||
(take-while #(not= % \}))
|
||||
(apply str)
|
||||
(re-seq #"\d+")
|
||||
(mapv parse-long))})
|
||||
|
||||
(def input (map parse-line (input-manager/get-input 2025 10)))
|
||||
|
||||
(defn minimum-button-mashing [{:keys [buttons indicators]}]
|
||||
(loop [i 0
|
||||
cnt 1]
|
||||
(if (>= i (combo/count-combinations buttons cnt))
|
||||
(recur 0 (inc cnt))
|
||||
(let [indicators' (reduce (partial reduce #(update %1 %2 not))
|
||||
indicators
|
||||
(combo/nth-combination buttons cnt i))]
|
||||
(if (every? (complement identity) indicators')
|
||||
cnt
|
||||
(recur (inc i) cnt))))))
|
||||
|
||||
;; part 1
|
||||
(apply + (map minimum-button-mashing input))
|
||||
|
||||
;; part 2
|
||||
(defn add-expressions [opt expressions]
|
||||
(.Add opt (into-array Expr expressions)))
|
||||
|
||||
(->> input
|
||||
(map (fn [{:keys [joltages buttons]}]
|
||||
(let [ctx (Context.)
|
||||
^Optimize opt (.mkOptimize ctx)
|
||||
bs (->> buttons
|
||||
count
|
||||
range
|
||||
(map #(.mkIntConst ctx (str "b" %))))
|
||||
js (->> joltages
|
||||
count
|
||||
range
|
||||
(map #(.mkIntConst ctx (str "j" %))))]
|
||||
(add-expressions opt (for [idx (range (count joltages))]
|
||||
(.mkEq ctx (nth js idx) (->> buttons
|
||||
(map set)
|
||||
(map-indexed vector)
|
||||
(filter #(contains? (second %) idx))
|
||||
(map first)
|
||||
(map #(nth bs %))
|
||||
(into-array Expr)
|
||||
(.mkAdd ctx)))))
|
||||
(add-expressions opt (for [[idx joltage] (map-indexed vector joltages)]
|
||||
(.mkEq ctx (nth js idx) (.mkInt ctx (long joltage)))))
|
||||
(add-expressions opt (for [b bs]
|
||||
(.mkGe ctx b (.mkInt ctx (long 0)))))
|
||||
(let [^Optimize$Handle mx (.MkMinimize opt (.mkAdd ctx (into-array Expr bs)))]
|
||||
(.Check opt (into-array Expr []))
|
||||
(.getInt ^IntNum (.getValue mx))))))
|
||||
(apply +))
|
||||
@@ -0,0 +1,21 @@
|
||||
(ns day11
|
||||
(:require [input-manager]))
|
||||
|
||||
(def input (->> (input-manager/get-input 2025 11)
|
||||
(map (comp (fn [[node & edges]]
|
||||
[node (into #{} edges)])
|
||||
(partial re-seq #"[a-z]{3}")))
|
||||
(into {})))
|
||||
|
||||
(def count-paths (memoize (fn [start target]
|
||||
(let [edges (input start)]
|
||||
(if (contains? edges target)
|
||||
1
|
||||
(apply + (map #(count-paths % target) edges)))))))
|
||||
|
||||
;; part 1
|
||||
(count-paths "you" "out")
|
||||
|
||||
;; part 2
|
||||
(+ (* (count-paths "svr" "dac") (count-paths "dac" "fft") (count-paths "fft" "out"))
|
||||
(* (count-paths "svr" "fft") (count-paths "fft" "dac") (count-paths "dac" "out")))
|
||||
@@ -0,0 +1,84 @@
|
||||
(ns day12
|
||||
(:require input-manager
|
||||
core
|
||||
[clojure.string :as str]
|
||||
clojure.set))
|
||||
|
||||
(def requirements (->> (input-manager/get-input-raw 2025 12)
|
||||
(core/split-on-double-newlines)
|
||||
(map str/split-lines)
|
||||
last
|
||||
(map (comp (fn [[x y & cnts]]
|
||||
[[x y] (into {} (map-indexed vector cnts))])
|
||||
(partial map parse-long)
|
||||
(partial re-seq #"\d+")))))
|
||||
|
||||
(defn fits-trivially?
|
||||
"is it trivially possible to fit all the pieces if they were 3x3 blocks instead of jigsaws"
|
||||
[[dimensions cnts]]
|
||||
(let [area (apply * dimensions)
|
||||
guess (->> cnts vals (reduce +) (* 9))]
|
||||
(>= area guess)))
|
||||
|
||||
;; part 1
|
||||
(->> requirements
|
||||
(filter fits-trivially?)
|
||||
count)
|
||||
|
||||
(comment
|
||||
;; NP Hard... general solution is not fast enough
|
||||
(defn flip [grid]
|
||||
(vec (reverse grid)))
|
||||
(defn rotations [grid]
|
||||
(->> [(for [x (range 0 3)]
|
||||
(for [y (range 0 3)]
|
||||
(.charAt (grid x) y)))
|
||||
(for [y (range 2 -1 -1)]
|
||||
(for [x (range 0 3)]
|
||||
(.charAt (grid x) y)))
|
||||
(for [x (range 2 -1 -1)]
|
||||
(for [y (range 2 -1 -1)]
|
||||
(.charAt (grid x) y)))
|
||||
(for [y (range 2 -1 -1)]
|
||||
(for [x (range 3)]
|
||||
(.charAt (grid x) y)))]
|
||||
(map (partial map-indexed (fn [row-idx row]
|
||||
(map-indexed (fn [col-idx cell]
|
||||
(when (= cell \#)
|
||||
[row-idx col-idx]))
|
||||
row))))
|
||||
(map (partial mapcat (partial filter identity)))
|
||||
(mapv (partial mapv vec))
|
||||
set))
|
||||
|
||||
#_(def jigsaws (->> (drop-last (->> (input-manager/get-input-raw 2025 12)
|
||||
(core/split-on-double-newlines)
|
||||
(map str/split-lines)))
|
||||
(map (fn [[idx & puzzle-lines]]
|
||||
[(parse-long (apply str (drop-last idx)))
|
||||
(clojure.set/union (rotations (vec puzzle-lines)) (rotations (flip puzzle-lines)))]))
|
||||
(into {})))
|
||||
(defn placeable? [jigsaw filled]
|
||||
(every? #(not (contains? filled %)) jigsaw))
|
||||
|
||||
(defn offset [loc jigsaw]
|
||||
(into #{} (map #(mapv + % loc) jigsaw)))
|
||||
|
||||
(defn fits? [[[rows cols :as dimensions] cnts] jigsaws filled]
|
||||
(cond
|
||||
(every? (partial = 0) (vals cnts)) true
|
||||
:else
|
||||
(let [[id] (first (filter (fn [[_ cnt]] (> cnt 0)) cnts))
|
||||
orientations (jigsaws id)
|
||||
locs (for [row (range (- rows 2))
|
||||
col (range (- cols 2))]
|
||||
[row col])
|
||||
cnts' (update cnts id dec)]
|
||||
(some (fn [loc]
|
||||
(->> orientations
|
||||
(map #(offset loc %))
|
||||
(filter #(placeable? % filled))
|
||||
(map #(fits? [dimensions cnts'] jigsaws (clojure.set/union filled %)))
|
||||
(filter identity)
|
||||
first))
|
||||
locs)))))
|
||||
@@ -0,0 +1,11 @@
|
||||
(ns user
|
||||
(:require
|
||||
[clojure.pprint :as pprint]))
|
||||
|
||||
(defonce printer (bound-fn* pprint/pprint))
|
||||
(add-tap printer)
|
||||
|
||||
(comment
|
||||
;; tap debugging
|
||||
(remove-tap printer))
|
||||
|
||||
Reference in New Issue
Block a user