initial commit

This commit is contained in:
2025-12-03 23:19:54 -05:00
commit 300f2e69b0
10 changed files with 6557 additions and 0 deletions

23
.gitignore vendored Normal file
View File

@@ -0,0 +1,23 @@
node_modules/
/target
/checkouts
/src/gen
.cpcache/
/build
pom.xml
pom.xml.asc
*.iml
*.jar
*.log
.shadow-cljs
.idea
.lein-*
.nrepl-*
.DS_Store
.calva/output-window
.calva/repl.calva-repl
.lsp/.cache
.clj-kondo/.cache

48
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,48 @@
// Configurration of the getting-started project for use with Calva
{
// Autostart the repl and connect it to the editor (Jack-in)
// https://calva.io/customizing-jack-in-and-connect/#customizing-jack-in
"calva.autoStartRepl": true,
// If you disable the above setting, you start the repl
// manually with the command;
// "Calva: Start a Project REPL and Connect (aka Jack-in)"
// https://calva.io/connect-sequences/
"calva.replConnectSequences": [
{
"name": "The Get Started REPL",
"autoSelectForConnect": true,
"autoSelectForJackIn": true,
"projectRootPath": ["."],
"cljsType": "none",
"projectType": "deps.edn",
"menuSelections": {
"cljAliases": ["test"]
}
}
],
// The below settings are more suitible for User settings.
// They are included here to make it easier to write guides
// about how to use the project.
// You can also see them as a suggestion for a nice repl
// workflow setup. Move the settings you like to your
// User (global) settings.json file.
// We use the Output “terminal” for evaluation results
// and side effect output.
// See https://calva.io/output/
"calva.outputDestinations": {
"evalResults": "terminal",
"evalOutput": "terminal",
"otherOutput": "terminal"
},
// Auto-open the Calva Inspector when the repl connects.
// (All evaluation results are available in the inspector.)
"calva.autoOpenInspector": true,
"calva.enableInspectorRainbow": true,
// Don't open the REPL prompt window automatically
// We recommend using regular editor files instead.
// See also: https://calva.io/fiddle-files/
// (There's a command for opening the REPL window.)
"calva.autoOpenREPLWindow": false
}

1
deps.edn Normal file
View File

@@ -0,0 +1 @@
{:deps {org.clojure/clojure {:mvn/version "1.12.0"}}}

1000
inputs/aoc2024/input1.txt Normal file

File diff suppressed because it is too large Load Diff

1000
inputs/aoc2024/input2.txt Normal file

File diff suppressed because it is too large Load Diff

4333
inputs/aoc2025/input1.txt Normal file

File diff suppressed because it is too large Load Diff

18
src/aoc2024/1.clj Normal file
View File

@@ -0,0 +1,18 @@
(ns aoc2024.1
(require '[clojure.string :as str]))
(def pairs (map (fn [ln] (map Integer/parseInt (str/split ln #"\s+")))
(str/split (slurp "input1.txt") #"\n")))
(def sum #(reduce + %))
(defn adv1_2
[l r]
(->> l
(map #(* % ((frequencies r) % 0)))
sum))
(let [A (map first pairs)
B (map second pairs)]
(adv1_2 A B))

54
src/aoc2024/2.clj Normal file
View File

@@ -0,0 +1,54 @@
(ns aoc2024.2
(:require
[aoc.utils :refer [read-input]]))
;; Each row is a report
;; Each number in the report is a level
(def tdata '((7 6 4 2 1)
(1 2 7 8 9)
(9 7 6 2 1)
(1 3 2 4 5)
(8 6 4 4 1)
(1 3 6 7 9)))
;; A report is safe if:
;; - The levels are either strictly increasing or strictly decreasing
;; - Any two adjacent levels differ by at:
;; - at least 1
;; - at most 3
;; The goal is to determine how many reports are safe
(defn report-is-safe
;; unknown if increasing or decreasing
([report]
(or (report-is-safe report -)
(report-is-safe report +)))
;; we know the direction
([report dir]
(let [[this next :as levels] report]
(or
(nil? next)
(and
(<= 1 (dir (- next this)) 3)
(report-is-safe (rest levels) dir))))))
(defn without-each
[v]
(map-indexed
(fn [idx _]
(concat
(take idx v)
(drop (inc idx) v)))
v))
(defn report-is-safe-with-allowance
[report]
(boolean (some true? (map report-is-safe (cons report (without-each report))))))
(map report-is-safe-with-allowance tdata)
(let [input (read-input "inputs/input2.txt")]
(count (filter report-is-safe-with-allowance input)))

68
src/aoc2025/1.clj Normal file
View File

@@ -0,0 +1,68 @@
(ns aoc2025.1 (:require [utils :refer [read-strs]]))
;; https://adventofcode.com/2025/day/1
(def turn-strs (read-strs "inputs/aoc2025/input1.txt"))
(defn turn-val
[[dir & num]]
(*
(if (= dir \L) -1 1)
(Integer/parseInt (apply str num))))
(turn-val "R35")
(def N 100)
(defn get-position
[initial change]
(mod (+ initial change) N))
(def start 50)
(get-position start (turn-val "L50"))
(defn password
[position [turn-str & rest] count]
(if (= turn-str nil)
count
(password
(get-position
position
(turn-val turn-str))
rest
(if (= position 0)
(inc count)
count))))
(password start turn-strs 0)
;; part 2 of the challenge added the complication that you're counting
;; the number of times the dial ~crosses~ 0, not just the number of times
;; it lands on 0
(defn cross-count
[position turn-val]
(+
(quot (abs turn-val) N) ;; guaranteed to cross at least x // N times
(let
[next-pos (get-position position turn-val)]
(if (neg? turn-val)
(if (and (not= position 0)
(or (> next-pos position)
(= next-pos 0)))
1
0)
(if (< next-pos position)
1
0)))))
(cross-count 0 -100)
(defn password-2
[position [turn-str & rest] count]
(if (= turn-str nil)
count
(password-2
(get-position
position
(turn-val turn-str))
rest
(+ count (cross-count position (turn-val turn-str))))))
(password-2 start turn-strs 0)

12
src/utils.clj Normal file
View File

@@ -0,0 +1,12 @@
(ns utils)
(require '[clojure.string :as str])
(defn read-ints
[filename]
(let [data (slurp filename)
lines (str/split data #"\n")
parse-line #(map Integer/parseInt (str/split % #"\s+"))]
(map parse-line lines)))
(def read-strs #(str/split (slurp %) #"\n"))