diff options
author | H.J <thechairman@thechairman.info> | 2024-06-03 17:16:30 -0400 |
---|---|---|
committer | H.J <thechairman@thechairman.info> | 2024-06-03 17:16:30 -0400 |
commit | 23c7ca166ac87a339c6ee6ed71aed41afefb5513 (patch) | |
tree | 904bea816aa94775084dc08ea740ac692112184a /aoc2017-gleam/src | |
parent | a679186bed8e5e284604fab7ef8ac932b66d4d51 (diff) | |
download | gleam_aoc-23c7ca166ac87a339c6ee6ed71aed41afefb5513.tar.gz gleam_aoc-23c7ca166ac87a339c6ee6ed71aed41afefb5513.zip |
gleam 2017 up to day 7 part 1
Diffstat (limited to 'aoc2017-gleam/src')
-rw-r--r-- | aoc2017-gleam/src/aoc_2017/day_4.gleam | 31 | ||||
-rw-r--r-- | aoc2017-gleam/src/aoc_2017/day_5.gleam | 48 | ||||
-rw-r--r-- | aoc2017-gleam/src/aoc_2017/day_6.gleam | 65 | ||||
-rw-r--r-- | aoc2017-gleam/src/aoc_2017/day_7.gleam | 42 |
4 files changed, 186 insertions, 0 deletions
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" +} |