Last active
December 12, 2022 16:07
-
-
Save joinr/5735a460402b3f16fed35783c852ccf9 to your computer and use it in GitHub Desktop.
minor optimizations for poster's code for aoc2022 8b
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;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