-
Notifications
You must be signed in to change notification settings - Fork 0
/
day_13.gleam
83 lines (69 loc) · 1.89 KB
/
day_13.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
import gleam/int
import gleam/list
import gleam/result
import gleam/string
pub fn part_1(input: String) -> Int {
input
|> solve(with_one_smudge: False)
}
pub fn part_2(input: String) -> Int {
input
|> solve(with_one_smudge: True)
}
fn solve(input: String, with_one_smudge with_one_smudge: Bool) -> Int {
input
|> string.trim
|> string.split("\n\n")
|> list.map(fn(pattern) {
let rows = pattern |> string.split("\n")
rows
|> find_reflecting_row(with_one_smudge:)
|> result.map(int.multiply(_, 100))
|> result.lazy_or(fn() {
rows
|> to_cols
|> find_reflecting_row(with_one_smudge:)
})
})
|> result.values
|> int.sum
}
fn find_reflecting_row(
rows: List(String),
with_one_smudge with_one_smudge: Bool,
) -> Result(Int, Nil) {
let row_count = list.length(rows)
list.range(1, row_count - 1)
|> list.find(fn(n) {
let #(upper_rows, lower_rows) =
rows
|> list.split(at: n)
|> fn(pair) {
let #(upper_rows, lower_rows) = pair
let amount = int.min(n, row_count - n)
let upper_rows = upper_rows |> list.reverse |> list.take(amount)
let lower_rows = lower_rows |> list.take(amount)
#(upper_rows, lower_rows)
}
case with_one_smudge {
True -> list.map2(upper_rows, lower_rows, count_row_diffs) |> int.sum == 1
False -> upper_rows == lower_rows
}
})
}
fn count_row_diffs(row_a: String, row_b: String) -> Int {
case row_a, row_b {
"", "" -> 0
"#" <> row_a, "#" <> row_b -> count_row_diffs(row_a, row_b)
"." <> row_a, "." <> row_b -> count_row_diffs(row_a, row_b)
"#" <> row_a, "." <> row_b -> count_row_diffs(row_a, row_b) + 1
"." <> row_a, "#" <> row_b -> count_row_diffs(row_a, row_b) + 1
_, _ -> panic
}
}
fn to_cols(rows: List(String)) -> List(String) {
rows
|> list.map(string.to_graphemes)
|> list.transpose
|> list.map(string.concat)
}