Skip to content

Instantly share code, notes, and snippets.

@joinr
Last active December 12, 2022 16:07
Show Gist options
  • Save joinr/5735a460402b3f16fed35783c852ccf9 to your computer and use it in GitHub Desktop.
Save joinr/5735a460402b3f16fed35783c852ccf9 to your computer and use it in GitHub Desktop.
minor optimizations for poster's code for aoc2022 8b
(ns aoc-2022.day08
(:require
[clojure.java.io :as io]
[criterium.core :as c]))
(set! *unchecked-math* :warn-on-boxed)
(defn- line->cells [line]
(vec (map (fn [h] {:height (read-string (str h))}) line)))
(defn- append-cells [acc line]
(let [cells (line->cells line)]
(conj acc cells)))
(defn- update-cell [vcells row col maxh]
(let [cell (get (get vcells row) col)
height (:height cell)]
[(assoc-in vcells [row col :visible] (or (:visible cell) (> height maxh)))
(max height maxh)]))
(defn- set-visible [cells]
(let [height (dec (count cells))
width (dec (count (get cells 0)))]
(loop [col 0
row 0
mh_left_col -1
mh_right_col -1
mh_down_row -1
mh_up_row -1
vcells cells]
(if (> row height)
vcells
(if (> col width)
(recur 0 (inc row) -1 -1 -1 -1 vcells)
(let [[vcells mh_left_col] (update-cell vcells row col mh_left_col)
[vcells mh_right_col] (update-cell vcells (- height row) (- width col) mh_right_col)
[vcells mh_down_row] (update-cell vcells col row mh_down_row)
[vcells mh_up_row] (update-cell vcells (- height col) (- width row) mh_up_row)]
(recur (inc col) row
mh_left_col mh_right_col
mh_down_row mh_up_row
vcells)))))))
#_
(defn part-1 [file]
(let [cells (utils/reduce-file append-cells [] file)
vcells (set-visible cells)
count (reduce
(fn [acc l]
(reduce
(fn [acc c] (if (:visible c) (inc acc) acc))
acc l))
0 vcells)]
count))
#_(part-1 (clojure.java.io/resource "day08"))
;;going for unboxed math here, but not impressive. a few nanos.
(defn- find-closer2 ^long [^long index ^long indexacc ^long nindex]
(if (> (abs (- index indexacc)) (abs (- index nindex))) nindex indexacc))
;;~4x faster than update-in.
(defn assoc3 [m i j k v]
(let [c (m i)
e (c j)]
(->> (assoc e k v)
(assoc c j)
(assoc m i))))
(let [^longs closer (long-array 1)]
(defn- update-cell-scenic [vcells row col index scenics]
(let [_ (aset closer 0 Long/MAX_VALUE)
cell ((vcells row) col)
height (cell :height)
;;reduce is faster. combine reduce
scenics (reduce-kv (fn [acc ^long k idx]
(if (>= k ^long height) ;;passes the filter
(do (aset closer 0 (find-closer2 index (aget closer 0) idx))
acc)
(dissoc acc k))) scenics scenics)
nscenics (assoc scenics height index)
nscenic (abs (- ^long index ^long (aget closer 0)))]
[(assoc3 vcells row col :scenic (if-let [scenic (:scenic cell)] (* ^long scenic ^long nscenic) nscenic))
nscenics])))
(defn- set-scenic [cells]
(let [height (dec (count cells))
width (dec (count (get cells 0)))
base_lou {9 0}
base_rod {9 height}]
(loop [col 0
row 0
scenics_left_col base_lou
scenics_right_col base_rod
scenics_down_row base_lou
scenics_up_row base_rod
vcells cells]
(if (> row height)
vcells
(if (> col width)
(recur 0 (inc row) base_lou base_rod base_lou base_rod vcells)
(let [[vcells scenics_left_col]
(update-cell-scenic vcells row col col scenics_left_col)
[vcells scenics_right_col]
(update-cell-scenic vcells (- height row) (- width col) (- width col) scenics_right_col)
[vcells scenics_down_row]
(update-cell-scenic vcells col row col scenics_down_row)
[vcells scenics_up_row]
(update-cell-scenic vcells (- height col) (- width row) (- height col) scenics_up_row)]
(recur (inc col) row
scenics_left_col scenics_right_col
scenics_down_row scenics_up_row
vcells)))))))
(defn part-2 [cells]
(let [scells (set-scenic cells)
count (reduce
(fn [acc l]
(reduce (fn [acc c] (max acc (:scenic c))) acc l))
0 scells)]
count))
(def data (->> (io/resource "day8input.txt") slurp clojure.string/split-lines (reduce append-cells [])))
;;for testing
;; aoc-2022.day08> (c/quick-bench (part-2 data))
;; Evaluation count : 30 in 6 samples of 5 calls.
;; Execution time mean : 23.872538 ms
;; Execution time std-deviation : 318.105010 µs
;; Execution time lower quantile : 23.632598 ms ( 2.5%)
;; Execution time upper quantile : 24.312766 ms (97.5%)
;; Overhead used : 1.833627 ns
;;unboxed math, combined with primitive array/cell, buys us another 10%
(defn- find-closer2 ^long [^long index ^long indexacc ^long nindex]
(if (> (abs (- index indexacc)) (abs (- index nindex))) nindex indexacc))
;;~4x faster than update-in.
(defn assoc3 [m i j k v]
(let [c (m i)
e (c j)]
(->> (assoc e k v)
(assoc c j)
(assoc m i))))
(let [^longs closer (long-array 1)]
(defn- update-cell-scenic [vcells row col index scenics]
(let [_ (aset closer 0 Long/MAX_VALUE)
cell ((vcells row) col)
height (cell :height)
;;reduce is faster. combine reduce
scenics (reduce-kv (fn [acc ^long k idx]
(if (>= k ^long height) ;;passes the filter
(do (aset closer 0 (find-closer2 index (aget closer 0) idx))
acc)
(dissoc acc k))) scenics scenics)
nscenics (assoc scenics height index)
nscenic (abs (- ^long index ^long (aget closer 0)))]
[(assoc3 vcells row col :scenic (if-let [scenic (:scenic cell)] (* ^long scenic ^long nscenic) nscenic))
nscenics])))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment