aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J <thechairman@thechairman.info>2024-06-03 17:16:30 -0400
committerH.J <thechairman@thechairman.info>2024-06-03 17:16:30 -0400
commit23c7ca166ac87a339c6ee6ed71aed41afefb5513 (patch)
tree904bea816aa94775084dc08ea740ac692112184a
parenta679186bed8e5e284604fab7ef8ac932b66d4d51 (diff)
downloadgleam_aoc-23c7ca166ac87a339c6ee6ed71aed41afefb5513.tar.gz
gleam_aoc-23c7ca166ac87a339c6ee6ed71aed41afefb5513.zip
gleam 2017 up to day 7 part 1
-rw-r--r--aoc2017-gleam/gleam.toml1
-rw-r--r--aoc2017-gleam/manifest.toml4
-rw-r--r--aoc2017-gleam/src/aoc_2017/day_4.gleam31
-rw-r--r--aoc2017-gleam/src/aoc_2017/day_5.gleam48
-rw-r--r--aoc2017-gleam/src/aoc_2017/day_6.gleam65
-rw-r--r--aoc2017-gleam/src/aoc_2017/day_7.gleam42
6 files changed, 190 insertions, 1 deletions
diff --git a/aoc2017-gleam/gleam.toml b/aoc2017-gleam/gleam.toml
index 2be991f..669a48d 100644
--- a/aoc2017-gleam/gleam.toml
+++ b/aoc2017-gleam/gleam.toml
@@ -15,6 +15,7 @@ version = "1.0.0"
[dependencies]
gleam_stdlib = ">= 0.34.0 and < 2.0.0"
gladvent = ">= 0.7.3 and < 1.0.0"
+gary = ">= 1.0.1 and < 2.0.0"
[dev-dependencies]
gleeunit = ">= 1.0.0 and < 2.0.0"
diff --git a/aoc2017-gleam/manifest.toml b/aoc2017-gleam/manifest.toml
index d41f27a..12fa60f 100644
--- a/aoc2017-gleam/manifest.toml
+++ b/aoc2017-gleam/manifest.toml
@@ -4,6 +4,7 @@
packages = [
{ name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" },
{ name = "filepath", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "EFB6FF65C98B2A16378ABC3EE2B14124168C0CE5201553DE652E2644DCFDB594" },
+ { name = "gary", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gary", source = "hex", outer_checksum = "4C05611EEC74876A1E36309EED22C826B92F22E566579ACBC65C579CD615EC60" },
{ name = "gladvent", version = "0.7.3", build_tools = ["gleam"], requirements = ["argv", "filepath", "gleam_erlang", "gleam_json", "gleam_otp", "gleam_package_interface", "gleam_stdlib", "glint", "parallel_map", "shellout", "simplifile", "snag", "spinner", "tom"], otp_app = "gladvent", source = "hex", outer_checksum = "59D93FD759427BCE8EE9828C0B62A3CD18362225F948C9789D334DCEAD621358" },
{ 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.4.0", build_tools = ["gleam"], requirements = ["gleam_json", "gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "795964217EBEDB3DA656F5EB8F67D7AD22872EB95182042D3E7AFEF32D3FD2FE" },
@@ -26,6 +27,7 @@ packages = [
]
[requirements]
-gladvent = { version = ">= 0.7.3 and < 1.0.0"}
+gary = { version = ">= 1.0.1 and < 2.0.0"}
+gladvent = { version = ">= 0.7.3 and < 1.0.0" }
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
diff --git a/aoc2017-gleam/src/aoc_2017/day_4.gleam b/aoc2017-gleam/src/aoc_2017/day_4.gleam
new file mode 100644
index 0000000..9bc4f9a
--- /dev/null
+++ b/aoc2017-gleam/src/aoc_2017/day_4.gleam
@@ -0,0 +1,31 @@
+import gleam/list
+import gleam/string
+
+pub fn parse(input: String) -> List(List(String)) {
+ use row <- list.map(string.split(input, "\n"))
+ string.split(row, " ")
+}
+
+pub fn pt_1(input: List(List(String))) {
+ use acc, passwords <- list.fold(input, 0)
+ case passwords == list.unique(passwords) {
+ True -> acc + 1
+ False -> acc
+ }
+}
+
+pub fn pt_2(input: List(List(String))) {
+ use acc, passwords <- list.fold(input, 0)
+ let sorted_passwords = list.map(passwords, sort_graphemes)
+ case sorted_passwords == list.unique(sorted_passwords) {
+ True -> acc + 1
+ False -> acc
+ }
+}
+
+fn sort_graphemes(word: String) -> String {
+ word
+ |> string.to_graphemes
+ |> list.sort(string.compare)
+ |> string.concat
+}
diff --git a/aoc2017-gleam/src/aoc_2017/day_5.gleam b/aoc2017-gleam/src/aoc_2017/day_5.gleam
new file mode 100644
index 0000000..a0b9b80
--- /dev/null
+++ b/aoc2017-gleam/src/aoc_2017/day_5.gleam
@@ -0,0 +1,48 @@
+import gary.{type ErlangArray}
+import gary/array
+import gleam/int
+import gleam/list
+import gleam/result
+import gleam/string
+
+pub fn parse(input: String) -> ErlangArray(Int) {
+ input
+ |> string.split("\n")
+ |> list.map(int.parse)
+ |> result.values()
+ |> array.from_list(default: 0)
+ |> array.make_fixed()
+}
+
+pub fn pt_1(input: ErlangArray(Int)) {
+ next_step(input, 0, 0, part: 1)
+}
+
+pub fn pt_2(input: ErlangArray(Int)) {
+ next_step(input, 0, 0, part: 2)
+}
+
+fn next_step(
+ instructions: ErlangArray(Int),
+ pointer: Int,
+ step: Int,
+ part part: Int,
+) {
+ case array.get(from: instructions, at: pointer) {
+ Ok(distance) -> {
+ let delta = delta(distance, part)
+ let assert Ok(updated_instructions) =
+ array.set(instructions, at: pointer, put: distance + delta)
+ next_step(updated_instructions, pointer + distance, step + 1, part)
+ }
+ Error(_) -> step
+ }
+}
+
+fn delta(d: Int, part: Int) {
+ case part, d {
+ 1, _ -> 1
+ _, n if n < 3 -> 1
+ _, _ -> -1
+ }
+}
diff --git a/aoc2017-gleam/src/aoc_2017/day_6.gleam b/aoc2017-gleam/src/aoc_2017/day_6.gleam
new file mode 100644
index 0000000..84222e1
--- /dev/null
+++ b/aoc2017-gleam/src/aoc_2017/day_6.gleam
@@ -0,0 +1,65 @@
+import gary.{type ErlangArray}
+import gary/array
+import gleam/bool
+import gleam/int
+import gleam/list
+import gleam/result
+import gleam/set.{type Set}
+import gleam/string
+
+pub fn parse(input) -> ErlangArray(Int) {
+ input
+ |> string.split("\t")
+ |> list.map(int.parse)
+ |> result.values()
+ |> array.from_list(default: -1)
+ |> array.make_fixed()
+}
+
+pub fn pt_1(input: ErlangArray(Int)) {
+ check_cycle(input, set.from_list([input]), 1).1
+}
+
+pub fn pt_2(input: ErlangArray(Int)) {
+ let #(target, cycle) = check_cycle(input, set.from_list([input]), 1)
+ cycle - check_cycle(input, set.from_list([input, target]), 1).1
+}
+
+fn get_max(array: ErlangArray(Int)) -> #(Int, Int) {
+ use index, value, max <- array.fold(over: array, from: #(-1, -1))
+ case value > max.1 {
+ True -> #(index, value)
+ False -> max
+ }
+}
+
+fn redistribute(
+ array: ErlangArray(Int),
+ pointer: Int,
+ remaining: Int,
+) -> ErlangArray(Int) {
+ use <- bool.guard(remaining == 0, array)
+ case array.get(from: array, at: pointer) {
+ Error(_) -> redistribute(array, 0, remaining)
+ Ok(n) -> {
+ let assert Ok(updated_array) =
+ array.set(into: array, at: pointer, put: n + 1)
+ redistribute(updated_array, pointer + 1, remaining - 1)
+ }
+ }
+}
+
+fn check_cycle(
+ current: ErlangArray(Int),
+ cache: Set(ErlangArray(Int)),
+ cycle: Int,
+) -> #(ErlangArray(Int), Int) {
+ let #(index, to_redistribute) = current |> get_max
+ let assert Ok(zeroed) = array.set(into: current, at: index, put: 0)
+ let next = redistribute(zeroed, index + 1, to_redistribute)
+
+ case set.contains(cache, next) {
+ True -> #(next, cycle)
+ False -> check_cycle(next, set.insert(cache, next), cycle + 1)
+ }
+}
diff --git a/aoc2017-gleam/src/aoc_2017/day_7.gleam b/aoc2017-gleam/src/aoc_2017/day_7.gleam
new file mode 100644
index 0000000..593282b
--- /dev/null
+++ b/aoc2017-gleam/src/aoc_2017/day_7.gleam
@@ -0,0 +1,42 @@
+import gleam/int
+import gleam/io
+import gleam/list
+import gleam/option.{None, Some}
+import gleam/regex.{type Match, Match}
+import gleam/set
+import gleam/string
+
+pub type Program {
+ Program(name: String, weight: Int, supporting: List(String))
+}
+
+pub fn parse(input: String) {
+ let assert Ok(re) = regex.from_string("([a-z]+) \\(([0-9]+)\\)(?> -> (.*))?")
+
+ use match <- list.map(string.split(input, "\n"))
+ case regex.scan(re, match) {
+ [Match(submatches: [Some(name), Some(weight)], ..)] ->
+ Program(name, to_int(weight), [])
+ [Match(submatches: [Some(name), Some(weight), Some(supporting)], ..)] ->
+ Program(name, to_int(weight), string.split(supporting, ", "))
+ _ -> panic as { "couldn't parse" <> match }
+ }
+}
+
+fn to_int(str: String) -> Int {
+ let assert Ok(n) = int.parse(str)
+ n
+}
+
+pub fn pt_1(input: List(Program)) {
+ let supporters = input |> list.map(fn(p) { p.name }) |> set.from_list()
+ let supporting =
+ input |> list.flat_map(fn(p) { p.supporting }) |> set.from_list()
+
+ let assert [base] = set.difference(supporters, supporting) |> set.to_list
+ base
+}
+
+pub fn pt_2(input: List(Program)) {
+ todo as "part 2 not implemented"
+}