1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
import gleam/int
import gleam/list
import gleam/option.{Some}
import gleam/regex.{Match}
import gleam/string
pub type Layer {
Layer(depth: Int, cycle: Int)
}
pub type Status {
Caught(severity: Int)
Free
}
pub fn parse(input: String) {
let assert Ok(re) = regex.from_string("([0-9]+): ([0-9]+)")
use acc, row <- list.fold(string.split(input, "\n"), [])
let assert [Match(submatches: [Some(depth), Some(cycle)], ..)] =
regex.scan(row, with: re)
let assert Ok(depth) = int.parse(depth)
let assert Ok(cycle) = int.parse(cycle)
[Layer(depth, cycle), ..acc]
}
fn severity(time: Int, depth: Int, cycle: Int) {
case { time + depth } % { 2 * { cycle - 1 } } {
0 -> Caught(cycle * depth)
_ -> Free
}
}
pub fn pt_1(input: List(Layer)) {
use acc, layer <- list.fold(input, 0)
case severity(0, layer.depth, layer.cycle) {
Free -> acc
Caught(severity) -> acc + severity
}
}
pub fn pt_2(input: List(Layer)) {
find_delay(0, input)
}
fn find_delay(delay: Int, layers: List(Layer)) {
let trial_run =
list.try_fold(layers, Free, fn(_, layer) {
case severity(delay, layer.depth, layer.cycle) {
Free -> Ok(Free)
Caught(_) -> Error(Nil)
}
})
case trial_run {
Ok(_) -> delay
_err -> find_delay(delay + 1, layers)
}
}
|