about summary refs log tree commit diff
path: root/day22.clj
blob: a89c1e4a6bea1751c03ae1f8cd5d4eed66264bdf (plain) (blame)
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
54
55
56
57
58
59
(ns org.vuxu.aoc2021.day22
  (:require [clojure.string :as str]
            [clojure.set :as set]))

(def data
  (->> (slurp "day22")
       str/split-lines
       (map (partial re-seq #"(?:on|off|-?\d+)"))
       (map (fn [[cmd & coords]]
              [(= cmd "on") (mapv parse-long coords)]))))

(defn step [state [cmd [x1 x2 y1 y2 z1 z2]]]
  ((if cmd set/union set/difference)
   state
   (set (for [x (range x1 (inc x2))
              y (range y1 (inc y2))
              z (range z1 (inc z2))]
          [x y z]))))

(def part1
  (->> data 
       (filter (fn [[cmd [x1 x2 y1 y2 z1 z2]]]
                 (and (<= -50 x1 x2 50)
                      (<= -50 y1 y2 50)
                      (<= -50 z1 z2 50))))
       (reduce step #{})
       count))
;; => 647062

(def combined
  (reduce
   (fn [cubes [cmd1 [xmin1 xmax1 ymin1 ymax1 zmin1 zmax1] :as ins1]]
     (let [ncubes
           (for [[cmd2 [xmin2 xmax2 ymin2 ymax2 zmin2 zmax2]] cubes
                 :let [xmin (max xmin1 xmin2)
                       xmax (min xmax1 xmax2)]
                 :when (<= xmin xmax)
                 :let [ymin (max ymin1 ymin2)
                       ymax (min ymax1 ymax2)]
                 :when (<= ymin ymax)
                 :let [zmin (max zmin1 zmin2)
                       zmax (min zmax1 zmax2)]
                 :when (<= zmin zmax)]
             [(not cmd2) [xmin xmax ymin ymax zmin zmax]])]
       (cond-> (concat cubes ncubes)
         cmd1
         (conj ins1))))
   []
   data))

(def part2
  (reduce (fn [acc [cmd [x1 x2 y1 y2 z1 z2]]]
            (+ acc (* (if cmd 1 -1)
                      (- x2 x1 -1)
                      (- y2 y1 -1)
                      (- z2 z1 -1))))
          0
          combined))
;; => 1319618626668022