diff options
author | Tomasz Chojnacki <tomaszchojnacki2001@gmail.com> | 2023-04-06 22:00:05 +0200 |
---|---|---|
committer | Tomasz Chojnacki <tomaszchojnacki2001@gmail.com> | 2023-04-06 22:00:05 +0200 |
commit | 76e1d24c9cb3f2461f4dca08271fa25f97e820b7 (patch) | |
tree | 232859b85c356d71fdb89e8c627df17455bd812b /aoc-2020-gleam/src/days | |
parent | 20852d6e60bee896e84c9bae77f45211773dbf60 (diff) | |
download | gleam_aoc2020-76e1d24c9cb3f2461f4dca08271fa25f97e820b7.tar.gz gleam_aoc2020-76e1d24c9cb3f2461f4dca08271fa25f97e820b7.zip |
Finish day 13
Diffstat (limited to 'aoc-2020-gleam/src/days')
-rw-r--r-- | aoc-2020-gleam/src/days/day10.gleam | 2 | ||||
-rw-r--r-- | aoc-2020-gleam/src/days/day13.gleam | 113 |
2 files changed, 114 insertions, 1 deletions
diff --git a/aoc-2020-gleam/src/days/day10.gleam b/aoc-2020-gleam/src/days/day10.gleam index b53000b..86c0137 100644 --- a/aoc-2020-gleam/src/days/day10.gleam +++ b/aoc-2020-gleam/src/days/day10.gleam @@ -49,7 +49,7 @@ fn arrangements(number: Int, adapters: List(Int), cache: Cache(Int, Int)) -> Int fn part2(numbers: List(Int)) -> Int { let adapters = process_adapters(numbers) - let device_joltage = resx.assert_unwrap(list.last(adapters)) + let assert Ok(device_joltage) = list.last(adapters) use cache <- cache.create() arrangements(device_joltage, adapters, cache) } diff --git a/aoc-2020-gleam/src/days/day13.gleam b/aoc-2020-gleam/src/days/day13.gleam new file mode 100644 index 0000000..c95cd42 --- /dev/null +++ b/aoc-2020-gleam/src/days/day13.gleam @@ -0,0 +1,113 @@ +import gleam/io +import gleam/int +import gleam/list +import gleam/pair +import gleam/string as str +import gleam/iterator as iter +import ext/intx +import ext/resultx as resx +import ext/iteratorx as iterx +import util/input_util + +type Bus { + Any + Line(Int) +} + +type Problem { + Problem(timestamp: Int, buses: List(Bus)) +} + +fn parse_problem(input: String) -> Problem { + let assert Ok(#(timestamp, buses)) = + input + |> str.trim + |> str.split_once(on: "\n") + let assert Ok(timestamp) = int.parse(timestamp) + let buses = + buses + |> str.split(on: ",") + |> list.map(with: fn(b) { + case b == "x" { + True -> Any + False -> + b + |> int.parse + |> resx.assert_unwrap + |> Line + } + }) + Problem(timestamp, buses) +} + +fn part1(input: String) -> Int { + let problem = parse_problem(input) + + problem.buses + |> list.filter_map(with: fn(b) { + case b { + Line(line) -> Ok(line) + Any -> Error(Nil) + } + }) + |> list.map(with: fn(b) { + #(b, b * intx.ceil_divide(problem.timestamp, by: b) - problem.timestamp) + }) + |> list.reduce(with: fn(acc, cur) { + case cur.1 < acc.1 { + True -> cur + False -> acc + } + }) + |> resx.assert_unwrap + |> fn(res: #(Int, Int)) { res.0 * res.1 } +} + +fn part2(input: String) -> Int { + let problem = parse_problem(input) + + let buses = + problem.buses + |> iter.from_list + |> iter.index + |> iter.flat_map(fn(entry) { + let #(i, b) = entry + case b { + Line(line) -> iter.single(#(line, i)) + Any -> iter.empty() + } + }) + |> iter.to_list + + let assert [#(timestamp, _), ..] = buses + + buses + |> list.fold( + from: #(timestamp, timestamp), + with: fn(prev, entry) { + let #(timestamp, period) = prev + let #(id, i) = entry + + let assert Ok(timestamp) = + timestamp + |> iterx.unfold_infinitely(with: int.add(_, period)) + |> iter.find(one_that: fn(t) { { t + i } % id == 0 }) + let period = intx.lcm(period, id) + + #(timestamp, period) + }, + ) + |> pair.first +} + +pub fn main() -> Nil { + let test = input_util.read_text("test13") + let assert 295 = part1(test) + let assert 1_068_781 = part2(test) + + let input = input_util.read_text("day13") + io.debug(part1(input)) + io.debug(part2(input)) + + Nil +} |