mirror of
https://github.com/Ajetski/advent-of-code.git
synced 2025-09-30 09:23:17 -09:00
WIP; init shared clj lib
This commit is contained in:
parent
9064515faf
commit
bef47f68b7
8
shared/clj/project.clj
Normal file
8
shared/clj/project.clj
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
(defproject org.ajet/advent-of-code "0.0.0-SNAPSHOT"
|
||||||
|
:description "my 2024 advent of code solutions in clojure"
|
||||||
|
:url "http://github.com/ajetski/advent-of-code"
|
||||||
|
:min-lein-version "2.0.0"
|
||||||
|
:dependencies [[org.clojure/clojure "1.12.0"]
|
||||||
|
[org.clojure/math.combinatorics "0.3.0"]
|
||||||
|
[babashka/fs "0.5.23"]
|
||||||
|
[org.babashka/http-client "0.4.22"]])
|
172
shared/clj/src/core.clj
Normal file
172
shared/clj/src/core.clj
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
(ns core
|
||||||
|
(:require
|
||||||
|
[clojure.string :as str]))
|
||||||
|
|
||||||
|
;; string/regex stuff
|
||||||
|
|
||||||
|
(defn split-on-comma [s]
|
||||||
|
(str/split s #","))
|
||||||
|
|
||||||
|
(defn split-whitespace [s]
|
||||||
|
(str/split s #"\s+"))
|
||||||
|
|
||||||
|
(defn split-on-double-newlines [s]
|
||||||
|
(str/split s #"\n\n"))
|
||||||
|
|
||||||
|
(defn get-match-groups [regex s]
|
||||||
|
(->> s (re-seq regex) (map rest)))
|
||||||
|
|
||||||
|
(defn re-pos [re s]
|
||||||
|
(loop [m (re-matcher re s)
|
||||||
|
res {}]
|
||||||
|
(if (.find m)
|
||||||
|
(recur m (assoc res (.start m) (.group m)))
|
||||||
|
res)))
|
||||||
|
|
||||||
|
|
||||||
|
;; general utils
|
||||||
|
|
||||||
|
(defn dbg
|
||||||
|
"prints a value and returns it.
|
||||||
|
useful for inserting into ->, ->>, and comp
|
||||||
|
|
||||||
|
(->> x
|
||||||
|
some-fn
|
||||||
|
dbg
|
||||||
|
some-fn-2)"
|
||||||
|
[x]
|
||||||
|
(println x)
|
||||||
|
x)
|
||||||
|
|
||||||
|
(defn log
|
||||||
|
"faster than dbg, for those really tricky graph problems
|
||||||
|
or just ya know, writing to your diary"
|
||||||
|
([msg]
|
||||||
|
(spit "logs.txt" msg :append true))
|
||||||
|
([file msg]
|
||||||
|
(spit file msg :append true)))
|
||||||
|
|
||||||
|
(defn compose
|
||||||
|
"just comp, but in the \"right\" order (left-to-right evaluation of fns)"
|
||||||
|
;; several inlined arrities for optimization
|
||||||
|
([f1]
|
||||||
|
f1)
|
||||||
|
([f1 f2]
|
||||||
|
(comp f2 f1))
|
||||||
|
([f1 f2 f3]
|
||||||
|
(comp f3 f2 f1))
|
||||||
|
([f1 f2 f3 f4 & fs]
|
||||||
|
(comp (apply comp (reverse fs)) f4 f3 f2 f1)))
|
||||||
|
|
||||||
|
|
||||||
|
;; alter collections
|
||||||
|
|
||||||
|
(defn get-coords [list-of-lists]
|
||||||
|
(for [row (range (count list-of-lists))
|
||||||
|
col (range (count (get list-of-lists row)))]
|
||||||
|
[row col]))
|
||||||
|
|
||||||
|
(defn map-by-coords [arr-2d]
|
||||||
|
(->> arr-2d
|
||||||
|
get-coords
|
||||||
|
(map (juxt identity #(get (get arr-2d (first %)) (second %))))
|
||||||
|
(into {})))
|
||||||
|
|
||||||
|
(defn insert-at-idx [coll idx el]
|
||||||
|
(concat (take idx coll)
|
||||||
|
(list el)
|
||||||
|
(drop idx coll)))
|
||||||
|
|
||||||
|
(defn mmap
|
||||||
|
"map map f coll"
|
||||||
|
[f & colls]
|
||||||
|
(apply map (partial map f) colls))
|
||||||
|
|
||||||
|
(defn mmapv
|
||||||
|
"mapv mapv f coll"
|
||||||
|
[f & colls]
|
||||||
|
(apply mapv (partial mapv f) colls))
|
||||||
|
|
||||||
|
(defn mmmap
|
||||||
|
"map map map f coll"
|
||||||
|
[f & colls]
|
||||||
|
(apply map (partial map (partial map f)) colls))
|
||||||
|
|
||||||
|
(defn mmmapv
|
||||||
|
"mapv mapv mapv f coll"
|
||||||
|
[f & colls]
|
||||||
|
(apply mapv (partial mapv (partial mapv f)) colls))
|
||||||
|
|
||||||
|
(defn partition-by-counts [counts coll]
|
||||||
|
(->> counts
|
||||||
|
(reduce (fn [[acc coll] c]
|
||||||
|
(let [[a b] (split-at c coll)]
|
||||||
|
[(conj acc a) b]))
|
||||||
|
[[] coll])
|
||||||
|
first))
|
||||||
|
|
||||||
|
(defn update-last [v f & args]
|
||||||
|
(let [idx (dec (count v))]
|
||||||
|
(apply update v idx f args)))
|
||||||
|
|
||||||
|
(defn partition-contiguous-nums [sorted-nums]
|
||||||
|
(:acc (reduce (fn [{acc :acc
|
||||||
|
a :last}
|
||||||
|
el]
|
||||||
|
(if (= el (inc a))
|
||||||
|
{:acc (update-last acc conj el)
|
||||||
|
:last el}
|
||||||
|
{:acc (conj acc [el])
|
||||||
|
:last el}))
|
||||||
|
{:acc [[(first sorted-nums)]]
|
||||||
|
:last (first sorted-nums)}
|
||||||
|
(rest sorted-nums))))
|
||||||
|
|
||||||
|
|
||||||
|
;; Math things
|
||||||
|
|
||||||
|
(defn square [n] (* n n))
|
||||||
|
(defn mean [a] (/ (reduce + a) (count a)))
|
||||||
|
(defn standard-deviation [a]
|
||||||
|
(let [mn (mean a)]
|
||||||
|
(Math/sqrt
|
||||||
|
(/ (reduce #(+ %1 (square (- %2 mn))) 0 a)
|
||||||
|
(dec (count a))))))
|
||||||
|
|
||||||
|
(defn cartesian-product [a b]
|
||||||
|
(partition (count b)
|
||||||
|
(for [el1 a
|
||||||
|
el2 b]
|
||||||
|
(* el1 el2))))
|
||||||
|
|
||||||
|
|
||||||
|
;; conversions
|
||||||
|
|
||||||
|
(def arrow-char->dir {\> :right
|
||||||
|
\v :down
|
||||||
|
\< :left
|
||||||
|
\^ :up})
|
||||||
|
|
||||||
|
(defn bool->binary-int
|
||||||
|
"converts bool to integral binary representation (0 or 1)"
|
||||||
|
[condition]
|
||||||
|
(if condition 1 0))
|
||||||
|
|
||||||
|
|
||||||
|
;; 👻 macros 👻
|
||||||
|
|
||||||
|
(defmacro pfor
|
||||||
|
"pairwise for, like clojure.core/for except NOT cartesian.
|
||||||
|
linear result over arrs"
|
||||||
|
[bindings & body]
|
||||||
|
(let [vars (take-nth 2 bindings)
|
||||||
|
forms (take-nth 2 (rest bindings))]
|
||||||
|
`(map (fn [~@vars] ~@body) ~@forms)))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(def ^:private a [1 2 3])
|
||||||
|
(def ^:private b [3 2 1])
|
||||||
|
(pfor [x a
|
||||||
|
y b
|
||||||
|
z [0 1 2]]
|
||||||
|
(+ x y z)))
|
28
shared/clj/src/input_manager.clj
Normal file
28
shared/clj/src/input_manager.clj
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
(ns input-manager
|
||||||
|
(:require
|
||||||
|
[babashka.fs :as fs]
|
||||||
|
[babashka.http-client :as http]
|
||||||
|
[clojure.string :as str]))
|
||||||
|
|
||||||
|
(def session (delay (first (fs/read-all-lines "input/.session"))))
|
||||||
|
|
||||||
|
(defn input-file-loc [year day]
|
||||||
|
(str "input/" year "-" day ".txt"))
|
||||||
|
|
||||||
|
(defn download-input [year day]
|
||||||
|
(->> {:headers {:cookie (str "session=" @session)}}
|
||||||
|
(http/get (str "https://adventofcode.com/" year "/day/" day "/input"))
|
||||||
|
:body
|
||||||
|
(str/split-lines)
|
||||||
|
(fs/write-lines (input-file-loc year day))))
|
||||||
|
|
||||||
|
(defn get-input [year day]
|
||||||
|
(try
|
||||||
|
(fs/read-all-lines (input-file-loc year day))
|
||||||
|
(catch java.nio.file.NoSuchFileException _e
|
||||||
|
(download-input year day)
|
||||||
|
(get-input year day))))
|
||||||
|
|
||||||
|
(defn get-input-raw [year day]
|
||||||
|
(str/join "\n" (get-input year day)))
|
||||||
|
|
24
shared/clj/test/core_test.clj
Normal file
24
shared/clj/test/core_test.clj
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
(ns core-test
|
||||||
|
(:require [core :as c]
|
||||||
|
[clojure.test :refer :all :as t]))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(use 'clojure.repl)
|
||||||
|
|
||||||
|
#_{:clj-kondo/ignore [:unresolved-symbol]}
|
||||||
|
(dir c)
|
||||||
|
|
||||||
|
(run-tests)
|
||||||
|
|
||||||
|
;
|
||||||
|
)
|
||||||
|
|
||||||
|
(deftest math-test
|
||||||
|
(testing "math utils"
|
||||||
|
(is (= 1 1))))
|
||||||
|
|
||||||
|
(deftest utils-test
|
||||||
|
(testing "general utils"))
|
||||||
|
|
||||||
|
(deftest coll-lib-test
|
||||||
|
(testing "alter coll utils"))
|
Loading…
x
Reference in New Issue
Block a user