-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday_12.gleam
89 lines (76 loc) · 2.17 KB
/
day_12.gleam
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import gleam/int
import gleam/list
import gleam/otp/task
import gleam/regex
import gleam/string
import rememo/ets/memo
const task_timeout = 100
type Spring {
Damaged
Operational
Unknown
}
pub fn part_1(input: String) -> Int {
input
|> string.trim
|> string.split("\n")
|> list.map(fn(row) {
let assert [raw_springs, raw_damaged_groups] =
row
|> string.split(" ")
let springs =
raw_springs
|> string.to_graphemes
|> list.map(fn(spring) {
case spring {
"#" -> Damaged
"." -> Operational
___ -> Unknown
}
})
let damaged_groups =
raw_damaged_groups
|> string.split(",")
|> list.filter_map(int.parse)
task.async(fn() {
use cache <- memo.create()
iterate(springs, damaged_groups, cache)
})
})
|> list.map(task.await(_, task_timeout))
|> int.sum
}
pub fn part_2(input: String) -> Int {
let regex_options = regex.Options(case_insensitive: True, multi_line: True)
let assert Ok(line) = regex.compile("^([^ ]+) ([^ ]+)$", with: regex_options)
input
|> string.trim
|> regex.replace(each: line, with: "\\1?\\1?\\1?\\1?\\1 \\2,\\2,\\2,\\2,\\2")
|> part_1
}
fn iterate(springs: List(Spring), damaged_groups: List(Int), cache) -> Int {
use <- memo.memoize(#(springs, damaged_groups), with: cache)
case springs, damaged_groups {
[], [] -> 1
[], [_, ..] -> 0
[Damaged, ..], [] -> 0
[Damaged, ..], [group_size, ..next_groups] -> {
let #(group, next_springs) = springs |> list.split(at: group_size)
case
group |> list.length == group_size
&& !{ group |> list.any(fn(spring) { spring == Operational }) }
&& next_springs |> list.first != Ok(Damaged)
{
True -> iterate(next_springs |> list.drop(1), next_groups, cache)
False -> 0
}
}
[Operational, ..next_springs], _ ->
iterate(next_springs, damaged_groups, cache)
[Unknown, ..next_springs], [] ->
iterate(next_springs, damaged_groups, cache)
[Unknown, ..next_springs], [_, ..] ->
iterate([Damaged, ..next_springs], damaged_groups, cache)
+ iterate(next_springs, damaged_groups, cache)
}
}