Skip to content

Instantly share code, notes, and snippets.

@dosbol
Last active December 21, 2019 16:58
Show Gist options
  • Save dosbol/206c4755bd726c2ab626cb39f1cf0d3d to your computer and use it in GitHub Desktop.
Save dosbol/206c4755bd726c2ab626cb39f1cf0d3d to your computer and use it in GitHub Desktop.
advent-of-code-2019.clj
(defn solve1-1 [x]
(int (- (Math/floor (/ x 3)) 2)))
(->> input
(map solve1-1)
(apply +))
(defn solve1-2 [s x]
(if (<= (solve1-1 x) 0) s
(recur (+ s (solve1-1 x)) (solve1-1 x))))
(+ (->> input
(map solve1-1)
(apply +))
(->> input
(map solve1-1)
(map (partial solve1-2 0))
(apply +)))
*****************************************************
(defn solve2 [input pos]
(let [op (get input pos)]
(cond
(or (> (- pos 1) (count input))
(= op 99))
(first input)
(and (not= op 1)
(not= op 2))
"error"
:else
(recur (assoc input (get input (+ pos 3)) (if (= op 1)
(+ (get input (get input (+ pos 1))) (get input (get input (+ pos 2))))
(* (get input (get input (+ pos 1))) (get input (get input (+ pos 2)))))) (+ pos 4)))))
(solve2 input 0)
(for [x (range 100)
y (range 100)]
(if (= 19690720
(solve2 (assoc input 1 x 2 y) 0))
[x y]
""))
(solve2 (assoc input 1 52 2 8) 0)
(+ (* 52 100) 8)
*****************************************************
(defn op->points [[op count] points]
(let [lst (last points)]
(case op
\U (concat points (map #(identity [(first lst) %]) (take count (iterate inc (inc (last lst))))))
\D (concat points (map #(identity [(first lst) %]) (take count (iterate dec (dec (last lst))))))
\R (concat points (map #(identity [% (last lst)]) (take count (iterate inc (inc (first lst))))))
\L (concat points (map #(identity [% (last lst)]) (take count (iterate dec (dec (first lst))))))
points)))
(defn ops->points [ops]
(reduce (fn [points op] (op->points op points)) [[0 0]] ops))
(->> (slurp "input.txt")
((fn [v] (clojure.string/split v #"\s")))
(map (fn [x] (clojure.string/split x #",")))
(map (fn [xs] (map (fn [x] [(first x) (Integer/parseInt (apply str (rest x)))]) xs)))
(map ops->points)
(map rest)
(map set)
((fn [v] (clojure.set/intersection (first v) (last v))))
(map (fn [[x y]] (+ (Math/abs x) (Math/abs y))))
sort
first)
*****************************************************
(def wires (->> (slurp "input.txt")
((fn [v] (clojure.string/split v #"\s")))
(map (fn [x] (clojure.string/split x #",")))
(map (fn [xs] (map (fn [x] [(first x) (Integer/parseInt (apply str (rest x)))]) xs)))
(map ops->points)))
(def intersections (->> (slurp "input.txt")
((fn [v] (clojure.string/split v #"\s")))
(map (fn [x] (clojure.string/split x #",")))
(map (fn [xs] (map (fn [x] [(first x) (Integer/parseInt (apply str (rest x)))]) xs)))
(map ops->points)
(map rest)
(map set)
((fn [v] (clojure.set/intersection (first v) (last v))))))
(defn intersection->length [point]
(+ (.indexOf (first wires) point)
(.indexOf (last wires) point)))
(->> intersections
(map intersection->length)
sort
first)
*****************************************************
(defn never-decrease? [n]
(let [iter (fn [prev curr]
(cond
(= curr 0) true
(< prev (mod curr 10)) false
:default (recur (mod curr 10) (int (/ curr 10)))))]
(iter (mod n 10) (int (/ n 10)))))
(defn two-adj-same? [n]
(let [iter (fn [prev curr]
(cond
(= curr 0) false
(= prev (mod curr 10)) true
:default (recur (mod curr 10) (int (/ curr 10)))))]
(iter (mod n 10) (int (/ n 10)))))
(count (filter #(and (never-decrease? %) (two-adj-same? %)) (range 256310 732737)))
*****************************************************
(defn num->list [n]
(let [iter (fn [acc num]
(if
(= (count acc) 6) acc
(recur (conj acc (mod num 10)) (int (/ num 10)))))]
(iter '() n)))
(defn never-decrease-1? [xs]
(= xs (sort xs)))
(defn two-adj-same-1? [xs]
(seq (filter (fn [[_ v]] (= 2 (count v))) (group-by identity xs))))
(count (filter #(and (never-decrease-1? %) (two-adj-same-1? %)) (map num->list (range 256310 732737))))
*****************************************************
(defn solve5 [pos input]
(if (> (+ pos 1) (count input))
:finish
(let [op (get input pos)
opcode (mod op 100)
first-mode-position (= (mod (quot op 100) 10) 0)
second-mode-position (= (mod (quot op 1000) 10) 0)
nextpos (case opcode
(3 4) (+ pos 2)
(1 2) (+ pos 4)
pos)
nextinput (case opcode
3 (assoc input (get input (inc pos)) 1)
1 (assoc input
(get input (+ pos 3))
(+ (if first-mode-position
(get input (get input (+ pos 1)))
(get input (+ pos 1)))
(if second-mode-position
(get input (get input (+ pos 2)))
(get input (+ pos 2)))))
2 (assoc input
(get input (+ pos 3))
(* (if first-mode-position
(get input (get input (+ pos 1)))
(get input (+ pos 1)))
(if second-mode-position
(get input (get input (+ pos 2)))
(get input (+ pos 2)))))
input)
_ (when (= opcode 4 ) (prn (if first-mode-position (get input (get input (inc pos))) (get input (inc pos)))))]
(if (= opcode 99)
:halt
(recur nextpos nextinput)))))
(->> "input.txt"
slurp
((fn [v] (clojure.string/split v #"\n")))
first
((fn [x] (clojure.string/split x #",")))
(map #(Integer/parseInt %))
vec
((partial solve5 0)))
*****************************************************
(defn solve5-2 [pos input]
(if (> (+ pos 1) (count input))
:finish
(let [op (get input pos)
opcode (mod op 100)
first-mode-position (= (mod (quot op 100) 10) 0)
second-mode-position (= (mod (quot op 1000) 10) 0)
nextpos (case opcode
(1 2 7 8) (+ pos 4)
(3 4) (+ pos 2)
5 (if (not=
(if first-mode-position
(get input (get input (+ pos 1)))
(get input (+ pos 1)))
0)
(if second-mode-position
(get input (get input (+ pos 2)))
(get input (+ pos 2)))
(+ pos 3))
6 (if (= (if first-mode-position
(get input (get input (+ pos 1)))
(get input (+ pos 1)))
0)
(if second-mode-position
(get input (get input (+ pos 2)))
(get input (+ pos 2)))
(+ pos 3))
pos)
nextinput (case opcode
3 (assoc input (get input (inc pos)) 5)
1 (assoc input
(get input (+ pos 3))
(+ (if first-mode-position
(get input (get input (+ pos 1)))
(get input (+ pos 1)))
(if second-mode-position
(get input (get input (+ pos 2)))
(get input (+ pos 2)))))
2 (assoc input
(get input (+ pos 3))
(* (if first-mode-position
(get input (get input (+ pos 1)))
(get input (+ pos 1)))
(if second-mode-position
(get input (get input (+ pos 2)))
(get input (+ pos 2)))))
7 (assoc input
(get input (+ pos 3))
(if (<
(if first-mode-position
(get input (get input (+ pos 1)))
(get input (+ pos 1)))
(if second-mode-position
(get input (get input (+ pos 2)))
(get input (+ pos 2))))
1
0))
8 (assoc input
(get input (+ pos 3))
(if (=
(if first-mode-position
(get input (get input (+ pos 1)))
(get input (+ pos 1)))
(if second-mode-position
(get input (get input (+ pos 2)))
(get input (+ pos 2))))
1
0))
input)
_ (when (= opcode 4) (prn (if first-mode-position (get input (get input (inc pos))) (get input (inc pos)))))]
(if (= opcode 99)
:halt
(recur nextpos nextinput)))))
*****************************************************
(def inp6 (->> "input.txt"
slurp
((fn [v] (clojure.string/split v #"\n")))
(map (fn [v] (clojure.string/split v #"\)")))))
(defn orb-counts [inp orb]
(let [parent (ffirst (filter (fn [[p c]] (= c orb)) inp))]
(if parent
(+ 1 (orb-counts inp parent))
0)))
(->> inp6
(apply concat)
set
(map (partial orb-counts inp6))
(apply +))
*****************************************************
(defn orb-path [inp orb path]
(let [parent (ffirst (filter (fn [[p c]] (= c orb)) inp))]
(if-not parent
path
(recur inp parent (conj path parent)))))
(let [you-path (orb-path inp6 "YOU" [])
san-path (orb-path inp6 "SAN" [])]
(loop [i 0]
(if (some #(= (get you-path i) %) san-path)
(+ (- (count you-path) (count (orb-path inp6 (get you-path i) [])))
(- (count san-path) (count (orb-path inp6 (get you-path i) []))))
(recur (inc i))))) ;; (- res 2)
*****************************************************
;; refactored
(defn int-code [inputv prog]
(let [iter (fn [pos input-pos prog result]
(let [op (get prog pos)
opcode (mod op 100)
first-mode-position (= (mod (quot op 100) 10) 0)
second-mode-position (= (mod (quot op 1000) 10) 0)
next-val (if first-mode-position
(get prog (get prog (+ pos 1)))
(get prog (+ pos 1)))
next-next-val (if second-mode-position
(get prog (get prog (+ pos 2)))
(get prog (+ pos 2)))
nextpos (case opcode
(1 2 7 8) (+ pos 4)
(3 4) (+ pos 2)
5 (if (not= next-val 0) next-next-val (+ pos 3))
6 (if (= next-val 0) next-next-val (+ pos 3))
pos)
nextprog (case opcode
3 (assoc prog (get prog (+ pos 1)) (get inputv input-pos))
1 (assoc prog (get prog (+ pos 3)) (+ next-val next-next-val))
2 (assoc prog (get prog (+ pos 3)) (* next-val next-next-val))
7 (assoc prog (get prog (+ pos 3)) (if (< next-val next-next-val) 1 0))
8 (assoc prog (get prog (+ pos 3)) (if (= next-val next-next-val) 1 0))
prog)
input-pos (if (= opcode 3) (inc input-pos) input-pos)
result (if (= opcode 4) next-val result)]
(case opcode
99 :halt
4 result
(recur nextpos input-pos nextprog result))))]
(iter 0 0 prog nil)))
*****************************************************
(def program (->> "input.txt"
slurp
((fn [v] (clojure.string/split v #"\n")))
first
((fn [x] (clojure.string/split x #",")))
(map #(Integer/parseInt %))
vec))
(defn phase->signal [program phase]
(loop [i 0 inp 0]
(if (= i 5)
inp
(recur (inc i) (int-code [(get phase i) inp] program)))))
(def phases (for [a [0 1 2 3 4]
b [0 1 2 3 4]
c [0 1 2 3 4]
d [0 1 2 3 4]
e [0 1 2 3 4]
:when (= (count (group-by identity [a b c d e])) 5)]
[a b c d e]))
(->> phases
(map (partial phase->signal program))
(apply max))
*****************************************************
;; refactored
(defn int-code [initial-input prog]
(let [initial (atom initial-input)]
(fn [input]
(let [iter (fn [pos prog result]
(let [op (get prog pos)
opcode (mod op 100)
first-mode-position (= (mod (quot op 100) 10) 0)
second-mode-position (= (mod (quot op 1000) 10) 0)
get-from-next-n (fn [n] (get prog (+ pos n)))
next-val (if first-mode-position
(get prog (get-from-next-n 1))
(get-from-next-n 1))
next-next-val (if second-mode-position
(get prog (get-from-next-n 2))
(get-from-next-n 2))
nextpos (case opcode
(1 2 7 8) (+ pos 4)
(3 4) (+ pos 2)
5 (if (not= next-val 0) next-next-val (+ pos 3))
6 (if (= next-val 0) next-next-val (+ pos 3))
pos)
next-input (or @initial input)
_ (when (= opcode 3) (reset! initial nil))
nextprog (case opcode
3 (assoc prog (get-from-next-n 1) next-input)
1 (assoc prog (get-from-next-n 3) (+ next-val next-next-val))
2 (assoc prog (get-from-next-n 3) (* next-val next-next-val))
7 (assoc prog (get-from-next-n 3) (if (< next-val next-next-val) 1 0))
8 (assoc prog (get-from-next-n 3) (if (= next-val next-next-val) 1 0))
prog)
result (if (= opcode 4) next-val result)]
(case opcode
99 :halt
4 result
(recur nextpos nextprog result))))]
(iter 0 prog nil)))))
*****************************************************
;;refactored
(defn int-code [initial-input prog]
(let [state (atom {:initial initial-input :pos 0 :prog prog})]
(fn [input]
(let [iter (fn [result]
(if (or (> (+ (:pos @state) 1) (count prog))
(= input :halt))
:halt
(let [pos (:pos @state)
prog (:prog @state)
op (get prog pos)
opcode (mod op 100)
first-mode-position (= (mod (quot op 100) 10) 0)
second-mode-position (= (mod (quot op 1000) 10) 0)
get-from-next-n (fn [n] (get prog (+ pos n)))
next-val (if first-mode-position
(get prog (get-from-next-n 1))
(get-from-next-n 1))
next-next-val (if second-mode-position
(get prog (get-from-next-n 2))
(get-from-next-n 2))
nextpos (case opcode
(1 2 7 8) (+ pos 4)
(3 4) (+ pos 2)
5 (if (not= next-val 0) next-next-val (+ pos 3))
6 (if (= next-val 0) next-next-val (+ pos 3))
pos)
next-input (or (:initial @state) input)
nextprog (case opcode
3 (assoc prog (get-from-next-n 1) next-input)
1 (assoc prog (get-from-next-n 3) (+ next-val next-next-val))
2 (assoc prog (get-from-next-n 3) (* next-val next-next-val))
7 (assoc prog (get-from-next-n 3) (if (< next-val next-next-val) 1 0))
8 (assoc prog (get-from-next-n 3) (if (= next-val next-next-val) 1 0))
prog)
result (if (= opcode 4) next-val result)
_ (when (= opcode 3) (reset! state (merge @state {:initial nil})))
_ (reset! state (merge @state {:pos nextpos :prog nextprog}))]
(case opcode
99 :halt
4 result
(recur result)))))]
(iter nil)))))
(defn phase->signal-2 [program [a b c d e]]
(let [amp-a (int-code a program)
amp-b (int-code b program)
amp-c (int-code c program)
amp-d (int-code d program)
amp-e (int-code e program)]
(loop [input 0 i 0]
(let [res (-> input amp-a amp-b amp-c amp-d amp-e)]
(if (= res :halt)
input
(recur res (inc i)))))))
(def phases-2 (for [a [5 6 7 8 9]
b [5 6 7 8 9]
c [5 6 7 8 9]
d [5 6 7 8 9]
e [5 6 7 8 9]
:when (= (count (group-by identity [a b c d e])) 5)]
[a b c d e]))
(->> phases-2
(map (partial phase->signal-2 program))
(apply max))
*****************************************************
(def layer (->> "input.txt"
slurp
(partition 150)
(map #(group-by identity %))
(map-indexed (fn [idx m] [idx (count (get m \0))]))
(sort-by last)
ffirst))
(->> (nth (->> "input.txt"
slurp
(partition 150))
layer)
(group-by identity)
((fn [m] (* (count (get m \1)) (count (get m \2))))))
*****************************************************
(defn first-not-two [& x]
(if-let [first (first x)]
(if (not= first \2)
first
(recur (rest x)))))
(defn char-to-str [char]
(if (= char \0) " " "x"))
(defn printer [x]
(if (= x "\n")
(println)
(print x)))
(->> "input.txt"
slurp
(partition 150)
(apply map first-not-two)
flatten
(map char-to-str)
(partition 25)
(interpose "\n")
(map printer))
********************** day-9 *******************************
(defn int-code [initial-input prog]
(let [state (atom {:initial initial-input :prog (into {} (map-indexed hash-map prog)) :pos 0 :base 0})]
(fn [input]
(let [iter (fn [results]
(if (= input :halt)
:halt
(let [{:keys [pos prog base initial]} @state
op (get prog pos)
opcode (mod op 100)
get-from-next-n (fn [n] (get prog (+ pos n) 0))
next-val (case (mod (quot op 100) 10)
0 (get prog (get-from-next-n 1) 0)
1 (get-from-next-n 1)
2 (get prog (+ base (get-from-next-n 1)) 0))
next-next-val (case (mod (quot op 1000) 10)
0 (get prog (get-from-next-n 2) 0)
1 (get-from-next-n 2)
2 (get prog (+ base (get-from-next-n 2)) 0))
get-write-pos (fn [n] (case (mod (quot op (* 10 (int (Math/pow 10 n)))) 10) ; 1 -> 100, 3 -> 10000
2 (+ base (get-from-next-n n))
0 (get-from-next-n n)))
nextpos (case opcode
(1 2 7 8) (+ pos 4)
(3 4 9) (+ pos 2)
5 (if (not= next-val 0) next-next-val (+ pos 3))
6 (if (= next-val 0) next-next-val (+ pos 3))
pos)
next-input (or initial input)
nextprog (case opcode
1 (assoc prog (get-write-pos 3) (+ next-val next-next-val))
2 (assoc prog (get-write-pos 3) (* next-val next-next-val))
3 (assoc prog (get-write-pos 1) next-input)
7 (assoc prog (get-write-pos 3) (if (< next-val next-next-val) 1 0))
8 (assoc prog (get-write-pos 3) (if (= next-val next-next-val) 1 0))
prog)
next-initial (if (= opcode 3) nil initial)
next-base (if (= opcode 9) (+ base next-val) base)
_ (reset! state {:pos nextpos :prog nextprog :initial next-initial :base next-base})]
(case opcode
99 (do (println results) :halt)
(recur (if (= opcode 4) (conj results next-val) results))))))]
(iter [])))))
(def program (->> "input.txt"
slurp
((fn [v] (clojure.string/split v #"\n")))
first
((fn [x] (clojure.string/split x #",")))
(map #(Integer/parseInt %))
vec))
((int-code 1 program) nil)
***********************day-10**************************
(def inp (-> "input.txt"
slurp
(clojure.string/split #"\n")))
(defn colinear? [[x1 y1] [x3 y3] [x2 y2]]
(= (* (- y2 y1) (- x3 x1))
(* (- y3 y1) (- x2 x1))))
(defn blocked? [[x1 y1] [x3 y3] [x2 y2]]
(and (colinear? [x1 y1] [x3 y3] [x2 y2])
(and (or (>= x1 x2 x3) (<= x1 x2 x3))
(or (>= y1 y2 y3) (<= y1 y2 y3)))))
(def x-length (count (get inp 0)))
(def y-length (count inp))
(defn no-found-linear? [p1 p2 detects]
(not-any? (partial blocked? p1 p2) detects))
(defn detects [[x1 y1]]
(let [state (atom [])
add-if-detect (fn [x y] (when (and (= (get-in inp [x y]) \#)
(no-found-linear? [x1 y1] [x y] @state))
(swap! state conj [x y])))]
(doall (for [x (range x1 x-length)
y (take y1 (iterate dec (dec y1)))]
(add-if-detect x y)))
(doall (for [x (range x1 x-length)
y (range y1 y-length)
:when (or (not= x x1) (not= y y1))]
(add-if-detect x y)))
(doall (for [x (take x1 (iterate dec (dec x1)))
y (range y1 y-length)
:when (or (not= x x1) (not= y y1))]
(add-if-detect x y)))
(doall (for [x (take x1 (iterate dec (dec x1)))
y (take y1 (iterate dec (dec y1)))
:when (or (not= x x1) (not= y y1))]
(add-if-detect x y)))
@state))
(def result (for [x (range x-length)
y (range y-length)
:when (= (get-in inp [x y]) \#)]
[(count (detects [x y])) x y]))
(->> result
(sort-by first)
last)
*******************************************************
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment