aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ.J <thechairman@thechairman.info>2024-05-30 21:49:58 -0400
committerJ.J <thechairman@thechairman.info>2024-05-30 21:49:58 -0400
commit231c2b688d1e6cf0846d46e883da30e042a9c6cf (patch)
tree98a6d3a461fe190b38b2cf33a708a1d01703fa70
parentfe088aa5778dcdbaab4dd8d4a7395a91c444b45c (diff)
parenta2c2b728ec6051323ed937f54816089cd2ae9d20 (diff)
downloadgleam_aoc-231c2b688d1e6cf0846d46e883da30e042a9c6cf.tar.gz
gleam_aoc-231c2b688d1e6cf0846d46e883da30e042a9c6cf.zip
Merge branch 'main' of https://github.com/hunkyjimpjorps/AdventOfCode
-rw-r--r--aoc2018/day-01/day-01.rkt16
-rw-r--r--aoc2018/day-02/day-02.rkt27
-rw-r--r--aoc2018/day-03/day-03.rkt51
-rw-r--r--aoc2018/day-04/day-04.rkt43
-rw-r--r--aoc2018/day-05/day-05.rkt31
-rw-r--r--aoc2018/day-06/day-06.rkt1
-rw-r--r--aoc2023-gleam/.DS_Store (renamed from aoc2023/.DS_Store)bin6148 -> 6148 bytes
-rw-r--r--aoc2023-gleam/.github/workflows/test.yml (renamed from aoc2023/.github/workflows/test.yml)0
-rw-r--r--aoc2023-gleam/.gitignore (renamed from aoc2023/.gitignore)0
-rw-r--r--aoc2023-gleam/README.md (renamed from aoc2023/README.md)0
-rw-r--r--aoc2023-gleam/gleam.toml (renamed from aoc2023/gleam.toml)0
-rw-r--r--aoc2023-gleam/manifest.toml (renamed from aoc2023/manifest.toml)22
-rw-r--r--aoc2023-gleam/src/.gitignore (renamed from aoc2023/src/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day1/.gitignore (renamed from aoc2023/src/day1/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day1/solve.gleam (renamed from aoc2023/src/day1/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day10/.gitignore (renamed from aoc2023/src/day10/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day10/solve.gleam (renamed from aoc2023/src/day10/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day11/.gitignore (renamed from aoc2023/src/day11/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day11/solve.gleam (renamed from aoc2023/src/day11/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day12/.gitignore (renamed from aoc2023/src/day12/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day12/solve.gleam (renamed from aoc2023/src/day12/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day13/.gitignore (renamed from aoc2023/src/day13/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day13/solve.gleam (renamed from aoc2023/src/day13/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day14/.gitignore (renamed from aoc2023/src/day14/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day14/solve.gleam (renamed from aoc2023/src/day14/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day15/.gitignore (renamed from aoc2023/src/day15/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day15/solve.gleam (renamed from aoc2023/src/day15/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day16/.gitignore (renamed from aoc2023/src/day16/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day16/solve.gleam (renamed from aoc2023/src/day16/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day17/.gitignore (renamed from aoc2023/src/day17/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day17/solve.gleam (renamed from aoc2023/src/day17/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day18/.gitignore (renamed from aoc2023/src/day18/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day18/solve.gleam (renamed from aoc2023/src/day18/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day19/.gitignore (renamed from aoc2023/src/day19/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day19/solve.gleam (renamed from aoc2023/src/day19/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day2/.gitignore (renamed from aoc2023/src/day2/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day2/solve.gleam (renamed from aoc2023/src/day2/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day20/.gitignore (renamed from aoc2023/src/day20/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day20/solve.gleam (renamed from aoc2023/src/day20/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day21/.gitignore (renamed from aoc2023/src/day22/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day21/solve.gleam25
-rw-r--r--aoc2023-gleam/src/day22/.gitignore (renamed from aoc2023/src/day23/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day22/solve.gleam (renamed from aoc2023/src/day22/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day23/.gitignore (renamed from aoc2023/src/day3/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day23/solve.gleam (renamed from aoc2023/src/day23/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day3/.gitignore (renamed from aoc2023/src/day4/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day3/solve.gleam (renamed from aoc2023/src/day3/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day4/.gitignore (renamed from aoc2023/src/day5/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day4/solve.gleam (renamed from aoc2023/src/day4/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day5/.gitignore (renamed from aoc2023/src/day6/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day5/solve.gleam (renamed from aoc2023/src/day5/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day6/.gitignore (renamed from aoc2023/src/day7/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day6/solve.gleam (renamed from aoc2023/src/day6/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day7/.gitignore (renamed from aoc2023/src/day8/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day7/solve.gleam (renamed from aoc2023/src/day7/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day8/.gitignore (renamed from aoc2023/src/day9/.gitignore)0
-rw-r--r--aoc2023-gleam/src/day8/solve.gleam (renamed from aoc2023/src/day8/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/day9/.gitignore1
-rw-r--r--aoc2023-gleam/src/day9/solve.gleam (renamed from aoc2023/src/day9/solve.gleam)0
-rw-r--r--aoc2023-gleam/src/utilities/array2d.gleam (renamed from aoc2023/src/utilities/array2d.gleam)0
-rw-r--r--aoc2023-gleam/src/utilities/memo.gleam (renamed from aoc2023/src/utilities/memo.gleam)0
-rw-r--r--aoc2023-gleam/src/utilities/prioqueue.gleam (renamed from aoc2023/src/utilities/prioqueue.gleam)0
-rw-r--r--aoc2023-gleam/test/aoc2023_test.gleam (renamed from aoc2023/test/aoc2023_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day1/day1_test.gleam (renamed from aoc2023/test/day1/day1_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day10/day10_test.gleam (renamed from aoc2023/test/day10/day10_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day11/day11_test.gleam (renamed from aoc2023/test/day11/day11_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day12/day12_test.gleam (renamed from aoc2023/test/day12/day12_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day13/day13_test.gleam (renamed from aoc2023/test/day13/day13_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day14/day14_test.gleam (renamed from aoc2023/test/day14/day14_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day15/day15_test.gleam (renamed from aoc2023/test/day15/day15_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day16/day16_test.gleam (renamed from aoc2023/test/day16/day16_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day17/day17_test.gleam (renamed from aoc2023/test/day17/day17_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day18/day18_test.gleam (renamed from aoc2023/test/day18/day18_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day19/day19_test.gleam (renamed from aoc2023/test/day19/day19_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day2/day2_test.gleam (renamed from aoc2023/test/day2/day2_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day20/day20_test.gleam (renamed from aoc2023/test/day20/day20_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day21/day21_test.gleam38
-rw-r--r--aoc2023-gleam/test/day22/day22_test.gleam (renamed from aoc2023/test/day22/day22_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day23/day23_test.gleam (renamed from aoc2023/test/day23/day23_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day3/day3_test.gleam (renamed from aoc2023/test/day3/day3_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day4/day4_test.gleam (renamed from aoc2023/test/day4/day4_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day5/day5_test.gleam (renamed from aoc2023/test/day5/day5_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day6/day6_test.gleam (renamed from aoc2023/test/day6/day6_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day7/day7_test.gleam (renamed from aoc2023/test/day7/day7_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day8/day8_test.gleam (renamed from aoc2023/test/day8/day8_test.gleam)0
-rw-r--r--aoc2023-gleam/test/day9/day9_test.gleam (renamed from aoc2023/test/day9/day9_test.gleam)0
-rw-r--r--aoc2023-racket/day-01/day-01.rkt (renamed from aoc2023-other/day-01/day-01.rkt)0
-rw-r--r--aoc2023-racket/day-02/day-02-parser.rkt (renamed from aoc2023-other/day-02/day-02-parser.rkt)0
-rw-r--r--aoc2023-racket/day-02/day-02.rkt (renamed from aoc2023-other/day-02/day-02.rkt)0
-rw-r--r--aoc2023-racket/day-03/day-03.rkt (renamed from aoc2023-other/day-03/day-03.rkt)0
-rw-r--r--aoc2023-racket/day-04/day-04.rkt (renamed from aoc2023-other/day-04/day-04.rkt)0
-rw-r--r--aoc2023-racket/day-05/day-05.rkt (renamed from aoc2023-other/day-05/day-05.rkt)0
-rw-r--r--aoc2023-racket/day-06/day-06.rkt (renamed from aoc2023-other/day-06/day-06.rkt)0
-rw-r--r--aoc2023-racket/day-07/day-07.rkt (renamed from aoc2023-other/day-07/day-07.rkt)0
-rw-r--r--aoc2023-racket/day-08/day-08.rkt (renamed from aoc2023-other/day-08/day-08.rkt)0
-rw-r--r--aoc2023-racket/day-09/day-09-polynomial.rkt (renamed from aoc2023-other/day-09/day-09-polynomial.rkt)0
-rw-r--r--aoc2023-racket/day-09/day-09.rkt (renamed from aoc2023-other/day-09/day-09.rkt)0
-rw-r--r--aoc2023-racket/day-10/day-10.rkt (renamed from aoc2023-other/day-10/day-10.rkt)0
-rw-r--r--aoc2023-racket/day-11/day-11.rkt (renamed from aoc2023-other/day-11/day-11.rkt)0
-rw-r--r--aoc2023-racket/day-12/day-12.rkt (renamed from aoc2023-other/day-12/day-12.rkt)0
-rw-r--r--aoc2023-racket/day-13/day-13.rkt (renamed from aoc2023-other/day-13/day-13.rkt)0
-rw-r--r--aoc2023-racket/day-14/day-14.rkt (renamed from aoc2023-other/day-14/day-14.rkt)0
-rw-r--r--aoc2023-racket/day-15/day-15.rkt (renamed from aoc2023-other/day-15/day-15.rkt)0
-rw-r--r--aoc2023-racket/day-16/day-16.rkt (renamed from aoc2023-other/day-16/day-16.rkt)0
-rw-r--r--aoc2023-racket/day-17/day-17.rkt (renamed from aoc2023-other/day-17/day-17.rkt)0
-rw-r--r--aoc2023-racket/day-18/day-18.rkt (renamed from aoc2023-other/day-18/day-18.rkt)0
-rw-r--r--aoc2023-racket/day-19/day-19.rkt (renamed from aoc2023-other/day-19/day-19.rkt)0
-rw-r--r--aoc2023-racket/day-20/day-20.rkt (renamed from aoc2023-other/day-20/day-20.rkt)0
-rw-r--r--aoc2023-racket/day-21/day-21.rkt (renamed from aoc2023-other/day-21/day-21.rkt)0
-rw-r--r--aoc2023-racket/day-22/day-22.rkt (renamed from aoc2023-other/day-22/day-22.rkt)0
-rw-r--r--aoc2023-racket/day-23/day-23.rkt (renamed from aoc2023-other/day-23/day-23.rkt)0
-rw-r--r--aoc2023-racket/day-24/day-24a.rkt (renamed from aoc2023-other/day-24/day-24a.rkt)0
-rw-r--r--aoc2023-racket/day-24/day-24b.rkt (renamed from aoc2023-other/day-24/day-24b.rkt)0
-rw-r--r--aoc2023-racket/day-25/day-25.rkt (renamed from aoc2023-other/day-25/day-25.rkt)0
-rw-r--r--aoc2023/src/aoc2023.gleam12
-rw-r--r--codingquest2024/.github/workflows/test.yml23
-rw-r--r--codingquest2024/.gitignore5
-rw-r--r--codingquest2024/README.md25
-rw-r--r--codingquest2024/gleam.toml22
-rw-r--r--codingquest2024/manifest.toml17
-rw-r--r--codingquest2024/src/codingquest2024.gleam5
-rw-r--r--codingquest2024/src/day1/solution.gleam55
-rw-r--r--codingquest2024/src/day2/solution.gleam66
-rw-r--r--codingquest2024/src/day3/solution.gleam50
-rw-r--r--codingquest2024/src/day4/solution.gleam49
-rw-r--r--codingquest2024/src/day5/solution.gleam67
-rw-r--r--codingquest2024/src/day6/solution.gleam86
-rw-r--r--codingquest2024/src/day7/solution.gleam73
-rw-r--r--codingquest2024/src/day8/solution.gleam26
-rw-r--r--codingquest2024/src/day9/input.txt203
-rw-r--r--codingquest2024/src/day9/solution.gleam0
-rw-r--r--codingquest2024/src/utilities/memo.gleam57
-rw-r--r--codingquest2024/test/codingquest2024_test.gleam12
133 files changed, 1085 insertions, 23 deletions
diff --git a/aoc2018/day-01/day-01.rkt b/aoc2018/day-01/day-01.rkt
new file mode 100644
index 0000000..b18f7c9
--- /dev/null
+++ b/aoc2018/day-01/day-01.rkt
@@ -0,0 +1,16 @@
+#lang racket
+
+(require advent-of-code
+ threading)
+
+(define deltas
+ (~>> (open-aoc-input (find-session) 2018 1 #:cache #true) port->lines (map string->number)))
+
+;; part 1
+(for/sum ([delta deltas]) delta)
+
+;; part 2
+(for/fold ([seen (set)] [current-frequency 0] #:result current-frequency) ([delta (in-cycle deltas)])
+ (define new-frequency (+ current-frequency delta))
+ #:final (set-member? seen new-frequency)
+ (values (set-add seen new-frequency) new-frequency))
diff --git a/aoc2018/day-02/day-02.rkt b/aoc2018/day-02/day-02.rkt
new file mode 100644
index 0000000..38155fb
--- /dev/null
+++ b/aoc2018/day-02/day-02.rkt
@@ -0,0 +1,27 @@
+#lang racket
+
+(require advent-of-code
+ threading)
+
+(define ids (port->lines (open-aoc-input (find-session) 2018 2 #:cache #true)))
+
+;; part 1
+(define (make-baskets str)
+ (for/fold ([baskets (hash)]) ([ch (in-string str)])
+ (hash-update baskets ch add1 0)))
+
+(define (has-count n ht)
+ (member n (hash-values ht)))
+
+(for/fold ([two 0] [three 0] #:result (* two three)) ([id (in-list ids)])
+ (define baskets (make-baskets id))
+ (values (if (has-count 2 baskets) (add1 two) two) (if (has-count 3 baskets) (add1 three) three)))
+
+;; part 2
+(define (string-difference str1 str2)
+ (for/sum ([ch1 (in-string str1)] [ch2 (in-string str2)]) (if (equal? ch1 ch2) 0 1)))
+
+(for*/first ([id1 (in-list ids)] [id2 (in-list ids)] #:when (= 1 (string-difference id1 id2)))
+ (~>> (for/list ([ch1 (in-string id1)] [ch2 (in-string id2)] #:when (equal? ch1 ch2))
+ ch1)
+ (apply string)))
diff --git a/aoc2018/day-03/day-03.rkt b/aoc2018/day-03/day-03.rkt
new file mode 100644
index 0000000..b486361
--- /dev/null
+++ b/aoc2018/day-03/day-03.rkt
@@ -0,0 +1,51 @@
+#lang racket
+
+(require advent-of-code
+ threading
+ data/applicative
+ data/monad
+ megaparsack
+ megaparsack/text)
+
+(struct claim (number start-x start-y size-x size-y) #:transparent)
+
+(define claim/p
+ (do (char/p #\#)
+ [number <- integer/p]
+ (string/p " @ ")
+ [start-x <- integer/p]
+ (char/p #\,)
+ [start-y <- integer/p]
+ (string/p ": ")
+ [size-x <- integer/p]
+ (char/p #\x)
+ [size-y <- integer/p]
+ (pure (claim number start-x start-y size-x size-y))))
+
+(define (parse-claim str)
+ (parse-result! (parse-string claim/p str)))
+
+(define (make-claim ht cl)
+ (for*/fold ([fabric ht])
+ ([x (in-range (claim-start-x cl) (+ (claim-start-x cl) (claim-size-x cl)))]
+ [y (in-range (claim-start-y cl) (+ (claim-start-y cl) (claim-size-y cl)))])
+ (hash-update fabric (cons x y) add1 0)))
+
+(define claims
+ (~> (port->lines (open-aoc-input (find-session) 2018 3 #:cache #true)) (map parse-claim _)))
+
+(define claimed-fabric
+ (for/fold ([fabric (hash)]) ([cl (in-list claims)])
+ (make-claim fabric cl)))
+
+;; part 1
+(for/sum ([claim-count (in-list (hash-values claimed-fabric))] #:when (< 1 claim-count)) 1)
+
+;; part 2
+(define (uncontested-claim? fabric cl)
+ (for*/and ([x (in-range (claim-start-x cl) (+ (claim-start-x cl) (claim-size-x cl)))]
+ [y (in-range (claim-start-y cl) (+ (claim-start-y cl) (claim-size-y cl)))])
+ (= 1 (hash-ref fabric (cons x y)))))
+
+(for/first ([cl (in-list claims)] #:when (uncontested-claim? claimed-fabric cl))
+ (claim-number cl))
diff --git a/aoc2018/day-04/day-04.rkt b/aoc2018/day-04/day-04.rkt
new file mode 100644
index 0000000..3660099
--- /dev/null
+++ b/aoc2018/day-04/day-04.rkt
@@ -0,0 +1,43 @@
+#lang racket
+
+(require advent-of-code
+ data/applicative
+ data/monad
+ megaparsack
+ megaparsack/text
+ threading)
+
+(struct entry (month day hour minute message) #:transparent)
+
+(define (parse-message chrs)
+ (define str (apply string chrs))
+ (match str
+ ["wakes up" 'awake]
+ ["falls asleep" 'asleep]
+ [shift (~> shift (string-trim "Guard #") (string-trim " begins shift") string->number)]))
+
+(define entry/p
+ (do (string/p "[1518-")
+ [month <- integer/p]
+ (char/p #\-)
+ [day <- integer/p]
+ space/p
+ [hour <- integer/p]
+ (char/p #\:)
+ [minute <- integer/p]
+ (string/p "] ")
+ [message <- (many/p any-char/p)]
+ (pure (entry month day hour minute (parse-message message)))))
+
+(define (parse-entry str)
+ (parse-result! (parse-string entry/p str)))
+
+(define entries
+ (~> (port->lines (open-aoc-input (find-session) 2018 4 #:cache #true)) (map parse-entry _)))
+
+(define sorted-entries
+ (~> entries
+ (sort < #:key entry-minute)
+ (sort < #:key entry-hour)
+ (sort < #:key entry-day)
+ (sort < #:key entry-month)))
diff --git a/aoc2018/day-05/day-05.rkt b/aoc2018/day-05/day-05.rkt
new file mode 100644
index 0000000..a78f5b5
--- /dev/null
+++ b/aoc2018/day-05/day-05.rkt
@@ -0,0 +1,31 @@
+#lang racket
+
+(require advent-of-code
+ threading)
+
+(define starting-chain
+ (~> (fetch-aoc-input (find-session) 2018 5 #:cache #true) string-trim string->list))
+
+(define (reactive-pair? ch1 ch2)
+ (and (equal? (char-downcase ch1) (char-downcase ch2)) (not (equal? ch1 ch2))))
+
+(define (remove-reactive-pairs chs [acc '()])
+ (match chs
+ [(list* ch1 ch2 rest-chs)
+ #:when (reactive-pair? ch1 ch2)
+ (remove-reactive-pairs rest-chs acc)]
+ [(list* ch rest-chs) (remove-reactive-pairs rest-chs (cons ch acc))]
+ [(list) (reverse acc)]))
+
+(define (keep-removing-reactive-pairs chs)
+ (define chs* (remove-reactive-pairs chs))
+ (if (equal? chs chs*) (length chs) (keep-removing-reactive-pairs chs*)))
+
+;; part 1
+(keep-removing-reactive-pairs starting-chain)
+
+;; part 2
+(~>> (for/list ([letter (in-string "abcdefghijklmnopqrstuvwxyz")])
+ (define tweaked-chain (filter (λ (c) (not (equal? (char-downcase c) letter))) starting-chain))
+ (keep-removing-reactive-pairs tweaked-chain))
+ (apply min))
diff --git a/aoc2018/day-06/day-06.rkt b/aoc2018/day-06/day-06.rkt
new file mode 100644
index 0000000..6f1f7b4
--- /dev/null
+++ b/aoc2018/day-06/day-06.rkt
@@ -0,0 +1 @@
+#lang racket
diff --git a/aoc2023/.DS_Store b/aoc2023-gleam/.DS_Store
index 5172429..5172429 100644
--- a/aoc2023/.DS_Store
+++ b/aoc2023-gleam/.DS_Store
Binary files differ
diff --git a/aoc2023/.github/workflows/test.yml b/aoc2023-gleam/.github/workflows/test.yml
index cf2096e..cf2096e 100644
--- a/aoc2023/.github/workflows/test.yml
+++ b/aoc2023-gleam/.github/workflows/test.yml
diff --git a/aoc2023/.gitignore b/aoc2023-gleam/.gitignore
index 8248306..8248306 100644
--- a/aoc2023/.gitignore
+++ b/aoc2023-gleam/.gitignore
diff --git a/aoc2023/README.md b/aoc2023-gleam/README.md
index 3f534e8..3f534e8 100644
--- a/aoc2023/README.md
+++ b/aoc2023-gleam/README.md
diff --git a/aoc2023/gleam.toml b/aoc2023-gleam/gleam.toml
index 8190aef..8190aef 100644
--- a/aoc2023/gleam.toml
+++ b/aoc2023-gleam/gleam.toml
diff --git a/aoc2023/manifest.toml b/aoc2023-gleam/manifest.toml
index 900b5c0..416a155 100644
--- a/aoc2023/manifest.toml
+++ b/aoc2023-gleam/manifest.toml
@@ -2,19 +2,19 @@
# You typically do not need to edit this file
packages = [
- { name = "adglent", version = "1.2.0", build_tools = ["gleam"], requirements = ["glint", "gleam_http", "gleam_stdlib", "simplifile", "gleam_erlang", "gap", "gleam_httpc", "snag", "gleam_community_ansi", "tom", "gleam_otp"], otp_app = "adglent", source = "hex", outer_checksum = "A20D35001061F8AD602E3B92FB3AC0E1E4EEC642AD2AAE0ACEAD3A85F37DA7F0" },
- { name = "gap", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_stdlib"], otp_app = "gap", source = "hex", outer_checksum = "5E369751DB547BFBDA7735878DC04DA31FCA3112193D61D5D7566010C7C8BA98" },
- { name = "gleam_community_ansi", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "8B5A9677BC5A2738712BBAF2BA289B1D8195FDF962BBC769569976AD5E9794E1" },
- { name = "gleam_community_colour", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "036C206886AFB9F153C552700A7A0B4D2864E3BC96A20C77E5F34A013C051BE3" },
- { name = "gleam_community_maths", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_maths", source = "hex", outer_checksum = "1B9DB313E94A0E4674CA84C5D29F45ECFE211BFB38ABBD8B23737395F47D08B3" },
+ { name = "adglent", version = "1.2.0", build_tools = ["gleam"], requirements = ["gap", "gleam_community_ansi", "gleam_erlang", "gleam_http", "gleam_httpc", "gleam_otp", "gleam_stdlib", "glint", "simplifile", "snag", "tom"], otp_app = "adglent", source = "hex", outer_checksum = "A20D35001061F8AD602E3B92FB3AC0E1E4EEC642AD2AAE0ACEAD3A85F37DA7F0" },
+ { name = "gap", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_stdlib"], otp_app = "gap", source = "hex", outer_checksum = "2EE1B0A17E85CF73A0C1D29DA315A2699117A8F549C8E8D89FA8261BE41EDEB1" },
+ { name = "gleam_community_ansi", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "FE79E08BF97009729259B6357EC058315B6FBB916FAD1C2FF9355115FEB0D3A4" },
+ { name = "gleam_community_colour", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "A49A5E3AE8B637A5ACBA80ECB9B1AFE89FD3D5351FF6410A42B84F666D40D7D5" },
+ { name = "gleam_community_maths", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_maths", source = "hex", outer_checksum = "E30C61A75051DAF7CFD77C4FBAA04140FDA0B5D831955E7A74521E5576E2780D" },
{ name = "gleam_erlang", version = "0.23.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "C21CFB816C114784E669FFF4BBF433535EEA9960FA2F216209B8691E87156B96" },
- { name = "gleam_http", version = "3.5.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "AECDA43AFD523D07A8F09068598A6E271C505278A0CB6F9C7A2E4365EAE8D11E" },
- { name = "gleam_httpc", version = "2.1.1", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_stdlib"], otp_app = "gleam_httpc", source = "hex", outer_checksum = "06AC1CA52C9BAA66C9D5C0303B2BF34E39AA1546BB96AEE496E4B06D513AB8C7" },
- { name = "gleam_otp", version = "0.8.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_erlang"], otp_app = "gleam_otp", source = "hex", outer_checksum = "18EF8242A5E54BA92F717C7222F03B3228AEE00D1F286D4C56C3E8C18AA2588E" },
- { name = "gleam_stdlib", version = "0.33.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "539E37A2AA5EBE8E75F4B74755E4CC604BD957C3000AC8D705A2024886A2738B" },
- { name = "glint", version = "0.13.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_community_ansi", "gleam_community_colour", "snag"], otp_app = "glint", source = "hex", outer_checksum = "46E56049CD370D61F720D319D0AB970408C9336EEB918F08B5DCB1DCE9845FA3" },
+ { name = "gleam_http", version = "3.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "8C07DF9DF8CC7F054C650839A51C30A7D3C26482AC241C899C1CEA86B22DBE51" },
+ { name = "gleam_httpc", version = "2.1.2", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_stdlib"], otp_app = "gleam_httpc", source = "hex", outer_checksum = "ACD05CA3BAC7780DF5FFAE334621FD199D1B490FAF6ECDFF74316CAA61CE88E6" },
+ { name = "gleam_otp", version = "0.8.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "18EF8242A5E54BA92F717C7222F03B3228AEE00D1F286D4C56C3E8C18AA2588E" },
+ { name = "gleam_stdlib", version = "0.36.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "C0D14D807FEC6F8A08A7C9EF8DFDE6AE5C10E40E21325B2B29365965D82EB3D4" },
+ { name = "glint", version = "0.13.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_community_colour", "gleam_stdlib", "snag"], otp_app = "glint", source = "hex", outer_checksum = "46E56049CD370D61F720D319D0AB970408C9336EEB918F08B5DCB1DCE9845FA3" },
{ name = "pqueue", version = "2.0.7", build_tools = ["rebar3"], requirements = [], otp_app = "pqueue", source = "hex", outer_checksum = "8B0204BB202335890E4E7F9B99A8EC0B84DDB8513EE298EB180EE9B3BCB4C859" },
- { name = "simplifile", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0BD6F0E7DA1A7E11D18B8AD48453225CAFCA4C8CFB4513D217B372D2866C501C" },
+ { name = "simplifile", version = "1.5.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "EB9AA8E65E5C1E3E0FDCFC81BC363FD433CB122D7D062750FFDF24DE4AC40116" },
{ name = "snag", version = "0.2.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "snag", source = "hex", outer_checksum = "8FD70D8FB3728E08AC425283BB509BB0F012BE1AE218424A597CDE001B0EE589" },
{ name = "tom", version = "0.2.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "tom", source = "hex", outer_checksum = "5C5A9B8586C547F1F39542B1A3BBD9FEE17AFEAB51CE53B32B13D0D46B421249" },
]
diff --git a/aoc2023/src/.gitignore b/aoc2023-gleam/src/.gitignore
index bc13a69..bc13a69 100644
--- a/aoc2023/src/.gitignore
+++ b/aoc2023-gleam/src/.gitignore
diff --git a/aoc2023/src/day1/.gitignore b/aoc2023-gleam/src/day1/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day1/.gitignore
+++ b/aoc2023-gleam/src/day1/.gitignore
diff --git a/aoc2023/src/day1/solve.gleam b/aoc2023-gleam/src/day1/solve.gleam
index 37a19d2..37a19d2 100644
--- a/aoc2023/src/day1/solve.gleam
+++ b/aoc2023-gleam/src/day1/solve.gleam
diff --git a/aoc2023/src/day10/.gitignore b/aoc2023-gleam/src/day10/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day10/.gitignore
+++ b/aoc2023-gleam/src/day10/.gitignore
diff --git a/aoc2023/src/day10/solve.gleam b/aoc2023-gleam/src/day10/solve.gleam
index c33634d..c33634d 100644
--- a/aoc2023/src/day10/solve.gleam
+++ b/aoc2023-gleam/src/day10/solve.gleam
diff --git a/aoc2023/src/day11/.gitignore b/aoc2023-gleam/src/day11/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day11/.gitignore
+++ b/aoc2023-gleam/src/day11/.gitignore
diff --git a/aoc2023/src/day11/solve.gleam b/aoc2023-gleam/src/day11/solve.gleam
index 35464a1..35464a1 100644
--- a/aoc2023/src/day11/solve.gleam
+++ b/aoc2023-gleam/src/day11/solve.gleam
diff --git a/aoc2023/src/day12/.gitignore b/aoc2023-gleam/src/day12/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day12/.gitignore
+++ b/aoc2023-gleam/src/day12/.gitignore
diff --git a/aoc2023/src/day12/solve.gleam b/aoc2023-gleam/src/day12/solve.gleam
index 893b83c..893b83c 100644
--- a/aoc2023/src/day12/solve.gleam
+++ b/aoc2023-gleam/src/day12/solve.gleam
diff --git a/aoc2023/src/day13/.gitignore b/aoc2023-gleam/src/day13/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day13/.gitignore
+++ b/aoc2023-gleam/src/day13/.gitignore
diff --git a/aoc2023/src/day13/solve.gleam b/aoc2023-gleam/src/day13/solve.gleam
index 6f9b9a0..6f9b9a0 100644
--- a/aoc2023/src/day13/solve.gleam
+++ b/aoc2023-gleam/src/day13/solve.gleam
diff --git a/aoc2023/src/day14/.gitignore b/aoc2023-gleam/src/day14/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day14/.gitignore
+++ b/aoc2023-gleam/src/day14/.gitignore
diff --git a/aoc2023/src/day14/solve.gleam b/aoc2023-gleam/src/day14/solve.gleam
index ecc5361..ecc5361 100644
--- a/aoc2023/src/day14/solve.gleam
+++ b/aoc2023-gleam/src/day14/solve.gleam
diff --git a/aoc2023/src/day15/.gitignore b/aoc2023-gleam/src/day15/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day15/.gitignore
+++ b/aoc2023-gleam/src/day15/.gitignore
diff --git a/aoc2023/src/day15/solve.gleam b/aoc2023-gleam/src/day15/solve.gleam
index a7d250c..a7d250c 100644
--- a/aoc2023/src/day15/solve.gleam
+++ b/aoc2023-gleam/src/day15/solve.gleam
diff --git a/aoc2023/src/day16/.gitignore b/aoc2023-gleam/src/day16/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day16/.gitignore
+++ b/aoc2023-gleam/src/day16/.gitignore
diff --git a/aoc2023/src/day16/solve.gleam b/aoc2023-gleam/src/day16/solve.gleam
index 65ce36b..65ce36b 100644
--- a/aoc2023/src/day16/solve.gleam
+++ b/aoc2023-gleam/src/day16/solve.gleam
diff --git a/aoc2023/src/day17/.gitignore b/aoc2023-gleam/src/day17/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day17/.gitignore
+++ b/aoc2023-gleam/src/day17/.gitignore
diff --git a/aoc2023/src/day17/solve.gleam b/aoc2023-gleam/src/day17/solve.gleam
index 7a01c4d..7a01c4d 100644
--- a/aoc2023/src/day17/solve.gleam
+++ b/aoc2023-gleam/src/day17/solve.gleam
diff --git a/aoc2023/src/day18/.gitignore b/aoc2023-gleam/src/day18/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day18/.gitignore
+++ b/aoc2023-gleam/src/day18/.gitignore
diff --git a/aoc2023/src/day18/solve.gleam b/aoc2023-gleam/src/day18/solve.gleam
index 2c000f9..2c000f9 100644
--- a/aoc2023/src/day18/solve.gleam
+++ b/aoc2023-gleam/src/day18/solve.gleam
diff --git a/aoc2023/src/day19/.gitignore b/aoc2023-gleam/src/day19/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day19/.gitignore
+++ b/aoc2023-gleam/src/day19/.gitignore
diff --git a/aoc2023/src/day19/solve.gleam b/aoc2023-gleam/src/day19/solve.gleam
index 186e783..186e783 100644
--- a/aoc2023/src/day19/solve.gleam
+++ b/aoc2023-gleam/src/day19/solve.gleam
diff --git a/aoc2023/src/day2/.gitignore b/aoc2023-gleam/src/day2/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day2/.gitignore
+++ b/aoc2023-gleam/src/day2/.gitignore
diff --git a/aoc2023/src/day2/solve.gleam b/aoc2023-gleam/src/day2/solve.gleam
index 608955f..608955f 100644
--- a/aoc2023/src/day2/solve.gleam
+++ b/aoc2023-gleam/src/day2/solve.gleam
diff --git a/aoc2023/src/day20/.gitignore b/aoc2023-gleam/src/day20/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day20/.gitignore
+++ b/aoc2023-gleam/src/day20/.gitignore
diff --git a/aoc2023/src/day20/solve.gleam b/aoc2023-gleam/src/day20/solve.gleam
index 9192dac..9192dac 100644
--- a/aoc2023/src/day20/solve.gleam
+++ b/aoc2023-gleam/src/day20/solve.gleam
diff --git a/aoc2023/src/day22/.gitignore b/aoc2023-gleam/src/day21/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day22/.gitignore
+++ b/aoc2023-gleam/src/day21/.gitignore
diff --git a/aoc2023-gleam/src/day21/solve.gleam b/aoc2023-gleam/src/day21/solve.gleam
new file mode 100644
index 0000000..4d5c246
--- /dev/null
+++ b/aoc2023-gleam/src/day21/solve.gleam
@@ -0,0 +1,25 @@
+import adglent.{First, Second}
+import gleam/io
+
+pub fn part1(input: String) {
+ todo as "Implement solution to part 1"
+}
+
+pub fn part2(input: String) {
+ todo as "Implement solution to part 2"
+}
+
+pub fn main() {
+ let assert Ok(part) = adglent.get_part()
+ let assert Ok(input) = adglent.get_input("21")
+ case part {
+ First ->
+ part1(input)
+ |> adglent.inspect
+ |> io.println
+ Second ->
+ part2(input)
+ |> adglent.inspect
+ |> io.println
+ }
+}
diff --git a/aoc2023/src/day23/.gitignore b/aoc2023-gleam/src/day22/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day23/.gitignore
+++ b/aoc2023-gleam/src/day22/.gitignore
diff --git a/aoc2023/src/day22/solve.gleam b/aoc2023-gleam/src/day22/solve.gleam
index 7bf2fb4..7bf2fb4 100644
--- a/aoc2023/src/day22/solve.gleam
+++ b/aoc2023-gleam/src/day22/solve.gleam
diff --git a/aoc2023/src/day3/.gitignore b/aoc2023-gleam/src/day23/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day3/.gitignore
+++ b/aoc2023-gleam/src/day23/.gitignore
diff --git a/aoc2023/src/day23/solve.gleam b/aoc2023-gleam/src/day23/solve.gleam
index e1fe638..e1fe638 100644
--- a/aoc2023/src/day23/solve.gleam
+++ b/aoc2023-gleam/src/day23/solve.gleam
diff --git a/aoc2023/src/day4/.gitignore b/aoc2023-gleam/src/day3/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day4/.gitignore
+++ b/aoc2023-gleam/src/day3/.gitignore
diff --git a/aoc2023/src/day3/solve.gleam b/aoc2023-gleam/src/day3/solve.gleam
index ad975aa..ad975aa 100644
--- a/aoc2023/src/day3/solve.gleam
+++ b/aoc2023-gleam/src/day3/solve.gleam
diff --git a/aoc2023/src/day5/.gitignore b/aoc2023-gleam/src/day4/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day5/.gitignore
+++ b/aoc2023-gleam/src/day4/.gitignore
diff --git a/aoc2023/src/day4/solve.gleam b/aoc2023-gleam/src/day4/solve.gleam
index 34d6098..34d6098 100644
--- a/aoc2023/src/day4/solve.gleam
+++ b/aoc2023-gleam/src/day4/solve.gleam
diff --git a/aoc2023/src/day6/.gitignore b/aoc2023-gleam/src/day5/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day6/.gitignore
+++ b/aoc2023-gleam/src/day5/.gitignore
diff --git a/aoc2023/src/day5/solve.gleam b/aoc2023-gleam/src/day5/solve.gleam
index 7c05310..7c05310 100644
--- a/aoc2023/src/day5/solve.gleam
+++ b/aoc2023-gleam/src/day5/solve.gleam
diff --git a/aoc2023/src/day7/.gitignore b/aoc2023-gleam/src/day6/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day7/.gitignore
+++ b/aoc2023-gleam/src/day6/.gitignore
diff --git a/aoc2023/src/day6/solve.gleam b/aoc2023-gleam/src/day6/solve.gleam
index 88044c4..88044c4 100644
--- a/aoc2023/src/day6/solve.gleam
+++ b/aoc2023-gleam/src/day6/solve.gleam
diff --git a/aoc2023/src/day8/.gitignore b/aoc2023-gleam/src/day7/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day8/.gitignore
+++ b/aoc2023-gleam/src/day7/.gitignore
diff --git a/aoc2023/src/day7/solve.gleam b/aoc2023-gleam/src/day7/solve.gleam
index 4454883..4454883 100644
--- a/aoc2023/src/day7/solve.gleam
+++ b/aoc2023-gleam/src/day7/solve.gleam
diff --git a/aoc2023/src/day9/.gitignore b/aoc2023-gleam/src/day8/.gitignore
index ae40cea..ae40cea 100644
--- a/aoc2023/src/day9/.gitignore
+++ b/aoc2023-gleam/src/day8/.gitignore
diff --git a/aoc2023/src/day8/solve.gleam b/aoc2023-gleam/src/day8/solve.gleam
index 6b36e2d..6b36e2d 100644
--- a/aoc2023/src/day8/solve.gleam
+++ b/aoc2023-gleam/src/day8/solve.gleam
diff --git a/aoc2023-gleam/src/day9/.gitignore b/aoc2023-gleam/src/day9/.gitignore
new file mode 100644
index 0000000..ae40cea
--- /dev/null
+++ b/aoc2023-gleam/src/day9/.gitignore
@@ -0,0 +1 @@
+input.txt \ No newline at end of file
diff --git a/aoc2023/src/day9/solve.gleam b/aoc2023-gleam/src/day9/solve.gleam
index a2cc7ae..a2cc7ae 100644
--- a/aoc2023/src/day9/solve.gleam
+++ b/aoc2023-gleam/src/day9/solve.gleam
diff --git a/aoc2023/src/utilities/array2d.gleam b/aoc2023-gleam/src/utilities/array2d.gleam
index 8538129..8538129 100644
--- a/aoc2023/src/utilities/array2d.gleam
+++ b/aoc2023-gleam/src/utilities/array2d.gleam
diff --git a/aoc2023/src/utilities/memo.gleam b/aoc2023-gleam/src/utilities/memo.gleam
index b06d8fd..b06d8fd 100644
--- a/aoc2023/src/utilities/memo.gleam
+++ b/aoc2023-gleam/src/utilities/memo.gleam
diff --git a/aoc2023/src/utilities/prioqueue.gleam b/aoc2023-gleam/src/utilities/prioqueue.gleam
index abf21b9..abf21b9 100644
--- a/aoc2023/src/utilities/prioqueue.gleam
+++ b/aoc2023-gleam/src/utilities/prioqueue.gleam
diff --git a/aoc2023/test/aoc2023_test.gleam b/aoc2023-gleam/test/aoc2023_test.gleam
index 2b696a4..2b696a4 100644
--- a/aoc2023/test/aoc2023_test.gleam
+++ b/aoc2023-gleam/test/aoc2023_test.gleam
diff --git a/aoc2023/test/day1/day1_test.gleam b/aoc2023-gleam/test/day1/day1_test.gleam
index 374653c..374653c 100644
--- a/aoc2023/test/day1/day1_test.gleam
+++ b/aoc2023-gleam/test/day1/day1_test.gleam
diff --git a/aoc2023/test/day10/day10_test.gleam b/aoc2023-gleam/test/day10/day10_test.gleam
index be9d82e..be9d82e 100644
--- a/aoc2023/test/day10/day10_test.gleam
+++ b/aoc2023-gleam/test/day10/day10_test.gleam
diff --git a/aoc2023/test/day11/day11_test.gleam b/aoc2023-gleam/test/day11/day11_test.gleam
index 8bb8c06..8bb8c06 100644
--- a/aoc2023/test/day11/day11_test.gleam
+++ b/aoc2023-gleam/test/day11/day11_test.gleam
diff --git a/aoc2023/test/day12/day12_test.gleam b/aoc2023-gleam/test/day12/day12_test.gleam
index 3daf0e9..3daf0e9 100644
--- a/aoc2023/test/day12/day12_test.gleam
+++ b/aoc2023-gleam/test/day12/day12_test.gleam
diff --git a/aoc2023/test/day13/day13_test.gleam b/aoc2023-gleam/test/day13/day13_test.gleam
index 7c65bed..7c65bed 100644
--- a/aoc2023/test/day13/day13_test.gleam
+++ b/aoc2023-gleam/test/day13/day13_test.gleam
diff --git a/aoc2023/test/day14/day14_test.gleam b/aoc2023-gleam/test/day14/day14_test.gleam
index 8efa74e..8efa74e 100644
--- a/aoc2023/test/day14/day14_test.gleam
+++ b/aoc2023-gleam/test/day14/day14_test.gleam
diff --git a/aoc2023/test/day15/day15_test.gleam b/aoc2023-gleam/test/day15/day15_test.gleam
index 0ecaecc..0ecaecc 100644
--- a/aoc2023/test/day15/day15_test.gleam
+++ b/aoc2023-gleam/test/day15/day15_test.gleam
diff --git a/aoc2023/test/day16/day16_test.gleam b/aoc2023-gleam/test/day16/day16_test.gleam
index 036504e..036504e 100644
--- a/aoc2023/test/day16/day16_test.gleam
+++ b/aoc2023-gleam/test/day16/day16_test.gleam
diff --git a/aoc2023/test/day17/day17_test.gleam b/aoc2023-gleam/test/day17/day17_test.gleam
index 2ce48e2..2ce48e2 100644
--- a/aoc2023/test/day17/day17_test.gleam
+++ b/aoc2023-gleam/test/day17/day17_test.gleam
diff --git a/aoc2023/test/day18/day18_test.gleam b/aoc2023-gleam/test/day18/day18_test.gleam
index 7b510c8..7b510c8 100644
--- a/aoc2023/test/day18/day18_test.gleam
+++ b/aoc2023-gleam/test/day18/day18_test.gleam
diff --git a/aoc2023/test/day19/day19_test.gleam b/aoc2023-gleam/test/day19/day19_test.gleam
index c911de5..c911de5 100644
--- a/aoc2023/test/day19/day19_test.gleam
+++ b/aoc2023-gleam/test/day19/day19_test.gleam
diff --git a/aoc2023/test/day2/day2_test.gleam b/aoc2023-gleam/test/day2/day2_test.gleam
index 28a65da..28a65da 100644
--- a/aoc2023/test/day2/day2_test.gleam
+++ b/aoc2023-gleam/test/day2/day2_test.gleam
diff --git a/aoc2023/test/day20/day20_test.gleam b/aoc2023-gleam/test/day20/day20_test.gleam
index 9b79b05..9b79b05 100644
--- a/aoc2023/test/day20/day20_test.gleam
+++ b/aoc2023-gleam/test/day20/day20_test.gleam
diff --git a/aoc2023-gleam/test/day21/day21_test.gleam b/aoc2023-gleam/test/day21/day21_test.gleam
new file mode 100644
index 0000000..5f46808
--- /dev/null
+++ b/aoc2023-gleam/test/day21/day21_test.gleam
@@ -0,0 +1,38 @@
+import gleam/list
+import showtime/tests/should
+import adglent.{type Example, Example}
+import day21/solve
+
+type Problem1AnswerType =
+ String
+
+type Problem2AnswerType =
+ String
+
+/// Add examples for part 1 here:
+/// ```gleam
+///const part1_examples: List(Example(Problem1AnswerType)) = [Example("some input", "")]
+/// ```
+const part1_examples: List(Example(Problem1AnswerType)) = []
+
+/// Add examples for part 2 here:
+/// ```gleam
+///const part2_examples: List(Example(Problem2AnswerType)) = [Example("some input", "")]
+/// ```
+const part2_examples: List(Example(Problem2AnswerType)) = []
+
+pub fn part1_test() {
+ part1_examples
+ |> should.not_equal([])
+ use example <- list.map(part1_examples)
+ solve.part1(example.input)
+ |> should.equal(example.answer)
+}
+
+pub fn part2_test() {
+ part2_examples
+ |> should.not_equal([])
+ use example <- list.map(part2_examples)
+ solve.part2(example.input)
+ |> should.equal(example.answer)
+}
diff --git a/aoc2023/test/day22/day22_test.gleam b/aoc2023-gleam/test/day22/day22_test.gleam
index 3f8c0ca..3f8c0ca 100644
--- a/aoc2023/test/day22/day22_test.gleam
+++ b/aoc2023-gleam/test/day22/day22_test.gleam
diff --git a/aoc2023/test/day23/day23_test.gleam b/aoc2023-gleam/test/day23/day23_test.gleam
index 206571c..206571c 100644
--- a/aoc2023/test/day23/day23_test.gleam
+++ b/aoc2023-gleam/test/day23/day23_test.gleam
diff --git a/aoc2023/test/day3/day3_test.gleam b/aoc2023-gleam/test/day3/day3_test.gleam
index 30e17a9..30e17a9 100644
--- a/aoc2023/test/day3/day3_test.gleam
+++ b/aoc2023-gleam/test/day3/day3_test.gleam
diff --git a/aoc2023/test/day4/day4_test.gleam b/aoc2023-gleam/test/day4/day4_test.gleam
index 324fe36..324fe36 100644
--- a/aoc2023/test/day4/day4_test.gleam
+++ b/aoc2023-gleam/test/day4/day4_test.gleam
diff --git a/aoc2023/test/day5/day5_test.gleam b/aoc2023-gleam/test/day5/day5_test.gleam
index 86a8692..86a8692 100644
--- a/aoc2023/test/day5/day5_test.gleam
+++ b/aoc2023-gleam/test/day5/day5_test.gleam
diff --git a/aoc2023/test/day6/day6_test.gleam b/aoc2023-gleam/test/day6/day6_test.gleam
index c551993..c551993 100644
--- a/aoc2023/test/day6/day6_test.gleam
+++ b/aoc2023-gleam/test/day6/day6_test.gleam
diff --git a/aoc2023/test/day7/day7_test.gleam b/aoc2023-gleam/test/day7/day7_test.gleam
index f7f8454..f7f8454 100644
--- a/aoc2023/test/day7/day7_test.gleam
+++ b/aoc2023-gleam/test/day7/day7_test.gleam
diff --git a/aoc2023/test/day8/day8_test.gleam b/aoc2023-gleam/test/day8/day8_test.gleam
index 2cd499a..2cd499a 100644
--- a/aoc2023/test/day8/day8_test.gleam
+++ b/aoc2023-gleam/test/day8/day8_test.gleam
diff --git a/aoc2023/test/day9/day9_test.gleam b/aoc2023-gleam/test/day9/day9_test.gleam
index 84fd3ba..84fd3ba 100644
--- a/aoc2023/test/day9/day9_test.gleam
+++ b/aoc2023-gleam/test/day9/day9_test.gleam
diff --git a/aoc2023-other/day-01/day-01.rkt b/aoc2023-racket/day-01/day-01.rkt
index b720f79..b720f79 100644
--- a/aoc2023-other/day-01/day-01.rkt
+++ b/aoc2023-racket/day-01/day-01.rkt
diff --git a/aoc2023-other/day-02/day-02-parser.rkt b/aoc2023-racket/day-02/day-02-parser.rkt
index 76cc24f..76cc24f 100644
--- a/aoc2023-other/day-02/day-02-parser.rkt
+++ b/aoc2023-racket/day-02/day-02-parser.rkt
diff --git a/aoc2023-other/day-02/day-02.rkt b/aoc2023-racket/day-02/day-02.rkt
index 973d20c..973d20c 100644
--- a/aoc2023-other/day-02/day-02.rkt
+++ b/aoc2023-racket/day-02/day-02.rkt
diff --git a/aoc2023-other/day-03/day-03.rkt b/aoc2023-racket/day-03/day-03.rkt
index 60e81a6..60e81a6 100644
--- a/aoc2023-other/day-03/day-03.rkt
+++ b/aoc2023-racket/day-03/day-03.rkt
diff --git a/aoc2023-other/day-04/day-04.rkt b/aoc2023-racket/day-04/day-04.rkt
index 7a357c5..7a357c5 100644
--- a/aoc2023-other/day-04/day-04.rkt
+++ b/aoc2023-racket/day-04/day-04.rkt
diff --git a/aoc2023-other/day-05/day-05.rkt b/aoc2023-racket/day-05/day-05.rkt
index 5b9aa52..5b9aa52 100644
--- a/aoc2023-other/day-05/day-05.rkt
+++ b/aoc2023-racket/day-05/day-05.rkt
diff --git a/aoc2023-other/day-06/day-06.rkt b/aoc2023-racket/day-06/day-06.rkt
index 53ca9ee..53ca9ee 100644
--- a/aoc2023-other/day-06/day-06.rkt
+++ b/aoc2023-racket/day-06/day-06.rkt
diff --git a/aoc2023-other/day-07/day-07.rkt b/aoc2023-racket/day-07/day-07.rkt
index 30e629b..30e629b 100644
--- a/aoc2023-other/day-07/day-07.rkt
+++ b/aoc2023-racket/day-07/day-07.rkt
diff --git a/aoc2023-other/day-08/day-08.rkt b/aoc2023-racket/day-08/day-08.rkt
index 06daafa..06daafa 100644
--- a/aoc2023-other/day-08/day-08.rkt
+++ b/aoc2023-racket/day-08/day-08.rkt
diff --git a/aoc2023-other/day-09/day-09-polynomial.rkt b/aoc2023-racket/day-09/day-09-polynomial.rkt
index 5bacb1f..5bacb1f 100644
--- a/aoc2023-other/day-09/day-09-polynomial.rkt
+++ b/aoc2023-racket/day-09/day-09-polynomial.rkt
diff --git a/aoc2023-other/day-09/day-09.rkt b/aoc2023-racket/day-09/day-09.rkt
index 5eda1eb..5eda1eb 100644
--- a/aoc2023-other/day-09/day-09.rkt
+++ b/aoc2023-racket/day-09/day-09.rkt
diff --git a/aoc2023-other/day-10/day-10.rkt b/aoc2023-racket/day-10/day-10.rkt
index 64d8727..64d8727 100644
--- a/aoc2023-other/day-10/day-10.rkt
+++ b/aoc2023-racket/day-10/day-10.rkt
diff --git a/aoc2023-other/day-11/day-11.rkt b/aoc2023-racket/day-11/day-11.rkt
index dba617b..dba617b 100644
--- a/aoc2023-other/day-11/day-11.rkt
+++ b/aoc2023-racket/day-11/day-11.rkt
diff --git a/aoc2023-other/day-12/day-12.rkt b/aoc2023-racket/day-12/day-12.rkt
index 50b14bb..50b14bb 100644
--- a/aoc2023-other/day-12/day-12.rkt
+++ b/aoc2023-racket/day-12/day-12.rkt
diff --git a/aoc2023-other/day-13/day-13.rkt b/aoc2023-racket/day-13/day-13.rkt
index 47718f8..47718f8 100644
--- a/aoc2023-other/day-13/day-13.rkt
+++ b/aoc2023-racket/day-13/day-13.rkt
diff --git a/aoc2023-other/day-14/day-14.rkt b/aoc2023-racket/day-14/day-14.rkt
index d0b7cad..d0b7cad 100644
--- a/aoc2023-other/day-14/day-14.rkt
+++ b/aoc2023-racket/day-14/day-14.rkt
diff --git a/aoc2023-other/day-15/day-15.rkt b/aoc2023-racket/day-15/day-15.rkt
index d049565..d049565 100644
--- a/aoc2023-other/day-15/day-15.rkt
+++ b/aoc2023-racket/day-15/day-15.rkt
diff --git a/aoc2023-other/day-16/day-16.rkt b/aoc2023-racket/day-16/day-16.rkt
index 4a70de8..4a70de8 100644
--- a/aoc2023-other/day-16/day-16.rkt
+++ b/aoc2023-racket/day-16/day-16.rkt
diff --git a/aoc2023-other/day-17/day-17.rkt b/aoc2023-racket/day-17/day-17.rkt
index 05709ad..05709ad 100644
--- a/aoc2023-other/day-17/day-17.rkt
+++ b/aoc2023-racket/day-17/day-17.rkt
diff --git a/aoc2023-other/day-18/day-18.rkt b/aoc2023-racket/day-18/day-18.rkt
index b589e41..b589e41 100644
--- a/aoc2023-other/day-18/day-18.rkt
+++ b/aoc2023-racket/day-18/day-18.rkt
diff --git a/aoc2023-other/day-19/day-19.rkt b/aoc2023-racket/day-19/day-19.rkt
index f7561f6..f7561f6 100644
--- a/aoc2023-other/day-19/day-19.rkt
+++ b/aoc2023-racket/day-19/day-19.rkt
diff --git a/aoc2023-other/day-20/day-20.rkt b/aoc2023-racket/day-20/day-20.rkt
index 2e3852d..2e3852d 100644
--- a/aoc2023-other/day-20/day-20.rkt
+++ b/aoc2023-racket/day-20/day-20.rkt
diff --git a/aoc2023-other/day-21/day-21.rkt b/aoc2023-racket/day-21/day-21.rkt
index b5478eb..b5478eb 100644
--- a/aoc2023-other/day-21/day-21.rkt
+++ b/aoc2023-racket/day-21/day-21.rkt
diff --git a/aoc2023-other/day-22/day-22.rkt b/aoc2023-racket/day-22/day-22.rkt
index 53668c0..53668c0 100644
--- a/aoc2023-other/day-22/day-22.rkt
+++ b/aoc2023-racket/day-22/day-22.rkt
diff --git a/aoc2023-other/day-23/day-23.rkt b/aoc2023-racket/day-23/day-23.rkt
index c048013..c048013 100644
--- a/aoc2023-other/day-23/day-23.rkt
+++ b/aoc2023-racket/day-23/day-23.rkt
diff --git a/aoc2023-other/day-24/day-24a.rkt b/aoc2023-racket/day-24/day-24a.rkt
index 31f526d..31f526d 100644
--- a/aoc2023-other/day-24/day-24a.rkt
+++ b/aoc2023-racket/day-24/day-24a.rkt
diff --git a/aoc2023-other/day-24/day-24b.rkt b/aoc2023-racket/day-24/day-24b.rkt
index b106b30..b106b30 100644
--- a/aoc2023-other/day-24/day-24b.rkt
+++ b/aoc2023-racket/day-24/day-24b.rkt
diff --git a/aoc2023-other/day-25/day-25.rkt b/aoc2023-racket/day-25/day-25.rkt
index aa32e43..aa32e43 100644
--- a/aoc2023-other/day-25/day-25.rkt
+++ b/aoc2023-racket/day-25/day-25.rkt
diff --git a/aoc2023/src/aoc2023.gleam b/aoc2023/src/aoc2023.gleam
deleted file mode 100644
index aab904d..0000000
--- a/aoc2023/src/aoc2023.gleam
+++ /dev/null
@@ -1,12 +0,0 @@
-import gleam/io
-import gleam/bit_array
-
-const str = "abcdefgh
-abcdefgh"
-
-pub fn main() {
- let trim = 8
- let assert <<_:bytes-size(trim), "\n":utf8, rest:bytes>> =
- bit_array.from_string(str)
- io.debug(rest)
-}
diff --git a/codingquest2024/.github/workflows/test.yml b/codingquest2024/.github/workflows/test.yml
new file mode 100644
index 0000000..916edea
--- /dev/null
+++ b/codingquest2024/.github/workflows/test.yml
@@ -0,0 +1,23 @@
+name: test
+
+on:
+ push:
+ branches:
+ - master
+ - main
+ pull_request:
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: erlef/setup-beam@v1
+ with:
+ otp-version: "26.0.2"
+ gleam-version: "1.0.0"
+ rebar3-version: "3"
+ # elixir-version: "1.15.4"
+ - run: gleam deps download
+ - run: gleam test
+ - run: gleam format --check src test
diff --git a/codingquest2024/.gitignore b/codingquest2024/.gitignore
new file mode 100644
index 0000000..6fdd6db
--- /dev/null
+++ b/codingquest2024/.gitignore
@@ -0,0 +1,5 @@
+*.beam
+*.ez
+/build
+erl_crash.dump
+data.txt
diff --git a/codingquest2024/README.md b/codingquest2024/README.md
new file mode 100644
index 0000000..8412b48
--- /dev/null
+++ b/codingquest2024/README.md
@@ -0,0 +1,25 @@
+# codingquest2024
+
+[![Package Version](https://img.shields.io/hexpm/v/codingquest2024)](https://hex.pm/packages/codingquest2024)
+[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/codingquest2024/)
+
+```sh
+gleam add codingquest2024
+```
+```gleam
+import codingquest2024
+
+pub fn main() {
+ // TODO: An example of the project in use
+}
+```
+
+Further documentation can be found at <https://hexdocs.pm/codingquest2024>.
+
+## Development
+
+```sh
+gleam run # Run the project
+gleam test # Run the tests
+gleam shell # Run an Erlang shell
+```
diff --git a/codingquest2024/gleam.toml b/codingquest2024/gleam.toml
new file mode 100644
index 0000000..f39baa5
--- /dev/null
+++ b/codingquest2024/gleam.toml
@@ -0,0 +1,22 @@
+name = "codingquest2024"
+version = "1.0.0"
+
+# Fill out these fields if you intend to generate HTML documentation or publish
+# your project to the Hex package manager.
+#
+# description = ""
+# licences = ["Apache-2.0"]
+# repository = { type = "github", user = "username", repo = "project" }
+# links = [{ title = "Website", href = "https://gleam.run" }]
+#
+# For a full reference of all the available options, you can have a look at
+# https://gleam.run/writing-gleam/gleam-toml/.
+
+[dependencies]
+gleam_stdlib = "~> 0.34 or ~> 1.0"
+simplifile = "~> 1.5"
+gleam_otp = "~> 0.10"
+gleam_erlang = "~> 0.24"
+
+[dev-dependencies]
+gleeunit = "~> 1.0"
diff --git a/codingquest2024/manifest.toml b/codingquest2024/manifest.toml
new file mode 100644
index 0000000..55b1f61
--- /dev/null
+++ b/codingquest2024/manifest.toml
@@ -0,0 +1,17 @@
+# This file was generated by Gleam
+# You typically do not need to edit this file
+
+packages = [
+ { name = "gleam_erlang", version = "0.24.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "26BDB52E61889F56A291CB34167315780EE4AA20961917314446542C90D1C1A0" },
+ { name = "gleam_otp", version = "0.10.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "0B04FE915ACECE539B317F9652CAADBBC0F000184D586AAAF2D94C100945D72B" },
+ { name = "gleam_stdlib", version = "0.36.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "C0D14D807FEC6F8A08A7C9EF8DFDE6AE5C10E40E21325B2B29365965D82EB3D4" },
+ { name = "gleeunit", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D364C87AFEB26BDB4FB8A5ABDE67D635DC9FA52D6AB68416044C35B096C6882D" },
+ { name = "simplifile", version = "1.5.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "EB9AA8E65E5C1E3E0FDCFC81BC363FD433CB122D7D062750FFDF24DE4AC40116" },
+]
+
+[requirements]
+gleam_erlang = { version = "~> 0.24"}
+gleam_otp = { version = "~> 0.10" }
+gleam_stdlib = { version = "~> 0.34 or ~> 1.0" }
+gleeunit = { version = "~> 1.0" }
+simplifile = { version = "~> 1.5" }
diff --git a/codingquest2024/src/codingquest2024.gleam b/codingquest2024/src/codingquest2024.gleam
new file mode 100644
index 0000000..5af4a2a
--- /dev/null
+++ b/codingquest2024/src/codingquest2024.gleam
@@ -0,0 +1,5 @@
+import gleam/io
+
+pub fn main() {
+ io.println("Hello from codingquest2024!")
+}
diff --git a/codingquest2024/src/day1/solution.gleam b/codingquest2024/src/day1/solution.gleam
new file mode 100644
index 0000000..abef2eb
--- /dev/null
+++ b/codingquest2024/src/day1/solution.gleam
@@ -0,0 +1,55 @@
+import gleam/dict.{type Dict}
+import gleam/int
+import gleam/io
+import gleam/list
+import gleam/option.{None, Some}
+import gleam/regex
+import gleam/result
+import gleam/string
+import simplifile
+
+pub type Adjustment {
+ Adjustment(spaceliner: String, value: Int)
+}
+
+pub fn main() {
+ let assert Ok(data) = simplifile.read(from: "./src/day1/data.txt")
+
+ let raw_adjustments = string.split(data, "\n")
+
+ raw_adjustments
+ |> collate_adjustments
+ |> dict.values
+ |> list.reduce(with: int.min)
+ |> result.unwrap(0)
+ |> int.to_string()
+ |> io.println()
+}
+
+fn parse_line(line: String) -> Adjustment {
+ let assert Ok(re) = regex.from_string("[\\s:]+")
+
+ let assert [spaceliner, kind, raw_value] =
+ regex.split(with: re, content: line)
+
+ let assert Ok(value) = int.parse(raw_value)
+ Adjustment(spaceliner, classify_adjustment(kind) * value)
+}
+
+fn classify_adjustment(name: String) -> Int {
+ case name {
+ "Seat" | "Meals" | "Luggage" | "Fee" | "Tax" -> 1
+ "Discount" | "Rebate" -> -1
+ _ -> panic as "unknown adjustment kind"
+ }
+}
+
+fn collate_adjustments(raw_adjustments: List(String)) -> Dict(String, Int) {
+ use acc, this <- list.fold(over: raw_adjustments, from: dict.new())
+ let adjustment = parse_line(this)
+ use maybe_v <- dict.update(in: acc, update: adjustment.spaceliner)
+ case maybe_v {
+ None -> adjustment.value
+ Some(v) -> v + adjustment.value
+ }
+}
diff --git a/codingquest2024/src/day2/solution.gleam b/codingquest2024/src/day2/solution.gleam
new file mode 100644
index 0000000..59f8d29
--- /dev/null
+++ b/codingquest2024/src/day2/solution.gleam
@@ -0,0 +1,66 @@
+import gleam/bit_array
+import gleam/list
+import gleam/int
+import gleam/io
+import gleam/string
+import simplifile
+
+pub type Location {
+ Internal
+ Passenger
+ Other
+}
+
+pub type Packet {
+ Packet(length: Int, endpoint: Location)
+}
+
+pub fn main() {
+ let assert Ok(data) = simplifile.read(from: "./src/day2/data.txt")
+
+ let #(internal_packets, passenger_packets) =
+ data
+ |> string.split("\n")
+ |> list.map(parse_packet)
+ |> list.partition(fn(p) { p.endpoint == Internal })
+
+ {
+ int.to_string(sum_packet_lengths(internal_packets))
+ <> "/"
+ <> int.to_string(sum_packet_lengths(passenger_packets))
+ }
+ |> io.println()
+}
+
+fn parse_packet(raw_packet: String) {
+ let assert Ok(<<
+ _:bytes-size(2),
+ length:int-size(16),
+ _:bytes-size(8),
+ source:bytes-size(4),
+ destination:bytes-size(4),
+ >>) = bit_array.base16_decode(raw_packet)
+
+ Packet(length, set_endpoint(source, destination))
+}
+
+fn set_endpoint(source: BitArray, dest: BitArray) -> Location {
+ case identify_location(source), identify_location(dest) {
+ Other, Internal | Internal, Other -> Internal
+ Other, Passenger | Passenger, Other -> Passenger
+ _, _ -> Other
+ }
+}
+
+fn identify_location(ip: BitArray) -> Location {
+ case ip {
+ <<192, 168, _, _>> -> Internal
+ <<10, 0, _, _>> -> Passenger
+ _ -> Other
+ }
+}
+
+fn sum_packet_lengths(packets: List(Packet)) -> Int {
+ use acc, p <- list.fold(packets, 0)
+ acc + p.length
+}
diff --git a/codingquest2024/src/day3/solution.gleam b/codingquest2024/src/day3/solution.gleam
new file mode 100644
index 0000000..6314060
--- /dev/null
+++ b/codingquest2024/src/day3/solution.gleam
@@ -0,0 +1,50 @@
+import gleam/bit_array
+import gleam/int
+import gleam/io
+import gleam/string
+import gleam/string_builder.{type StringBuilder}
+import simplifile
+
+pub fn main() {
+ let assert Ok(data) = simplifile.read(from: "./src/day3/data.txt")
+
+ data
+ |> string.split(" ")
+ |> build_flat_image(" ", string_builder.new())
+ |> bit_array.from_string()
+ |> print_next_slice()
+}
+
+fn build_flat_image(
+ nums: List(String),
+ pixel: String,
+ acc: StringBuilder,
+) -> String {
+ case nums {
+ [] -> string_builder.to_string(acc)
+ [h, ..t] -> {
+ let assert Ok(n) = int.parse(h)
+ let pixels = string.repeat(pixel, n)
+ build_flat_image(t, next_pixel(pixel), string_builder.append(acc, pixels))
+ }
+ }
+}
+
+fn print_next_slice(str: BitArray) -> Nil {
+ case str {
+ <<slice:bytes-size(100), rest:bytes>> -> {
+ let assert Ok(out) = bit_array.to_string(slice)
+ io.println(out)
+ print_next_slice(rest)
+ }
+ _ -> Nil
+ }
+}
+
+fn next_pixel(p: String) -> String {
+ case p {
+ " " -> "#"
+ "#" -> " "
+ _ -> panic
+ }
+}
diff --git a/codingquest2024/src/day4/solution.gleam b/codingquest2024/src/day4/solution.gleam
new file mode 100644
index 0000000..a03b2be
--- /dev/null
+++ b/codingquest2024/src/day4/solution.gleam
@@ -0,0 +1,49 @@
+import gleam/float
+import gleam/io
+import gleam/list
+import gleam/regex
+import gleam/result
+import gleam/string
+import simplifile
+
+pub type Star {
+ Star(name: String, x: Float, y: Float, z: Float)
+}
+
+pub fn main() {
+ let assert Ok(data) = simplifile.read(from: "./src/day4/data.txt")
+
+ let assert [_, ..stars] = string.split(data, "\n")
+
+ stars
+ |> list.map(parse_star_record)
+ |> list.combination_pairs()
+ |> list.map(star_distance)
+ |> list.reduce(float.min)
+ |> io.debug
+}
+
+fn parse_star_record(str: String) -> Star {
+ let assert Ok(re) = regex.from_string("\\s{2,}")
+
+ let assert [name, ..coords] = regex.split(with: re, content: str)
+ let assert [_, x, y, z] =
+ coords
+ |> list.map(float.parse)
+ |> result.values
+
+ Star(name, x, y, z)
+}
+
+fn star_distance(stars: #(Star, Star)) -> Float {
+ let #(star1, star2) = stars
+ let assert Ok(dist) =
+ float.square_root(
+ sq(star1.x -. star2.x) +. sq(star1.y -. star2.y) +. sq(star1.z -. star2.z),
+ )
+ dist
+}
+
+fn sq(x: Float) -> Float {
+ x *. x
+}
diff --git a/codingquest2024/src/day5/solution.gleam b/codingquest2024/src/day5/solution.gleam
new file mode 100644
index 0000000..6c10693
--- /dev/null
+++ b/codingquest2024/src/day5/solution.gleam
@@ -0,0 +1,67 @@
+import gleam/dict.{type Dict}
+import gleam/io
+import gleam/int
+import gleam/list
+import gleam/regex
+import gleam/result
+import gleam/string
+import simplifile
+
+type Atlas =
+ Dict(String, Dict(String, Int))
+
+pub fn main() {
+ let assert Ok(data) = simplifile.read(from: "./src/day5/data.txt")
+
+ let assert [table, routes] = string.split(data, "\n\n")
+ let assert [header, ..rows] = string.split(table, "\n")
+
+ let dests =
+ header
+ |> string.trim()
+ |> split_on_many_spaces
+
+ let atlas = build_atlas(rows, dests)
+
+ routes
+ |> string.split("\n")
+ |> list.fold(0, fn(acc, route) { acc + find_total_distance(route, atlas) })
+ |> io.debug
+}
+
+fn split_on_many_spaces(str) {
+ let assert Ok(re_spaces) = regex.from_string("\\s+")
+ regex.split(re_spaces, str)
+}
+
+fn build_atlas(rows, dests) {
+ rows
+ |> list.map(split_on_many_spaces)
+ |> list.fold(dict.new(), fn(acc, row) {
+ let assert [from, ..raw_dists] = row
+ let assert Ok(dists) = list.try_map(raw_dists, int.parse)
+ let to_dict =
+ dests
+ |> list.zip(dists)
+ |> dict.from_list()
+
+ dict.insert(acc, from, to_dict)
+ })
+}
+
+fn dist_between(leg: #(String, String), dict: Atlas) -> Int {
+ let assert Ok(dist) =
+ dict
+ |> dict.get(leg.0)
+ |> result.try(dict.get(_, leg.1))
+
+ dist
+}
+
+fn find_total_distance(row: String, atlas: Atlas) {
+ let assert [_, route] = string.split(row, ": ")
+
+ string.split(route, " -> ")
+ |> list.window_by_2
+ |> list.fold(0, fn(acc, leg) { acc + dist_between(leg, atlas) })
+}
diff --git a/codingquest2024/src/day6/solution.gleam b/codingquest2024/src/day6/solution.gleam
new file mode 100644
index 0000000..8a0319c
--- /dev/null
+++ b/codingquest2024/src/day6/solution.gleam
@@ -0,0 +1,86 @@
+import gleam/dict
+import gleam/io
+import gleam/list
+import gleam/regex
+import gleam/result
+import gleam/string
+import simplifile
+
+pub opaque type Location {
+ Location(row: Int, col: Int)
+}
+
+pub fn main() {
+ let assert Ok(data) = simplifile.read(from: "./src/day6/data.txt")
+ let assert ["Cipher key: " <> key, "Message: " <> raw_message] =
+ string.split(data, "\n")
+
+ let letter_to_location = make_cipher_grid(key)
+ let location_to_letter =
+ letter_to_location
+ |> dict.fold(dict.new(), fn(acc, k, v) { dict.insert(acc, v, k) })
+
+ raw_message
+ |> string.split(" ")
+ |> list.map(fn(s) {
+ s
+ |> string.to_graphemes
+ |> list.sized_chunk(2)
+ })
+ |> list.map(fn(s) {
+ s
+ |> decode_word(letter_to_location, location_to_letter)
+ |> string.concat()
+ })
+ |> string.join(" ")
+ |> io.println()
+}
+
+fn make_cipher_grid(key) {
+ let assert Ok(in_key) = regex.from_string("[" <> key <> "]")
+ let grid =
+ regex.split(in_key, "abcdefghiklmnopqrstuvwxyz")
+ |> string.concat
+ |> string.append(key, _)
+ |> string.to_graphemes
+ |> list.sized_chunk(5)
+
+ list.index_map(grid, fn(row, r) {
+ list.index_map(row, fn(cell, c) { #(cell, Location(r, c)) })
+ })
+ |> list.flatten
+ |> dict.from_list
+}
+
+fn decode_word(word: List(List(String)), to_loc, to_letter) {
+ case word {
+ [] -> []
+ [[a, b], ..rest] -> [
+ transform_pair(a, b, to_loc, to_letter),
+ ..decode_word(rest, to_loc, to_letter)
+ ]
+ _ -> panic as "bad playfair format"
+ }
+}
+
+fn transform_pair(a, b, to_loc, to_letter) {
+ let assert Ok(Location(r_a, c_a)) = dict.get(to_loc, a)
+ let assert Ok(Location(r_b, c_b)) = dict.get(to_loc, b)
+
+ case r_a == r_b, c_a == c_b {
+ True, _ -> [
+ dict.get(to_letter, Location(r_a, { c_a + 4 } % 5)),
+ dict.get(to_letter, Location(r_b, { c_b + 4 } % 5)),
+ ]
+ _, True -> [
+ dict.get(to_letter, Location({ r_a + 4 } % 5, c_a)),
+ dict.get(to_letter, Location({ r_b + 4 } % 5, c_b)),
+ ]
+ _, _ -> [
+ dict.get(to_letter, Location(r_a, c_b)),
+ dict.get(to_letter, Location(r_b, c_a)),
+ ]
+ }
+ |> result.values
+ |> string.concat
+}
diff --git a/codingquest2024/src/day7/solution.gleam b/codingquest2024/src/day7/solution.gleam
new file mode 100644
index 0000000..2ca7cbf
--- /dev/null
+++ b/codingquest2024/src/day7/solution.gleam
@@ -0,0 +1,73 @@
+import gleam/io
+import gleam/string
+import gleam/set.{type Set}
+import gleam/int
+import gleam/regex.{Match}
+import gleam/option.{Some}
+import simplifile
+
+pub opaque type Item {
+ File(name: String, size: Int)
+ Directory(name: String)
+}
+
+pub fn main() {
+ let assert Ok(data) = simplifile.read(from: "./src/day7/data.txt")
+ let lines = string.split(data, "\n")
+
+ mark_for_deletion(lines, 0, "", set.new())
+ |> io.debug()
+}
+
+fn mark_for_deletion(
+ lines: List(String),
+ deleted: Int,
+ current_folder: String,
+ deleted_folders: Set(String),
+) {
+ case lines {
+ [] -> deleted
+ ["Folder: " <> folder, ..rest] ->
+ mark_for_deletion(rest, deleted, folder, deleted_folders)
+ [file, ..rest] -> {
+ case
+ string.contains(file, "temporary")
+ || string.contains(file, "delete")
+ || set.contains(deleted_folders, current_folder)
+ {
+ True ->
+ case string.contains(file, "[FOLDER") {
+ True -> {
+ file
+ |> get_folder_number()
+ |> set.insert(deleted_folders, _)
+ |> mark_for_deletion(rest, deleted, current_folder, _)
+ }
+ False -> {
+ file
+ |> get_file_size()
+ |> int.add(deleted, _)
+ |> mark_for_deletion(rest, _, current_folder, deleted_folders)
+ }
+ }
+ False ->
+ mark_for_deletion(rest, deleted, current_folder, deleted_folders)
+ }
+ }
+ }
+}
+
+fn get_folder_number(file) {
+ let assert Ok(re) = regex.from_string("\\[FOLDER ([0-9]+)\\]")
+
+ let assert [Match(submatches: [Some(n)], ..)] = regex.scan(re, file)
+ n
+}
+
+fn get_file_size(file) {
+ let assert Ok(re) = regex.from_string("- .+ ([0-9]+)$")
+
+ let assert [Match(submatches: [Some(n)], ..)] = regex.scan(re, file)
+ let assert Ok(n) = int.parse(n)
+ n
+}
diff --git a/codingquest2024/src/day8/solution.gleam b/codingquest2024/src/day8/solution.gleam
new file mode 100644
index 0000000..cb4d907
--- /dev/null
+++ b/codingquest2024/src/day8/solution.gleam
@@ -0,0 +1,26 @@
+import gleam/io
+import gleam/int
+import gleam/list
+import utilities/memo
+
+const options = [40, 12, 2, 1]
+
+const distance = 856
+
+pub fn main() {
+ use cache <- memo.create()
+ solve(distance, cache)
+ |> io.debug
+}
+
+fn solve(target, cache) {
+ use <- memo.memoize(cache, target)
+ case target {
+ 0 -> 1
+ _ ->
+ options
+ |> list.filter(fn(n) { n <= target })
+ |> list.map(fn(n) { solve(target - n, cache) })
+ |> int.sum
+ }
+}
diff --git a/codingquest2024/src/day9/input.txt b/codingquest2024/src/day9/input.txt
new file mode 100644
index 0000000..1d30914
--- /dev/null
+++ b/codingquest2024/src/day9/input.txt
@@ -0,0 +1,203 @@
+#####################################################################################################
+......#.....#.#.......#.....#.....#.....#.#.................#...............#.............#.#.......#
+#.###.#.#.#.#.#.#####.#.#.#.#.###.###.#.#.#.#######.#######.#########.#####.#.#####.#####.#.#.###.#.#
+#.#.#...#.#.#.#.#...#...#.#...#.#.....#.#.#...#...#.#...#.....#.....#.#...#.#.#...#.#...#.#...#...#.#
+#.#.#####.#.#.#.#.#.#####.#####.#######.#.###.#.#.#.#.#.#.###.#.###.#.#.#.#.#.#.#.#.#.#.#.#.###.#####
+#...#$..#.$...#$#.#.$.#.#$..#.$....$..#.$....$#.#.$.#.#$..#.$.#.#$..#.$.#..$..#.$...#$#.#.$.#.#$#...#
+###.#.#.#.#####.#.###.#.###.#.#######.#.###.###.#####.#####.###.#.###.###.###.#.#####.###.#.#.#.#.#.#
+#.#...#.#.......#...#...#...#.......#.#...#...#...#...#...#.....#.#.....#.#...#.#.....#...#...#.#.#.#
+#.#####.#########.#.#####.#.#########.###.#######.#.#.#.#.#######.###.#.###.###.#.#.#.#.#####.#.#.#.#
+#.....#.#.#.......#...#...#.#...#...#...#...#.....#.#.#.#.#.....#...#.#...#.#.#.#.#.#.#.....#.#...#.#
+#.###$#.#.$.###$####$.#.#$###.$.#.#$#.#.$##.#$####$.#.#$#.#.$.#.#$#.##$##.#$#.#.$##.#$####$.#.#$###.#
+#...#...#.......#...#.#.......#.#.#.#.#...#.#.#.....#...#...#.#...#.#...#.....#.#...#.....#.#...#.#.#
+###.#####.#####.#.#.#.#########.#.#.#.#.#.#.#.#########.#####.#####.#.#.#######.#.#.#.#.###.###.#.#.#
+#.#.#.....#...#.#.#...#...#...#.#.#.#.#.#.#.#.#...#...#...#.#...#...#.#.......#.#.#.#.#...#...#...#.#
+#.#.#.#####.#.###.###.#.#.#.#.#.#.#.###.###.#.#.#.#.#.###.#.###.#.###.#######.#.#.#.#.###.###.#####.#
+#.#.#$#...$.#..$#.#.$.#.#$#.#.$.#.#$#...$...#$..#.$.#..$#.#.$.#..$#...$.#.#$..#.$.#.#$#.#.$...#$....#
+#.#.#.#.#######.#.#.###.#.#.#####.#.#.#.#.#####.#######.#.#.#.#########.#.#.###.#.#.#.#.#.#.###.###.#
+#.#.#.#...#...#.#.#.....#.#.#.....#.#.#.#.....#.#.#...#.#...#...........#.#.....#.#.#...#.#...#.#...#
+#.#.#####.#.#.#.#.#########.#.#####.#.#.#####.#.#.#.#.#.#################.#######.#.###.#.###.#.###.#
+#.#.#.....#.#.....#.......#...#.....#.#.....#.#.#...#.#...#...#...#...#.#.........#.#...#...#.#...#.#
+#.#.#$####$.###$###.$####$####$.###$#.##$####$#.##$##.#$#.#.$.#.#$#.#.$.#.#$####$.###$####$.#.#$#.###
+#.#.#.#...#.#.......#.#...#...#...#...........#.....#.#...#.#...#...#.#.......#.#.....#...#...#.#...#
+#.#.#.###.#.#.#######.#.###.#.###.#######.#########.#.#.###.#########.#######.#.#######.#.#####.###.#
+#.#.#...#...#.....#...#.....#...#.......#.#...#.......#.#...#.......#...#...#...#.......#...#.....#.#
+#.#.#.#.#.#######.#.###########.###.###.#.#.#.#.#######.#.###.#.#######.#.#.###.#####.#####.#####.#.#
+#...#$#.#.$...#$..#.$.#..$#...$...#$#.#.$...#$#...$...#$#...$.#..$....$.#.#$#...$...#$#...$...#$#.#.#
+#.#####.###.#.#.###.#.#.#.#.#.###.#.#.#.#####.#####.#.#.###.#########.#.#.#.###.#.#.#.#.#####.#.#.#.#
+#.#.....#...#...#...#...#...#...#.#...#.#...#.......#.#...#...#...#...#...#...#...#...#.......#...#.#
+#.#.#.#.#.#######.#########.###.#.#####.#.###########.#.#.###.#.#.#.#########.#########.#######.###.#
+#.#.#.#.#.......#.#...#...#...#.#.......#...........#.#.#...#.#.#...#.......#...#...#...#.........#.#
+#.###$#.##$####$#.#.$.#.#$####$.###$####$.###$###.$##.#$###.$.#.#$###.$####$###.$.###$###.$####$###.#
+#.....#.#.....#.#...#.#.#...#.......#...#.......#...#...#.#.#...#.#...#...#.....#...#.#.....#.......#
+#######.###.#.#.#######.###.#.#####.#.#.###.#####.#.#####.#.###.###.###.#.#########.#.#.#####.#####.#
+#.#.....#...#.#.#.......#.#.#...#.....#.#...#...#.#.#.....#.#...#...#...#...........#.#.#...#.#.#...#
+#.#.#####.###.#.#.#######.#.###.#.#####.#####.#.###.#.#.###.#.###.###############.###.#.#.#.#.#.#.###
+#.#.#$....$...#$#...$....$#.#.$.#.#$..#.$...#$#...$.#.#$..#.$.#.#$#...$....$....$....$#.#.$...#$..#.#
+#.#.#.###.#.###.###.#######.#.#####.#.#####.#.#######.###.#.#.#.#.#.###########.#.#######.#####.###.#
+#...#.#.#.#...#.....#.......#.......#.#.......#.....#...#...#.#.#.#.......#.#...#.#.....#...#.......#
+#.###.#.#.###########.#####.#####.###.#####.###.###.###.#####.#.#.#######.#.#.###.#.###.#.#.#######.#
+#.#.#.#.#.#...#.....#...#...#...#...#.....#.#...#.#...#.#...#.#.#.......#...#.#.....#...#.#.#.....#.#
+#.#.#$#.#.$.#.#$###.$##.#$#.#.$.###$###.$.#.#$###.$.###$#.#.$.#.#$###.$####$#.##$####$###.$.#.#$#.#.#
+#.#.....#.#.#.#.#...#.#...#.#.#...#...#.#.#.#.....#.#.....#.#...#...#.......#.#...#.#...#.#.#.#...#.#
+#.#######.#.#.#.#.#.#.###.###.###.#.#.###.#.#####.#.#.#####.###.#.#.###.#####.#.#.#.###.###.#.#.###.#
+#...#.....#.#...#.#...#.#.....#.#...#...#.#.#.....#...#...#...#.#.#...#.#...#.#.#.#...#...#...#.#...#
+###.#.#####.#####.###.#.#######.#######.#.###.#########.#.#####.#.###.#.#.#.#.#.#.#.#.###.#.###.#.###
+#.#.#$....$...#$..#.$.#..$..#.$....$..#.$.#..$#...$.#.#$#.#.$...#$..#.$.#.#$#...$.#.#$..#.$.#..$#.#.#
+#.#.#.###.###.#.###.#.###.#.#.###.###.#.#.#.###.###.#.#.#.#.#######.#.###.#.#####.#.#####.#.#.###.#.#
+#.#.#...#...#.#.#...#.....#.#.#...#...#.#...#...#...#.#.#...#.....#.#.....#.......#.......#.#.#.....#
+#.#.#####.#.#.#.#.#########.#.#.#####.#.###.#.#####.#.#.#####.#####.###############.#########.#####.#
+#.#.....#.#.#.#.#.......#...#.#.....#.#...#...#...#...#...#.....#...#.....................#...#...#.#
+#.###$#.#.$##.#$###.$.###$###.$####$#.##$.###$#.#.$##.#$#.#.$##.#$###.$####$###.$####$###.$.#.#$#.#.#
+#.....#.#.....#...#.#.#...#.#.#...#.#...#.......#...#...#.#.#...#.#.....#.....#...#.....#.#.#.#.#.#.#
+#.#.###.#####.###.#.#.#.###.#.#.#.#.###.###########.###.#.###.###.#####.#.###.#####.###.#.#.###.#.###
+#.#...#.#...#.#...#.#.#.#.....#.#.#...#...#...#...#...#.#...#...#.....#.#...#.........#.#...#...#...#
+#.###.#.#.#.###.###.#.#.#####.#.#####.###.#.#.###.###.#.###.###.#####.###.###########.#.#####.#####.#
+#.#.#$..#.$....$#...$.#.#$..#.$....$#...$...#$....$...#$..#.$.#..$#.#.$...#$....$...#$#.#.$...#$....#
+#.#.#####.#######.###.#.#.#.#.#####.###.#########.#.#########.#.#.#.#######.#######.#.#.#.#####.###.#
+#.#.....#.....#.#.#.#...#.#.#.#.....#.#.#.......#.#.#...#...#.#.#.......#...#.....#.#.#.....#...#.#.#
+#.###.#.#####.#.#.#.#####.#.#.#.###.#.#.###.#####.#.#.#.#.#.#.#.#########.###.###.#.#########.###.#.#
+#.....#.......#.#.......#.#.#...#.#.#.#...#.#.....#.#.#.#.#.#.#...#.......#...#...#...........#.#...#
+#####$####$####$####$##.#$#.##$##.#$#.##$.#.#$####$.#.#$#.#.$.###$#.##$####$####$####$####$####$#.###
+#.........#...#.......#...#.#.....#.....#.#.#.#...#...#...#...#...#...#.....#...................#.#.#
+#.#.#####.#.#.#.#.#########.#.#.#####.###.#.#.#.#.###########.#.#####.#.#####.###.#############.#.#.#
+#.#...#.#...#.#.#.#...#.....#.#.....#.#...#...#.#.......#...#...#.....#...#...#.#.....#...#...#.#...#
+#####.#.#####.#.#.#.#.#.#########.#.#.#.#######.#######.#.#.#####.#######.#.###.#####.#.#.#.#.#####.#
+#....$#.#.$.#..$#.#.$...#$....$...#$#.#.$....$..#.$....$#.#.$....$#...$...#$....$...#$..#.$.#..$..#.#
+#.#####.#.#.#####.#.#####.###.#######.#.#.#######.#.#####.#########.#####.#####.#.#.#####.#.###.###.#
+#.#.......#.....#.#.#...#.#.#.....#...#.#.#.......#.......#.............#...#...#.#.....#.#...#...#.#
+#.###.#####.#####.#.###.#.#.#####.#.###.#.#.###.#.#########.###########.#####.#######.#.#.#.#####.#.#
+#...#...#.#.......#...#.#...#...#.....#.#.#...#.#.....#...#.#.........#.#.....#.......#.#.#.#.....#.#
+#.#.#$#.#.$####$####$.#.#$###.$.#.#$###.$.###$#.##$##.#$#.#.$.###$###.$.#.#$###.$####$#.#.$.#.#$#.#.#
+#.#.#...#...........#.#...#...#.#...#...#.#...#.....#...#.#.#.......#.#...#.....#...#...#...#.#...#.#
+#.#.#.###.#.#####.###.#.###.###.#####.#.#.#########.###.###.#######.###.###.###.#.#.#.#######.#.###.#
+#.#.#.....#.#...#.#...#...#...#.#.....#.#.#.....#...#...#...#...#.#.#...#...#.#.#.#.#.....#...#.#...#
+#.#.#########.#.###.#########.#.#.#####.#.#.###.#.#######.###.#.#.#.#.###.###.#.#.#.#######.#####.###
+#.#..$#...$...#$....$....$#...$.#.#$..#.$...#$..#.$....$..#.$.#..$#.#.$.#..$#...$.#..$....$....$#...#
+#####.#.#############.###.#.###.#.#.#.#.#####.###.#.#########.###.#.###.#.#.#.###.#######.#.###.###.#
+#.....#.#...#.........#.#.#...#.#...#.#...#...#...#.....#.....#...#...#.#.#.#.#.#.#...#...#.#.....#.#
+#.#.###.#.#.#.#########.#.#.#.#.#####.###.#.###.#######.#.###########.#.###.#.#.#.###.#.#####.#####.#
+#.#.#.....#...#.........#.#.#.#.......#...#.#.........#.#...#.........#.....#...#...#.#.#.....#...#.#
+#.###$####$####$####$##.#$###.$####$####$##.#$####$##.#$###.$.###$####$##.#$####$.#.#$#.#.$####$#.#.#
+#.....#.......#.#.....#.#.....#.....#.......#.#.......#...#.#.....#.#.....#.....#.#.#...#.#...#.#...#
+#######.#####.#.#.###.#####.#####.###.#######.#.#########.#.#####.#.#.#####.###.#.#.#.###.#.#.#.#####
+#...#...#...#.#.#...#.......#...#.#...#.......#...........#.....#.#...#.....#.#.#.#.#...#.#.#.#...#.#
+#.#.#.###.###.#.###.#########.#.###.#########.#############.#.#.#.#.###.#####.#.#.#.###.#.#.#.###.#.#
+#.#..$#...$...#$#...$.#..$#...$...#$#...$...#$....$.#..$..#.$.#.#$#.#.$.#..$#...$.#.#$#.#.$.#..$..#.#
+#.#####.#.#.###.#.#####.#.#.#####.#.#.#####.#######.#.###.###.#.#.###.###.#.#.#####.#.#.#.#.#######.#
+#...#.#.#...#.....#.#...#.#.#...#.#...#.....#.......#...#.#...#.#...#.#...#.#.......#...#.#.#.....#.#
+#.#.#.#.#########.#.#.###.#.#.#.#.#####.#####.#######.#.#.#.#######.#.#.###.###.#####.###.#.###.#.#.#
+#.#.#.#.#.......#...#.#.#...#.#...#.....#...#.....#...#.#...#...#...#.....#...#.#...#.....#.....#.#.#
+###.#$#.#.$####$####$.#.#$###.$####$####$.#.#$###.$.###$####$.#.#$###.$####$#.##$.#.#$####$####$#.#.#
+#...#.....#.........#.#.#.....#...#.#.#...#...#...#...#.#.....#...#.#.#.....#.#...#.#.........#...#.#
+#.#########.#######.#.#.#.#####.#.#.#.#.###.###.#######.#.#########.#.#.###.#.#.###.#.#####.#.#.###.#
+#.......#...#.....#...#...#.....#...#.#.#.#.........#...#.....#.......#.#.#...#.#...#.#.#...#.#.#...#
+#.#####.#####.###.#####.#######.#####.#.#.#########.#.#######.###.#####.#.###.#.#.#.#.#.#.#####.#.#.#
+#...#$..#.$...#$..#.$.#..$..#.$.#..$....$...#$..#.$...#$....$...#$#.#.$.#..$..#.$.#.#$#.#.$....$#.#.#
+###.#.#.#.#####.###.#.#####.#.###########.###.#.#####.#.#.#####.#.#.#.###.#####.#.###.#.#########.#.#
+#...#.#.#.#...#.....#.....#...#.....#...#.#...#.#...#.#.#...#...#.#.....#.#.....#...#.#.......#...#.#
+#.###.###.#.#.###########.#####.###.#.#.###.###.#.#.###.###.#.###.#.###.###.#######.#.#.#####.#.###.#
+#...#.......#...........#.........#...#.......#...#.......#...#.......#...........#.....#.......#....
+#####################################################################################################
+
+#####################################################################################################
+#.........#.........#...#.................#.....#.....#...........#...#.....#.....#...........#.....#
+#####.###.#.#######.#.#.###.###.###########.#.###.#.#.###.#######.###.#.#.#.###.#.#####.#.###.#.###.#
+#.....#...#.......#...#...#...#.#...#.......#.....#.#...#.....#.#...#...#.#...#.#.....#.#.#.....#.#.#
+#.###############.#######.###.###.#.#.#############.###.#####.#.###.#####.###.#.#####.#.#.#.#####.#.#
+#....$#...$....$#...$.#.#$..#.$...#$..#.$...#$....$...#$..#.$.#..$#...$...#$..#.$....$#.#.$.#..$#.#.#
+#####.#.#.#.###.#####.#.###.#.#############.#.###.#.#.###.#.###.###.#######.###.#.#####.#.###.#.#.#.#
+#.....#.#.....#.....#.#...#.#.....#.........#...#.#.#.#...#.#.......#...#.......#...#...#.#...#.#...#
+#.###.#.#########.###.###.#.#####.###.###.#####.#.###.#.###.###.#####.#.###########.#####.#.###.#.###
+#.#...#...#.....#.#.......#.....#.....#...#.....#...#.#...#...#.#.....#.#.........#.....#...#...#.#.#
+#.###$###.$.###$#.#.$####$####$.###$###.$##.#$####$.#.#$#.##$.###$####$.#.#$####$.###$#.##$##.#$#.#.#
+#...#.....#.#...#...#...#.....#.#.#.......#.#.....#...#.#...#...#...#...#.#...#.#.#.....#.....#...#.#
+#.#.#.#####.###.###.#.#.#.###.#.#.#.#######.#.###.#####.###.#.#.###.#.#.#.#.#.#.#.###.###.#####.###.#
+#.#.#.....#...#...#.#.#.....#...#...#.......#...#...#...#...#.#.#...#.#.#.#.#...#...#.#.....#.#.#...#
+#.#.#.#######.###.###.#####.#####.###.#########.#.#.#.###.#####.#.###.#.#.#.#######.#.#####.#.#.#.#.#
+#.#..$#...$...#$#...$.#..$#...$...#$..#.$....$..#.$...#$..#.$...#$..#.$.#..$#...$...#$#...$.#.#$#.#.#
+#.#####.#######.#######.#.#.#.#.###.###.#########.#.###.###.#######.#.#####.#.#######.#.#.#.#.#.#.#.#
+#.#...#.....#.......#...#.#.#...#...#...#.......#.#.#.......#.......#.....#.#.....#.....#...#.#...#.#
+#.#.#.#####.#.###.#.###.#.#.#####.#####.###.###.#.###.#######.#########.###.#####.###########.#####.#
+#...#.#...#.#.#...#...#.#...#...#.....#...#...#.#.....#.#...#...#.#...#...#.#...#.......#...#.....#.#
+#####$#.#.$.###$####$.###$###.$.###$#.##$.###$#.##$####$#.#.$##.#$#.#.$##.#$#.##$##.#$#.#.$##.#$###.#
+#.....#.#.#...#.#...#.........#.....#.#.#.....#.........#.#.....#...#...#.#.#.#...#...#.#...#.#.....#
+#.#####.#.###.#.#.#.###############.#.#.#####.#.#######.#.###########.#.#.#.#.#.#.#####.###.#.#######
+#.#.#...#...#.#...#...#...#.......#...#.....#...#.#.....#.............#.#...#.#.#.#.....#...#.....#.#
+#.#.#.#####.#.#####.#.#.#.#######.#####.###.#####.#.###############.#######.#.#.#.#.#####.#.#####.#.#
+#.#.#$..#.$...#$..#.$.#.#$....$.#..$..#.$.#..$#...$.#..$....$....$#.#.$...#$..#.$...#$....$...#$..#.#
+#.#.###.#.#####.#.###.#.#######.#.###.###.#.###.#####.#######.#####.#.###.#####.#####.#.#######.###.#
+#.#...#.#.#.....#...#...#.......#...#.....#.#...#.....#.....#.......#.#...#...#...#...#...#...#.#...#
+#.#.#.#.###.#######.#####.#.#######.#####.#.#.###.#####.#############.###.#.#.###.###.###.#.#.#.###.#
+#.#.#.#.....#.#.....#.....#.#.....#.#...#.#...#...#...........#.#...#...#...#...#...#...#...#.#.#...#
+#.#.#$####$##.#$####$.###$#.#.$##.#$#.#.$####$#.##$####$###.$.#.#$#.##$.###$###.$##.#$#.##$##.#$#.#.#
+#.#.#...#.....#.....#...#.#.#.#.#.....#.#...#.#...........#.#.#...#...#.#...........#.#.....#...#.#.#
+#.#####.#.#.#.#####.#.#.#.#.#.#.#######.#.#.###.#########.#.#.#####.#.#.#############.#####.#####.###
+#.....#...#.#.....#.#.#.#...#.#.......#.#.#...#.#.......#.#.#.......#.#...........#.......#.....#...#
+#####.#.###.#.#######.#.###.#.#.#####.#.#.###.#.#.#####.#.#.#######.#####.#######.#.###.#.#####.#.#.#
+#...#$#...$.#.#$....$.#..$#.#.$....$#.#.$.#.#$..#.$...#$#...$....$#.#.$.#..$....$.#.#$..#.$...#$#.#.#
+###.#.###.#.###.###.#.###.###.#######.#.#.#.#####.#.###.#######.###.#.#.#######.#.###.#.###.#.#.###.#
+#...#.#...#...#...#.#...#...#.#.......#...#.....#.#.....#.......#...#.#.#.....#.#.#...#.#...#.#.#...#
+#.#.#.#.#####.###.#.###.###.#.#.#####.#######.###.#.#####.#####.#.###.#.#####.#.#.#.#####.###.#.#.###
+#.#.#.#.#...#.....#.....#.#...#.....#.........#...#...#.......#.#.#.#.#.....#...#.#.........#.#.#...#
+#.###$#.#.$.###$####$##.#$####$####$###.$####$#.##$##.#$####$.###$#.#.$####$#.##$.#.#$####$##.#$###.#
+#.....#...#.#.........#.....#.....#...#.#.......#...#.#.....#.......#.....#.#...#.#...#.....#...#...#
+#.#######.###.#.#####.#####.#.###.#.#.###.#######.#.#.###################.#.###.#.#####.###.###.#.#.#
+#...#...#.#...#.#...#.....#...#...#.#...#.......#.#.#.......#.......#.....#.#...#.....#.#.#...#...#.#
+###.###.#.#.#####.#.#####.#######.#####.#######.#.#.#######.#.#####.#.#####.#.#######.#.#.###.#######
+#.#..$#.#.$....$..#.$...#$....$.#..$#...$...#$..#.$....$#...$....$#...$....$#...$....$#.#.$.#.#$....#
+#.###.#.#.#########.#.#########.###.#.#.#####.###.#.#####.#######.#####.#####.###.#####.###.#.#.###.#
+#.....#.#...#...#...#...#.....#.#.....#.#.....#.#.#...............#...#...#...#...#.........#...#...#
+#.#####.###.###.#.###.#.#.#.###.#########.#####.#.###################.###.###.#.###.#######.#####.###
+#.#.......#.....#.#...#...#...#.#.......#.#...#...#.......#...........#.#...#.#.......#...#.....#...#
+#.###$###.$.###$#.#.$####$#.#.$.#.#$###.$.#.#$####$.###$#.#.$.###$###.$.###$#.##$####$#.#.$.###$#.#.#
+#.#...#...#.#.....#...#.....#.#...#...#.#.#.#.....#.....#.#.#.#...#.#...#...#...#...#...#.#.#...#.#.#
+#.#.#.#.###.#.#######.#.#####.#####.###.#.#.#####.#####.#.###.#.#.#.#.###.#####.#.###.###.#.#.#.###.#
+#...#.#.....#.#.....#...#...#.......#...#...#...#.....#.#...#.#.#.#...#...#...#.#...#.#.#.#.#.#.#...#
+#####.#.#####.#.###.#.###.#.#####.#.#.###.###.#.#.#.###.###.#.#.#.###.#.###.###.###.#.#.#.#.#.#.#.#.#
+#...#$#...$...#$..#.$.#..$#...$...#$#.#.$...#$#.#.$.#..$#.#.$...#$..#.$.#..$....$...#$#...$.#.#$..#.#
+#.###.###.#.###########.###########.#.#####.#.#.###.#.###.#.#.#####.###.#.#########.#.#.###.#.#####.#
+#...#...#.#.#...........#...#...#...#...#...#.#...#.#.....#.#.....#.....#.#...#.....#.#...#.#.#.#...#
+#.#.###.###.#.#.#########.#.#.#.#.#####.#####.###.#.###.###.#####.#######.#.#.#######.###.###.#.#.###
+#.#...#.....#.#.......#...#...#.#.#...#.......#...#...#.#...#...#...#.....#.#...#.....#.#...#.#...#.#
+#.###$####$##.#$####$.#.#$####$.#.#$#.##$####$#.##$.#.#$#.##$.###$#.##$####$###.$.###$#.##$.#.#$###.#
+#...#...#.#...#.....#...#.....#.#.............#.#.#.#...#.#...#...#...#.....#.#.#.....#...#...#...#.#
+#.###.#.#.#.###.#####.#######.#.#############.#.#.#.#####.#.###.#.###.#.#####.#.#####.#.#.#######.#.#
+#.#...#.#.#.#...#...#...#.....#.#...........#.#.#...#...#.#.....#...#...#...#.#.......#.#.......#.#.#
+###.###.#.#.#.#.#.#.###.#.###.#.#.###########.#.###.#.#.#.###.#####.###.#.#.#.#########.#######.#.#.#
+#...#$#.#.$.#.#$#.#.$...#$..#.$.#..$....$...#$#...$.#.#$#...$....$#...$...#$#...$....$....$....$#...#
+#.###.#.#.#.#.###.#.###.###.#.#.#########.#.#.###.###.#.###.#####.###.#####.###.#.#########.###.###.#
+#.#...#.#.#.#.#...#...#.....#.#.....#...#.#...#...#...#.....#.....#...#.......#.......#.....#.....#.#
+#.#.###.#.#.#.#.#####.#######.#####.#.#.#######.###.#########.#####.#########.#######.#.#####.#####.#
+#.#.....#.....#...#.........#.....#.#.#.......#.....#.........#.....#...#...#.......#.#.....#.#.....#
+#.###$####$##.#$#.##$####$#.##$##.#$#.##$####$####$####$####$##.#$###.$.#.#$####$##.#$#.##$.###$#####
+#...#.......#...#.......#.......#.#.#.#.....#.........#...#...#.......#...#.#.....#...#.#.#...#.#...#
+#.#.#######.#.#####.###.#.#####.###.#.###.#####.#####.#####.#.#######.#####.#####.###.#.#.###.#.#.#.#
+#.#.......#.#.#...#.#...#.#...#.....#...#.#.....#...#...#...#.#.....#.....#.#...#...#.#...#...#...#.#
+#.#######.#.#.#.#.###.#.###.#.#####.###.#.#.#######.###.#.###.#.###.#######.#.#.###.#.###.#.#.#####.#
+#...#$..#.$.#.#$#...$.#.#$..#.$....$#.#.$.#..$....$....$#.#.$.#..$#...$....$#.#.$.#..$#...$.#.#$....#
+###.###.#.#.#.#.###.#.###.###.###.###.#.#.#######.###.###.#.#.#.#.#####.#####.###.#.#######.###.#####
+#.....#.#.#.#.#...#.#.#...#.#...#.#...#.#...#...#...#.#...#...#.#.#...#.#.....#.#.#.......#...#.#...#
+#####.#.#.#.#.###.#.#.#.###.###.#.#.###.#.#.#.#.###.#.#.#.#.###.#.#.#.###.#####.#.#######.###.#.#.#.#
+#...#...#.#.#.#...#...#.#.....#.#.#...#...#.#.#.#...#.#.#.#...#.#...#...........#.......#.#...#.#.#.#
+#.#.#$###.$.###$####$.#.#$###.$.#.#$#.##$##.#$###.$##.#$#.##$.###$###.$####$####$##.#$#.#.$.#.#$#.#.#
+#.#.......#.....#.#...#.#.#...#.#.....#...#.#.#...#.......#...#.....#.#.#.....#...#.#...#...#.#.#.#.#
+#.#####.#########.#.###.###.#.#.###.###.#.#.#.#.###########.###.###.#.#.#.###.#.#.###.#######.#.#.#.#
+#.#...#.#...#...#...#.#.#...#.#.#...#...#...#.#.....#.....#...#.#...#...#.#.....#.#...#.......#...#.#
+#.#.#.###.#.#.#.#.###.#.#.###.#.###.#.#######.#####.#.#.#.###.#.###.###.#.#######.#.###.###########.#
+#.#.#$....$.#.#$#.#.$.#..$#...$...#$#.#.$....$#...$.#.#$#.#.$.#..$#...$.#..$#...$...#$#.#.$...#$....#
+#.#.#######.#.###.#.#.#####.#####.###.#.#.###.#.#.#.###.###.#####.###.#####.#########.#.#.###.#.#####
+#...#.......#.....#.#.#.....#...#.#...#.#.#.#...#.#...#...#.......#.........#...#.......#.#.#.#.....#
+#.###.###########.#.###.#######.#.#.#####.#.#####.###.#.#.#########.#########.#.#######.#.#.#.#####.#
+#.#.#.......#...#...#...#.....#.#.#.#.....#.#.....#.#.#.#...........#.........#.#.....#.#...#.....#.#
+#.#.#$####$.#.#$###.$.###$###.$.#.#$#.##$##.#$####$.#.#$####$##.#$###.$####$###.$.###$###.$##.#$###.#
+#.#.......#...#.#.#.#.#...#.....#.#.#.#...#...#.....#.........#...#.#.#...#.....#...#.....#...#.....#
+#.#.###.#######.#.#.#.###.#######.#.#.#.#.#.###.###.#########.###.#.#.###.#.#######.#######.#.#.#####
+#...#...#...#...#...#...#.#.....#.#...#.#.#...#.#.......#...#...#...#.#...#.#.......#.......#.#.....#
+###.#####.#.#.###.#####.#.#.###.#.#####.#####.#.#######.#.#.#.#.#####.#.###.#.#######.#############.#
+#...#$..#.$...#$....$...#$#.#.$...#$..#.$....$#...$.#..$#.#.$.#..$..#.$.#..$#.#.$...#$..#.$...#$....#
+#.###.#.#.#########.#.###.#.#######.#.#.#######.#.#.#.###.#.#######.###.#.###.#.###.###.#.###.#.#####
+#...#.#...#...#...#.#...#.#.#.......#...#.....#.#.#.#.#.#.#.........#...#...#.#...#.#.#.#.#...#.#...#
+###.#.#####.#.#.#.#####.#.#.#.###########.###.###.#.#.#.#.###########.#####.#.###.#.#.#.#.#.###.#.#.#
+#...#.......#...#.........#...............#.......#.....#.................#.......#...#...#.......#.#
+##################################################################################################### \ No newline at end of file
diff --git a/codingquest2024/src/day9/solution.gleam b/codingquest2024/src/day9/solution.gleam
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/codingquest2024/src/day9/solution.gleam
diff --git a/codingquest2024/src/utilities/memo.gleam b/codingquest2024/src/utilities/memo.gleam
new file mode 100644
index 0000000..b06d8fd
--- /dev/null
+++ b/codingquest2024/src/utilities/memo.gleam
@@ -0,0 +1,57 @@
+import gleam/dict.{type Dict}
+import gleam/otp/actor.{type Next, Continue, Stop}
+import gleam/erlang/process.{type Subject, Normal}
+import gleam/option.{None}
+
+const timeout = 1000
+
+type Message(k, v) {
+ Shutdown
+ Get(key: k, client: Subject(Result(v, Nil)))
+ Set(key: k, value: v)
+}
+
+type Server(k, v) =
+ Subject(Message(k, v))
+
+pub opaque type Cache(k, v) {
+ Cache(server: Server(k, v))
+}
+
+fn handle_message(
+ message: Message(k, v),
+ dict: Dict(k, v),
+) -> Next(Message(k, v), Dict(k, v)) {
+ case message {
+ Shutdown -> Stop(Normal)
+ Get(key, client) -> {
+ process.send(client, dict.get(dict, key))
+ Continue(dict, None)
+ }
+ Set(key, value) -> Continue(dict.insert(dict, key, value), None)
+ }
+}
+
+pub fn create(apply fun: fn(Cache(k, v)) -> t) -> t {
+ let assert Ok(server) = actor.start(dict.new(), handle_message)
+ let result = fun(Cache(server))
+ process.send(server, Shutdown)
+ result
+}
+
+pub fn set(in cache: Cache(k, v), for key: k, insert value: v) -> Nil {
+ process.send(cache.server, Set(key, value))
+}
+
+pub fn get(from cache: Cache(k, v), fetch key: k) -> Result(v, Nil) {
+ process.call(cache.server, fn(c) { Get(key, c) }, timeout)
+}
+
+pub fn memoize(with cache: Cache(k, v), this key: k, apply fun: fn() -> v) -> v {
+ let result = case get(from: cache, fetch: key) {
+ Ok(value) -> value
+ Error(Nil) -> fun()
+ }
+ set(in: cache, for: key, insert: result)
+ result
+}
diff --git a/codingquest2024/test/codingquest2024_test.gleam b/codingquest2024/test/codingquest2024_test.gleam
new file mode 100644
index 0000000..3831e7a
--- /dev/null
+++ b/codingquest2024/test/codingquest2024_test.gleam
@@ -0,0 +1,12 @@
+import gleeunit
+import gleeunit/should
+
+pub fn main() {
+ gleeunit.main()
+}
+
+// gleeunit test functions end in `_test`
+pub fn hello_world_test() {
+ 1
+ |> should.equal(1)
+}