-
Notifications
You must be signed in to change notification settings - Fork 0
/
day04.kk
67 lines (49 loc) 路 1.57 KB
/
day04.kk
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
module day04
import std/os/readline
effect fstream
ctl read-line() : string
effect yield<a>
ctl yield(x : a) : ()
type overlap-calculation-mode
Fully
Partial
pub fun main()
var counter := 0
with ctl yield(x : bool)
counter := counter + int(x)
resume(())
with ctl read-line()
val line = readline()
resume(line)
inner-main(Partial)
println(counter)
fun inner-main(mode : overlap-calculation-mode) : <fstream, yield<bool>, div, exn> ()
val input = read-line()
if input.is-empty() then
()
else
val (assign1, assign2) = parse-pair-of-assignments(input)
val overlaps = match mode
Fully -> assign1.contains(assign2) || assign2.contains(assign1)
Partial -> assign1.overlaps(assign2)
yield(overlaps)
inner-main(mode)
fun parse-pair-of-assignments(line : string) : exn (int-range, int-range)
match line.split(",").map(parse-assignment)
[assign1, assign2] -> (assign1, assign2)
_ -> throw("Invalid number of assignments on line")
fun parse-assignment(ss : string) : exn int-range
match ss.split("-").map(fn(s) parse-int(s))
[Just(start), Just(end)] -> Int-range(start, end)
_ -> throw("invalid assignment syntax: " ++ ss)
// Inclusive integer range.
struct int-range
start : int
end : int
fun contains(r1 : int-range, r2 : int-range) : bool
r1.start <= r2.start && r2.end <= r1.end
fun overlaps(r1 : int-range, r2 : int-range) : bool
val together = Int-range(r1.start.min(r2.start), r1.end.max(r2.end))
together.count() < r1.count() + r2.count()
fun count(r : int-range) : int
r.end - r.start + 1