aboutsummaryrefslogtreecommitdiff
path: root/aoc-2020-gleam/src/days/day09.gleam
diff options
context:
space:
mode:
authorTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2023-03-03 17:43:42 +0100
committerTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2023-03-03 17:43:42 +0100
commit8367d45862c59889e1b9824bab2e11645c09521f (patch)
tree4f86f635148e06faa4e91daae647ef7f432b7aa3 /aoc-2020-gleam/src/days/day09.gleam
parent6c661db5b3e167d45554f7c5e4838dbc3bffa63a (diff)
downloadgleam_aoc2020-8367d45862c59889e1b9824bab2e11645c09521f.tar.gz
gleam_aoc2020-8367d45862c59889e1b9824bab2e11645c09521f.zip
Finish day 9
Diffstat (limited to 'aoc-2020-gleam/src/days/day09.gleam')
-rw-r--r--aoc-2020-gleam/src/days/day09.gleam68
1 files changed, 68 insertions, 0 deletions
diff --git a/aoc-2020-gleam/src/days/day09.gleam b/aoc-2020-gleam/src/days/day09.gleam
new file mode 100644
index 0000000..81dac89
--- /dev/null
+++ b/aoc-2020-gleam/src/days/day09.gleam
@@ -0,0 +1,68 @@
+import gleam/io
+import gleam/int
+import gleam/list
+import gleam/pair
+import gleam/result as res
+import gleam/iterator as iter
+import ext/listx
+import ext/iteratorx as iterx
+import ext/resultx as resx
+import util/input_util
+
+fn satisfies_two_sum(numbers: List(Int), sum: Int) -> Bool {
+ numbers
+ |> list.combination_pairs
+ |> list.filter(fn(two) { pair.first(two) != pair.second(two) })
+ |> list.any(satisfying: fn(two) { pair.first(two) + pair.second(two) == sum })
+}
+
+fn part1(numbers: List(Int), preamble_length: Int) -> Int {
+ numbers
+ |> list.window(by: preamble_length + 1)
+ |> iter.from_list
+ |> iter.drop_while(satisfying: fn(window) {
+ let assert [sum, ..numbers] = list.reverse(window)
+ satisfies_two_sum(numbers, sum)
+ })
+ |> iter.first
+ |> resx.assert_unwrap
+ |> list.last
+ |> resx.assert_unwrap
+}
+
+fn part2(numbers: List(Int), preamble_length: Int) -> Int {
+ let sum = part1(numbers, preamble_length)
+ numbers
+ |> iter.from_list
+ |> iter.index
+ |> iterx.filter_map(with: fn(step) {
+ let #(index, _) = step
+ let sublist = list.drop(from: numbers, up_to: index)
+
+ sublist
+ |> list.scan(from: 0, with: int.add)
+ |> list.drop(up_to: 1)
+ |> list.take_while(satisfying: fn(s) { s <= sum })
+ |> listx.index_of(sum)
+ |> res.map(with: fn(offset) { list.take(from: sublist, up_to: offset + 2) })
+ })
+ |> iter.first
+ |> resx.assert_unwrap
+ |> fn(set) {
+ let assert Ok(min) = list.reduce(set, with: int.min)
+ let assert Ok(max) = list.reduce(set, with: int.max)
+ min + max
+ }
+}
+
+pub fn run() -> Nil {
+ let test = input_util.read_numbers("test09")
+ let assert 127 = part1(test, 5)
+ let assert 62 = part2(test, 5)
+
+ let input = input_util.read_numbers("day09")
+ io.debug(part1(input, 25))
+ io.debug(part2(input, 25))
+
+ Nil
+}