Skip to content

Instantly share code, notes, and snippets.

@JpOnline
Last active December 18, 2019 21:02
Show Gist options
  • Save JpOnline/a525bb8cca9c742733cd0c99fd71295c to your computer and use it in GitHub Desktop.
Save JpOnline/a525bb8cca9c742733cd0c99fd71295c to your computer and use it in GitHub Desktop.
(ns nothing.advent)
;; ---------- Day 2 ----------
(defn insert-into [original position element]
(let [[before after] (split-at position original)]
(vec (concat before [element] (rest after)))))
(defn program-alarm
([data input] (program-alarm data 0 input))
([data position-to-process input]
(let [elem-in #(get data %)
instruction (elem-in position-to-process)
immediate-position-to-store (+ 3 position-to-process)
position-to-store (if (= 1 (mod (quot instruction 10000) 10))
immediate-position-to-store
(elem-in immediate-position-to-store))
immediate-first-arg (elem-in (inc position-to-process))
first-arg (if (= 1 (mod (quot instruction 100) 10))
immediate-first-arg
(elem-in immediate-first-arg))
immediate-second-arg (elem-in (+ 2 position-to-process))
second-arg (if (= 1 (mod (quot instruction 1000) 10))
immediate-second-arg
(elem-in immediate-second-arg))
]
(case (mod instruction 100)
1 (-> data
(insert-into position-to-store (+ first-arg second-arg))
(program-alarm (+ 4 position-to-process)))
2 (-> data
(insert-into position-to-store (* first-arg second-arg))
(program-alarm (+ 4 position-to-process)))
3 (-> data
(insert-into (elem-in (inc position-to-process)) input)
(program-alarm (+ 2 position-to-process)))
4 (elem-in (elem-in (inc position-to-process)))
99 data))))
(program-alarm [1 0 0 0 99] 0)
(program-alarm [2 3 0 3 99] 0)
(program-alarm [2 4 4 5 99 0] 0)
(program-alarm [1 1 1 4 99 5 6 0 99] 0)
noun-verb
(def noun-verb
(let [program [1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,10,19,1,19,5,23,2,23,6,27,1,27,5,31,2,6,31,35,1,5,35,39,2,39,9,43,1,43,5,47,1,10,47,51,1,51,6,55,1,55,10,59,1,59,6,63,2,13,63,67,1,9,67,71,2,6,71,75,1,5,75,79,1,9,79,83,2,6,83,87,1,5,87,91,2,6,91,95,2,95,9,99,1,99,6,103,1,103,13,107,2,13,107,111,2,111,10,115,1,115,6,119,1,6,119,123,2,6,123,127,1,127,5,131,2,131,6,135,1,135,2,139,1,139,9,0,99,2,14,0,0]]
(loop [noun 0
verb 0]
(let [result (first (program-alarm (-> program
(insert-into 1 noun)
(insert-into 2 verb))))]
(cond
(= 19690720 result) [noun verb]
(> noun 99) "nao achei"
(> verb 99) (recur (inc noun) 0)
:else (recur noun (inc verb)))))))
;; ---------- Day 3 ----------
(defn final-position [[row column] direction]
(case direction
"U" [(inc row) column]
"R" [row (inc column)]
"D" [(dec row) column]
"L" [row (dec column)]))
(defn step [grid final-pos wire-id steps]
(merge-with (partial merge-with +)
grid {final-pos {:intersections 1 wire-id steps}}))
(defn move [grid direction wire-id steps-counter init-steps init-pos]
(loop [grid grid
direction direction
steps (dec init-steps)
steps-counter steps-counter
position init-pos]
(let [f-pos (final-position position direction)
step-c (inc steps-counter)]
(if (zero? steps)
[f-pos step-c (step grid f-pos wire-id step-c)]
(recur (step grid f-pos wire-id step-c) direction (dec steps) step-c f-pos)))))
(defn cross-wire [grid wire-id input]
(reduce (fn [[init-pos steps-counter grid] [_ dir steps]]
(move grid dir wire-id steps-counter (Integer/parseInt steps) init-pos))
[[0 0] 0 grid]
(re-seq #"([LURD])(\d+)" input)))
(let [[_ _ first-wire] (cross-wire {} :first-wire "R1009,U993,L383,D725,R163,D312,R339,U650,R558,U384,R329,D61,L172,D555,R160,D972,L550,D801,L965,U818,L123,D530,R176,D353,L25,U694,L339,U600,L681,D37,R149,D742,R762,U869,R826,U300,L949,U978,L303,U361,R136,D343,L909,U551,R745,U913,L566,D292,R820,U886,R205,D431,L93,D71,R577,U872,L705,U510,L698,U963,R607,U527,L669,D543,R690,U954,L929,D218,R490,U500,L589,D332,R949,D538,R696,U659,L188,U468,L939,U833,L445,D430,R78,D303,R130,D649,R849,D712,L511,U745,R51,U973,R799,U829,R605,D771,L837,U204,L414,D427,R538,U116,R540,D168,R493,U900,L679,U431,L521,D500,L428,U332,L954,U717,L853,D339,L88,U807,L607,D496,L163,U468,L25,U267,L759,D898,L591,U445,L469,U531,R596,D486,L728,D677,R350,D429,R39,U568,R92,D875,L835,D841,R877,U178,L221,U88,R592,U692,R455,U693,L419,U90,R609,U672,L293,U168,R175,D456,R319,D570,R504,D165,L232,D624,L604,D68,R807,D59,R320,D281,L371,U956,L788,D897,L231,D829,R287,D798,L443,U194,R513,D925,L232,U225,L919,U563,R448,D889,R661,U852,L950,D558,L269,U186,L625,U673,L995,U732,R435,U849,L413,D690,L158,D234,R361,D458,L271,U90,L781,U754,R256,U162,L842,U927,L144,D62,R928,D238,R473,U97,L745,U303,L487,D349,L520,D31,L825,U385,L133,D948,L39,U62,R801,D664,L333,U134,R692,U385,L658,U202,L279,D374,R489,D686,L182,U222,R733,U177,R94,D603,L376,U901,R216,D851,L155,D214,L460,U758,R121,D746,L180,U175,L943,U146,L166,D251,L238,U168,L642,D341,R281,U182,R539,D416,R553,D67,L748,U272,R257,D869,L340,U180,R791,U138,L755,D976,R731,U713,R602,D284,L258,U176,R509,U46,R935,U576,R96,U89,L913,U703,R833")
[_ _ final] (cross-wire first-wire :second-wire "L1006,D998,R94,D841,R911,D381,R532,U836,L299,U237,R781,D597,L399,D800,L775,D405,L485,U636,R589,D942,L878,D779,L751,U711,L973,U410,L151,U15,L685,U417,L106,D648,L105,D461,R448,D743,L589,D430,R883,U37,R155,U350,L421,U23,R337,U816,R384,D671,R615,D410,L910,U914,L579,U385,R916,U13,R268,D519,R289,U410,L389,D885,L894,U734,L474,U707,L72,U155,L237,U760,L127,U806,L15,U381,L557,D727,L569,U320,L985,D452,L8,D884,R356,U732,L672,D458,L485,U402,L238,D30,R644,U125,R753,U183,L773,U487,R849,U210,L164,D808,L595,D668,L340,U785,R313,D72,L76,D263,R689,U604,R471,U688,R462,D915,R106,D335,R869,U499,R190,D916,R468,D882,R56,D858,L143,D741,L386,U856,R50,U853,R151,D114,L773,U854,L290,D344,L23,U796,L531,D932,R314,U960,R643,D303,L661,D493,L82,D491,L722,U848,L686,U4,L985,D509,L135,D452,R500,U105,L326,D101,R222,D944,L645,D362,L628,U305,L965,U356,L358,D137,R787,U728,R967,U404,R18,D928,L695,D965,R281,D597,L791,U731,R746,U163,L780,U41,L255,U81,L530,D964,R921,D297,R475,U663,L226,U623,L984,U943,L143,U201,R926,U572,R343,U839,R764,U751,R128,U939,R987,D108,R474,U599,R412,D248,R125,U797,L91,D761,L840,U290,L281,U779,R650,D797,R185,D320,L25,U378,L696,U332,R75,D620,L213,D667,R558,U267,L846,U306,R939,D220,R311,U827,R345,U534,R56,D679,R48,D845,R898,U8,R862,D960,R753,U319,L886,D795,R805,D265,R876,U729,R894,D368,R858,U744,R506,D327,L903,U919,L721,U507,L463,U753,R775,D719,R315,U128,R17,D376,R999,D386,L259,U181,L162,U605,L265,D430,R35,D968,R207,U466,R796,D667,R93,U749,L315,D410,R312,U929,L923,U260,R638")
result (filter (fn [[k v]] (and (:first-wire v) (:second-wire v))) final)
crossing-points (map second result)]
;; (clojure.pprint/pprint crossing-points)
;; (sort (map (fn [[r c]] (+ (Math/abs r) (Math/abs c))) crossing-points))
(sort (map (fn [{:keys [first-wire second-wire]}] (+ first-wire second-wire)) crossing-points))
)
;; ---------- Day 4 ----------
(defn two-adjacent? [password]
(some (partial = 2) (map count (partition-by identity (str password)))))
(defn never-decrease? [password]
(every? #(<= (Character/digit (first %) 10) (Character/digit (second %) 10)) (partition 2 1 (str password))))
(loop [counter 278384
result 0
limit 824795]
(if (> counter limit)
result
(recur (inc counter) (if (and (two-adjacent? counter) (never-decrease? counter))
(inc result)
result)
limit)
)
)
;; ---------- Day 5 ----------
(defn program-alarm
[data position-to-process input input2]
(let [elem-in #(get data %)
;; p (log/spy (take 20 data))
instruction (elem-in position-to-process)
immediate-position-to-store (elem-in (+ 3 position-to-process))
;; p (log/spy (elem-in immediate-position-to-store))
position-to-store immediate-position-to-store #_(if (= 1 (mod (quot instruction 10000) 10))
immediate-position-to-store
(elem-in immediate-position-to-store))
immediate-first-arg (elem-in (inc position-to-process))
first-arg (if (= 1 (mod (quot instruction 100) 10))
immediate-first-arg
(elem-in immediate-first-arg))
immediate-second-arg (elem-in (+ 2 position-to-process))
second-arg (if (= 1 (mod (quot instruction 1000) 10))
immediate-second-arg
(elem-in immediate-second-arg))
;; p (log/spy (elem-in 225))
]
(case (mod instruction 100)
1 (-> data
(insert-into position-to-store (+ first-arg second-arg))
(program-alarm (+ 4 position-to-process) input input2))
2 (-> data
(insert-into position-to-store (* first-arg second-arg))
(program-alarm (+ 4 position-to-process) input input2))
3 (-> data
(insert-into (elem-in (inc position-to-process)) input)
(program-alarm (+ 2 position-to-process) input2 input2))
4 [[data (+ 2 position-to-process) input2 input2]
first-arg]
;; Jump if true
5 (if (= 0 first-arg)
(program-alarm data (+ 3 position-to-process) input input2)
(program-alarm data second-arg input input2))
;; Jump if false
6 (if (= 0 first-arg)
(program-alarm data second-arg input input2)
(program-alarm data (+ 3 position-to-process) input input2))
;; Less than
7 (let [new-data (if (< first-arg second-arg)
(insert-into data position-to-store 1)
(insert-into data position-to-store 0))]
(program-alarm new-data (+ 4 position-to-process) input input2))
;; equals
8 (let [new-data (if (= first-arg second-arg)
(insert-into data position-to-store 1)
(insert-into data position-to-store 0))]
(program-alarm new-data (+ 4 position-to-process) input input2))
99 [data])))
(program-alarm [3 0 4 0 99] 1)
;; ---------- Day 6 ----------
(defn process-one-orbit [orbit-pair]
(let [[orbited orbiting] (clojure.string/split orbit-pair #"\)")]
{orbited [orbiting]}
))
(defn process-input [input]
(apply (partial merge-with concat)
(map process-one-orbit (clojure.string/split input #"\n")))
)
(defn count-total-orbits [processed-input level lookup-object]
(if-let [objects-to-count (processed-input lookup-object)]
(+ level
(apply +
(map (partial count-total-orbits processed-input (inc level))
objects-to-count)))
level
)
)
(count-total-orbits
(process-input
"COM)B
B)C
C)D
D)E
E)F
B)G
G)H
D)I
E)J
J)K
K)L
K)YOU
I)SAN"
) 0 "COM")
(defn process-one-orbit-orbiting [orbit-pair]
(let [[orbited orbiting] (clojure.string/split orbit-pair #"\)")]
{orbiting orbited}
))
(defn process-input-map [input]
(let [splited-input (clojure.string/split input #"\n")]
{:orbited (apply (partial merge-with concat)
(map process-one-orbit splited-input))
:orbiting (apply merge (map process-one-orbit-orbiting splited-input))
}))
(defn goto-san [orbit-map previous counter current]
(let [to-visit (remove nil? (remove #{nil previous} (conj ((:orbited orbit-map) current) ((:orbiting orbit-map) current))))]
(cond
(seq (filter #{"SAN"} to-visit)) counter
(empty? to-visit) 9999999999999999999
:else (apply min (map (partial goto-san orbit-map current (inc counter)) to-visit))
)))
(goto-san orbit-map "YOU" 0 "TFB")
(def previous "YOU")
(def current "TFB")
(def counter 0)
(def orbit-map (process-input-map ""))
;; ---------- Day 7 ----------
(defn thruster [phase-setting-sequence]
(loop [programs (vec (repeat 5 [[
3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,
-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,
53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10
]
0
]))
running-amp 0
output 0]
(let [instruction-to-run (second (get programs running-amp))
[program-alarm-state result] (program-alarm
(first (get programs running-amp))
instruction-to-run
(if (= 0 instruction-to-run)
(get phase-setting-sequence running-amp)
output)
output)]
(cond
(> output 10000000000) "muito grande"
(nil? result) output
:else (recur (insert-into programs running-amp program-alarm-state)
(mod (inc running-amp) 5)
result)
)
)))
(repeat 3 [1 2])
(def phase 4)
(def output 0)
(thruster [0 1 2 3 4])
(thruster [9 7 8 5 6])
(take 12 (iterate (partial thruster [9 8 7 6 5]) 0))
(take 20 (iterate (partial thruster [9 7 8 5 6]) 0))
(require '[clojure.math.combinatorics :as combi])
(apply max (map thruster (combi/permutations [5 6 7 8 9])))
;; ---------- Day 8 ----------
(defn parse-image [input width height]
(partition height (partition width (re-seq #"\d" input)))
)
(defn count-in-layer [digit layer]
(->> layer
flatten
(filter #{digit})
count))
(defn print-layer [layer]
(->> layer
(map clojure.string/join)
(map println)))
(let [parsed-input (parse-image input 25 6)
layer-least-0 (->> parsed-input
(map (partial count-in-layer "0"))
(map-indexed vector)
(apply min-key second)
first)
digits-1 (count-in-layer "1" (get (vec parsed-input) layer-least-0))
digits-2 (count-in-layer "2" (get (vec parsed-input) layer-least-0))
]
(* digits-1 digits-2))
(defn choose-final-pixel [flattened-layers position]
(->> flattened-layers
(map #(nth % position))
(remove #{"2"})
first))
(let [width 25
height 6
parsed-input (parse-image input width height)
flattened-layers (map flatten parsed-input)
final-pixels (map #(choose-final-pixel flattened-layers %)
(range (* width height)))
]
(-> final-pixels
(clojure.string/join)
(parse-image width height)
first
print-layer))
;; ---------- Day 9 ----------
(defn intcode-computer
[memory pointer input input2 relative-base]
(let [#_#_memory (vec (concat memory (repeat 500 0)))
elem-in #(get memory %)
;; _ (log/spy (take 20 memory))
instruction (elem-in pointer)
immediate-position-to-store (elem-in (+ 3 pointer))
;; _ (log/spy (elem-in immediate-position-to-store))
position-to-store (case (mod (quot instruction 10000) 10)
2 (+ relative-base immediate-position-to-store)
immediate-position-to-store)
immediate-first-arg (elem-in (inc pointer))
first-arg (case (mod (quot instruction 100) 10)
2 (elem-in (+ relative-base immediate-first-arg))
1 immediate-first-arg
(elem-in immediate-first-arg))
immediate-second-arg (elem-in (+ 2 pointer))
second-arg (case (mod (quot instruction 1000) 10)
2 (elem-in (+ relative-base immediate-second-arg))
1 immediate-second-arg
(elem-in immediate-second-arg))
first-arg-for-op-3 (case (mod (quot instruction 100) 10)
2 (+ relative-base (elem-in (inc pointer)))
(elem-in (inc pointer)))
]
(case (mod instruction 100)
1 (-> memory
(insert-into position-to-store (+ first-arg second-arg))
(recur (+ 4 pointer) input input2 relative-base))
2 (-> memory
(insert-into position-to-store (* first-arg second-arg))
(recur (+ 4 pointer) input input2 relative-base))
3 (-> memory
(insert-into first-arg-for-op-3 input)
(recur (+ 2 pointer) input2 input2 relative-base))
4 (do (println first-arg)
(recur memory (+ 2 pointer) input input2 relative-base))
;; Jump if true
5 (if (= 0 first-arg)
(recur memory (+ 3 pointer) input input2 relative-base)
(recur memory second-arg input input2 relative-base))
;; Jump if false
6 (if (= 0 first-arg)
(recur memory second-arg input input2 relative-base)
(recur memory (+ 3 pointer) input input2 relative-base))
;; Less than
7 (let [new-data (if (< first-arg second-arg)
(insert-into memory position-to-store 1)
(insert-into memory position-to-store 0))]
(recur new-data (+ 4 pointer) input input2 relative-base))
;; equals
8 (let [new-data (if (= first-arg second-arg)
(insert-into memory position-to-store 1)
(insert-into memory position-to-store 0))]
(recur new-data (+ 4 pointer) input input2 relative-base))
;; Adjust relative-base
9 (recur memory (+ 2 pointer) input input2 (+ first-arg relative-base))
99 [memory])))
(intcode-computer [209 2 204 3 99 -3 8 10 11] 0 0 0 1)
(intcode-computer [109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99] 0 0 0 0)
(intcode-computer [1102,34915192,34915192,7,4,7,99,0] 0 0 0 0)
(intcode-computer (vec (concat input-memory (repeat 500 0))) 0 2 0 0)
;; ---------- Day 9 ----------
(defn map->rows [asteroid-map]
(clojure.string/split asteroid-map #"\n"))
(defn process-column [row-index]
(fn [column-index column-value]
[column-index row-index column-value]))
(defn process-row [row-index row]
(map-indexed (process-column row-index) (re-seq #"." row)))
(defn asteroid-map->asteroid-list [asteroid-map]
(map butlast
(filter #(= "#" (nth % 2))
(apply concat (map-indexed process-row (map->rows asteroid-map))))))
(defn gcd [a b]
(if (zero? b)
a
(recur b (mod a b))))
(defn points-not-visible [p1 p2 max-width max-height]
(let [
;; p1 '(7 9)
;; p2 '(7 0)
;; max-width 9
;; max-height 9
[p1-x p1-y] p1
[p2-x p2-y] p2
[dx dy] [(- p2-x p1-x) (- p2-y p1-y)]
divisor (Math/abs (gcd dx dy))
[fx fy] [(/ dx divisor) (/ dy divisor)]]
(set
(remove #{p1 p2}
(take-while (fn [[w h]] (and (<= w max-width) (<= h max-height) (>= w 0) (>= h 0)))
(iterate (fn [[x y]] [(+ x fx) (+ y fy)]) p1))))))
(defn only-visible [asteroid-list asteroid]
(let [max-width (first (apply max-key first asteroid-list))
max-height (second (apply max-key second asteroid-list))
without-self (remove #{asteroid} asteroid-list)]
(loop [visible []
[current & r] without-self]
(let [to-be-removed (points-not-visible asteroid current max-width max-height)
asteroids-to-process (remove to-be-removed r)]
(if (seq asteroids-to-process)
(recur (conj visible current)
asteroids-to-process)
(conj visible current))))))
(defn asteroid-map->detected-maps [input]
(let [asteroid-list (asteroid-map->asteroid-list input)]
(map #(into {:asteroid %
:can-detect (count (only-visible asteroid-list %))
:detected (only-visible asteroid-list %)})
asteroid-list)))
(let [detected-maps (asteroid-map->detected-maps
"..............#.#...............#....#....
#.##.......#....#.#..##........#...#......
..#.....#....#..#.#....#.....#.#.##..#..#.
...........##...#...##....#.#.#....#.##..#
....##....#...........#..#....#......#.###
.#...#......#.#.#.#...#....#.##.##......##
#.##....#.....#.....#...####........###...
.####....#.......#...##..#..#......#...#..
...............#...........#..#.#.#.......
........#.........##...#..........#..##...
...#..................#....#....##..#.....
.............#..#.#.........#........#.##.
...#.#....................##..##..........
.....#.#...##..............#...........#..
......#..###.#........#.....#.##.#......#.
#......#.#.....#...........##.#.....#..#.#
.#.............#..#.....##.....###..#..#..
.#...#.....#.....##.#......##....##....#..
.........#.#..##............#..#...#......
..#..##...#.#..#....#..#.#.......#.##.....
#.......#.#....#.#..##.#...#.......#..###.
.#..........#...##.#....#...#.#.........#.
..#.#.......##..#.##..#.......#.###.......
...#....###...#......#..#.....####........
.............#.#..........#....#......#...
#................#..................#.###.
..###.........##...##..##.................
.#.........#.#####..#...##....#...##......
........#.#...#......#.................##.
.##.....#..##.##.#....#....#......#.#....#
.....#...........#.............#.....#....
........#.##.#...#.###.###....#.#......#..
..#...#.......###..#...#.##.....###.....#.
....#.....#..#.....#...#......###...###...
#..##.###...##.....#.....#....#...###..#..
........######.#...............#...#.#...#
...#.....####.##.....##...##..............
###..#......#...............#......#...#..
#..#...#.#........#.#.#...#..#....#.#.####
#..#...#..........##.#.....##........#.#..
........#....#..###..##....#.#.......##..#
.................##............#.......#..")]
(apply max-key :can-detect detected-maps))
(remove #{[1 0] [2 2]} [[1 0] [2 2] [3 4]])
[0 0] [3 1] (apply gcd (map - [6 2] [9 3]))
(comment
(require '[taoensso.timbre :as log])
(log/merge-config!
{:middleware [(fn [data]
(update data :vargs
(partial mapv #(if (string? %)
%
(with-out-str (clojure.pprint/pprint %))))))]})
(require '[alembic.still])
(alembic.still/load-project)
(alembic.still/distill '[org.clojure/math.combinatorics "0.1.6"])
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment