aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHJ <thechairman@thechairman.info>2023-12-08 02:59:26 -0500
committerHJ <thechairman@thechairman.info>2023-12-08 02:59:26 -0500
commitb9c4b4dfadd305c55fb09d421252780cb254f89b (patch)
treec92d27064bf177d72e7cc55a1eeee713e957ef63
parentc82dee4b12a824ff73dc91f89445d4df75d3c876 (diff)
downloadgleam_aoc-b9c4b4dfadd305c55fb09d421252780cb254f89b.tar.gz
gleam_aoc-b9c4b4dfadd305c55fb09d421252780cb254f89b.zip
day 8 complete
-rw-r--r--aoc2023-other/day-06/day-06.rkt3
-rw-r--r--aoc2023-other/day-07/day-07.rkt49
-rw-r--r--aoc2023/gleam.toml1
-rw-r--r--aoc2023/manifest.toml10
-rw-r--r--aoc2023/src/day8/.gitignore1
-rw-r--r--aoc2023/src/day8/solve.gleam89
-rw-r--r--aoc2023/test/day8/day8_test.gleam61
7 files changed, 209 insertions, 5 deletions
diff --git a/aoc2023-other/day-06/day-06.rkt b/aoc2023-other/day-06/day-06.rkt
index 2897821..399c131 100644
--- a/aoc2023-other/day-06/day-06.rkt
+++ b/aoc2023-other/day-06/day-06.rkt
@@ -1,7 +1,8 @@
#lang racket
(require advent-of-code
- threading)
+ threading
+ )
(match-define (list times distances)
(~> (open-aoc-input (find-session) 2023 6 #:cache #true) port->lines))
diff --git a/aoc2023-other/day-07/day-07.rkt b/aoc2023-other/day-07/day-07.rkt
new file mode 100644
index 0000000..67dc212
--- /dev/null
+++ b/aoc2023-other/day-07/day-07.rkt
@@ -0,0 +1,49 @@
+#lang racket
+
+(require advent-of-code
+ threading)
+
+(struct hand (cards wager) #:transparent)
+
+(define/match (card->int card)
+ [((? char-numeric?)) (~> card string string->number)]
+ [(#\A) 14]
+ [(#\K) 13]
+ [(#\Q) 12]
+ [(#\J) 11]
+ [(#\T) 10]
+ [(#\*) 1])
+
+(define (parse-hand str)
+ (match-define (list card-str wager-str) (string-split str))
+ (define cards (~> card-str string->list (map card->int _)))
+ (define wager (~> wager-str string->number))
+ (hand cards wager))
+
+(define input (~> (open-aoc-input (find-session) 2023 7 #:cache #true) port->lines))
+
+(define (identify-hand h)
+ (define freqs (~> h hand-cards (sort <) (group-by identity _) (map length _)))
+ (match freqs
+ [(list-no-order 5) 8]
+ [(list-no-order 1 4) 7]
+ [(list-no-order 2 3) 6]
+ [(list-no-order 1 1 3) 5]
+ [(list-no-order 1 2 2) 4]
+ [(list-no-order 1 1 1 2) 3]
+ [(list-no-order 1 1 1 1 1) 2]))
+
+(define (compare-first-card cs1 cs2)
+ (if (= (first cs1) (first cs2))
+ (compare-first-card (rest cs1) (rest cs2))
+ (< (first cs1) (first cs2))))
+
+(define (compare-hands h1 h2)
+ (define rank1 (identify-hand h1))
+ (define rank2 (identify-hand h2))
+ (if (= rank1 rank2) (compare-first-card (hand-cards h1) (hand-cards h2)) (< rank1 rank2)))
+
+;; part 1
+
+(for/sum ([(h i) (in-indexed (~> input (map parse-hand _) (sort compare-hands)))])
+ (* (add1 i) (hand-wager h)))
diff --git a/aoc2023/gleam.toml b/aoc2023/gleam.toml
index 387036d..8fc812a 100644
--- a/aoc2023/gleam.toml
+++ b/aoc2023/gleam.toml
@@ -14,6 +14,7 @@ gleam = ">= 0.32.0"
gleam_stdlib = "~> 0.32"
simplifile = "~> 1.0"
gleam_erlang = "~> 0.23"
+gleam_community_maths = "~> 1.0"
[dev-dependencies]
gleeunit = "~> 1.0"
diff --git a/aoc2023/manifest.toml b/aoc2023/manifest.toml
index aea86fb..b6965da 100644
--- a/aoc2023/manifest.toml
+++ b/aoc2023/manifest.toml
@@ -2,17 +2,18 @@
# You typically do not need to edit this file
packages = [
- { name = "adglent", version = "1.2.0", build_tools = ["gleam"], requirements = ["tom", "gleam_http", "gleam_stdlib", "simplifile", "gleam_community_ansi", "gap", "gleam_httpc", "gleam_otp", "snag", "glint", "gleam_erlang"], otp_app = "adglent", source = "hex", outer_checksum = "A20D35001061F8AD602E3B92FB3AC0E1E4EEC642AD2AAE0ACEAD3A85F37DA7F0" },
+ { name = "adglent", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_otp", "gap", "glint", "gleam_http", "snag", "gleam_stdlib", "tom", "gleam_community_ansi", "gleam_erlang", "gleam_httpc", "simplifile"], otp_app = "adglent", source = "hex", outer_checksum = "A20D35001061F8AD602E3B92FB3AC0E1E4EEC642AD2AAE0ACEAD3A85F37DA7F0" },
{ name = "gap", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_community_ansi"], 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_ansi", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_community_colour"], 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.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_maths", source = "hex", outer_checksum = "2F85C076830150347FBA286C3C440EC2CFB3538407105E5EF3FC64D17E711AC2" },
{ 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_stdlib", "gleam_http"], otp_app = "gleam_httpc", source = "hex", outer_checksum = "06AC1CA52C9BAA66C9D5C0303B2BF34E39AA1546BB96AEE496E4B06D513AB8C7" },
+ { 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_erlang", "gleam_stdlib"], 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 = "gleeunit", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D3682ED8C5F9CAE1C928F2506DE91625588CC752495988CBE0F5653A42A6F334" },
- { name = "glint", version = "0.13.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_stdlib", "gleam_community_colour", "snag"], otp_app = "glint", source = "hex", outer_checksum = "46E56049CD370D61F720D319D0AB970408C9336EEB918F08B5DCB1DCE9845FA3" },
+ { name = "glint", version = "0.13.0", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib", "gleam_community_ansi", "snag"], otp_app = "glint", source = "hex", outer_checksum = "46E56049CD370D61F720D319D0AB970408C9336EEB918F08B5DCB1DCE9845FA3" },
{ name = "simplifile", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0BD6F0E7DA1A7E11D18B8AD48453225CAFCA4C8CFB4513D217B372D2866C501C" },
{ 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" },
@@ -20,6 +21,7 @@ packages = [
[requirements]
adglent = { version = "~> 1.2" }
+gleam_community_maths = { version = "~> 1.0" }
gleam_erlang = { version = "~> 0.23" }
gleam_stdlib = { version = "~> 0.32" }
gleeunit = { version = "~> 1.0" }
diff --git a/aoc2023/src/day8/.gitignore b/aoc2023/src/day8/.gitignore
new file mode 100644
index 0000000..ae40cea
--- /dev/null
+++ b/aoc2023/src/day8/.gitignore
@@ -0,0 +1 @@
+input.txt \ No newline at end of file
diff --git a/aoc2023/src/day8/solve.gleam b/aoc2023/src/day8/solve.gleam
new file mode 100644
index 0000000..dee24a4
--- /dev/null
+++ b/aoc2023/src/day8/solve.gleam
@@ -0,0 +1,89 @@
+import adglent.{First, Second}
+import gleam/bool
+import gleam/dict.{type Dict}
+import gleam/io
+import gleam/iterator.{Next}
+import gleam/list
+import gleam/option.{Some}
+import gleam/string
+import gleam/regex.{type Match, Match}
+import gleam_community/maths/arithmetics
+
+type Paths {
+ Paths(to_left: String, to_right: String)
+}
+
+type Maze =
+ Dict(String, Paths)
+
+fn parse(input: String) {
+ let [directions_str, maze_str] = string.split(input, "\n\n")
+
+ let directions =
+ directions_str
+ |> string.to_graphemes()
+ |> iterator.from_list
+ |> iterator.cycle
+
+ let assert Ok(re) = regex.from_string("(...) = \\((...), (...)\\)")
+ let maze =
+ maze_str
+ |> string.split("\n")
+ |> list.map(fn(str) {
+ let assert [Match(submatches: [Some(name), Some(left), Some(right)], ..)] =
+ regex.scan(re, str)
+ #(name, Paths(left, right))
+ })
+ |> dict.from_list
+
+ #(directions, maze)
+}
+
+fn to_next_step(current, stop_at, count, directions, maze: Maze) {
+ use <- bool.guard(string.ends_with(current, stop_at), count)
+ let assert Next(next_direction, rest_directions) = iterator.step(directions)
+ let assert Ok(paths) = dict.get(maze, current)
+ case next_direction {
+ "L" -> paths.to_left
+ "R" -> paths.to_right
+ }
+ |> to_next_step(stop_at, count + 1, rest_directions, maze)
+}
+
+pub fn part1(input: String) {
+ let #(directions, maze) = parse(input)
+
+ to_next_step("AAA", "ZZZ", 0, directions, maze)
+ |> string.inspect
+}
+
+pub fn part2(input: String) {
+ let #(directions, maze) = parse(input)
+
+ maze
+ |> dict.keys
+ |> list.filter(string.ends_with(_, "A"))
+ |> list.fold(
+ 1,
+ fn(acc, name) {
+ to_next_step(name, "Z", 0, directions, maze)
+ |> arithmetics.lcm(acc)
+ },
+ )
+ |> string.inspect
+}
+
+pub fn main() {
+ let assert Ok(part) = adglent.get_part()
+ let assert Ok(input) = adglent.get_input("8")
+ case part {
+ First ->
+ part1(input)
+ |> adglent.inspect
+ |> io.println
+ Second ->
+ part2(input)
+ |> adglent.inspect
+ |> io.println
+ }
+}
diff --git a/aoc2023/test/day8/day8_test.gleam b/aoc2023/test/day8/day8_test.gleam
new file mode 100644
index 0000000..e54d887
--- /dev/null
+++ b/aoc2023/test/day8/day8_test.gleam
@@ -0,0 +1,61 @@
+import gleam/list
+import showtime/tests/should
+import adglent.{type Example, Example}
+import day8/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)) = [
+ Example(
+ "LLR
+
+AAA = (BBB, BBB)
+BBB = (AAA, ZZZ)
+ZZZ = (ZZZ, ZZZ)",
+ "6",
+ ),
+]
+
+/// Add examples for part 2 here:
+/// ```gleam
+///const part2_examples: List(Example(Problem2AnswerType)) = [Example("some input", "")]
+/// ```
+const part2_examples: List(Example(Problem2AnswerType)) = [
+ Example(
+ "LR
+
+11A = (11B, XXX)
+11B = (XXX, 11Z)
+11Z = (11B, XXX)
+22A = (22B, XXX)
+22B = (22C, 22C)
+22C = (22Z, 22Z)
+22Z = (22B, 22B)
+XXX = (XXX, XXX)",
+ "6",
+ ),
+]
+
+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)
+}