From c45d2e403278608e4c0baef70343e03149d499b3 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Mon, 6 Dec 2021 23:04:43 +0000 Subject: day 5: nim --- d5.nim | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 d5.nim diff --git a/d5.nim b/d5.nim new file mode 100644 index 0000000..5c5e94e --- /dev/null +++ b/d5.nim @@ -0,0 +1,71 @@ +import std/sets, std/strutils, std/sugar, std/sequtils, std/os + +type + Num = range[0..9999999] + Pos = tuple[x, y: Num] + Vent = tuple[a, b: Pos] + VentType = enum vt_horz vt_vert vt_diag + +proc parse_pos(pos: string): Pos = + let xy = pos.split(',', maxsplit=1).map(parse_int) + return (xy[0].Num, xy[1].Num) + +proc read_vents(filename: string): seq[Vent] = + let f = open(filename) + defer: f.close() + result = collect: + for line in f.lines(): + let ab = line.split(" -> ", maxsplit=1).map(parse_pos) + (ab[0], ab[1]) + +func classify(v: Vent): VentType = + if v.a.x == v.b.x: + return vt_vert + if v.a.y == v.b.y: + return vt_horz + return vt_diag + +iterator intersect(u, v: Vent): Pos = + var + uc = classify(u) + vc = classify(v) + if uc == vc: + for x in max(u.a.x, v.a.x) .. min(u.b.x, v.b.x): + for y in max(u.a.y, v.a.y) .. min(u.b.y, v.b.y): + yield (x, y) + else: + var + u = u + v = v + if uc == vt_vert and vc == vt_horz: + (u, v) = (v, u) + let + x = v.a.x + y = u.a.y + if x >= u.a.x and x <= u.b.x and y >= v.a.y and y <= v.b.y: + yield (x, y) + +func normalise(v: Vent): Vent = + result = v + if ((classify(v) != vt_vert and v.b.x < v.a.x) or + (classify(v) == vt_vert and v.b.y < v.a.y)): + result = (v.b, v.a) + +proc part1(vents: seq[Vent]): int = + var intersections: HashSet[Pos] + for i, a in vents: + if classify(a) == vt_diag: continue + let a = normalise(a) + for b in vents[i + 1 .. ^1]: + if classify(b) == vt_diag: continue + let b = normalise(b) + for p in intersect(a, b): + intersections.incl(p) + return len(intersections) + +when is_main_module: + var filename: string = "5.in" + if param_count() == 1: + filename = param_str(1) + let vents = read_vents(filename) + echo part1(vents) -- cgit v1.2.3-54-g00ecf