summaryrefslogtreecommitdiff
path: root/day5/part2/main.ha
blob: 4f38b58d760900e42241dcd0d9f148eaf8caa41c (plain)
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
use fmt;
use io;
use os;
use sort;
use sort::cmp;
use strconv::{stou64};
use strings::{cut, fromutf8_unsafe, split};

fn cmpranges(a: const *opaque, b: const *opaque) int = {
	const a = *(a: const *(u64, u64)), b = *(b: const *(u64, u64));
	return if (a.0 < b.0) -1
		else if (a.0 > b.0) 1
		else if (a.1 < b.1) -1
		else if (a.1 > b.1) 1
		else 0;
};

fn fresh_ingredients(fresh_ranges: [](u64, u64)) u64 = {
	let ingredients: u64 = 0;

	sort::sort(fresh_ranges: []opaque, size((u64, u64)), &cmpranges)!;

	let i: size = 0;

	for (true) {
		for (true) {
			if (fresh_ranges[i].1 >= fresh_ranges[i + 1].0) {
				if (fresh_ranges[i].1 < fresh_ranges[i + 1].1)
					fresh_ranges[i].1 = fresh_ranges[i + 1].1;
				delete(fresh_ranges[i + 1]);
			} else break;
		};

		if (i < len(fresh_ranges) - 2) i += 1
		else break;
	};

	for (let range .. fresh_ranges) {
		ingredients += (range.1 - range.0) + 1;
	};

	free(fresh_ranges);

	return ingredients;
};

export fn main() void = {
	let handle = os::open("input.txt")!;
	defer io::close(handle)!;

	let buf = io::drain(handle)!;
	defer free(buf);

	let lines = split(fromutf8_unsafe(buf), "\n")!;
	defer free(lines);

	let ranges: [](u64, u64) = [];

	for (let line .. lines) {
		if (line == "")
			break;

		let range = cut(line, "-");

		let start = stou64(range.0)!;
		let end = stou64(range.1)!;

		append(ranges, (start, end))!;
	};

	let answer = fresh_ingredients(ranges);

	fmt::printfln("Answer: {}", answer)!;
};