--- /dev/null
+#load "core/std"
+
+use package core
+
+Line :: struct {
+ x1, y1: i32;
+ x2, y2: i32;
+}
+
+line_points :: (l: Line) -> Iterator(Point) {
+ Context :: struct {
+ l: Line;
+ dx, dy: i32;
+ curr_t: i32;
+ max_t: i32;
+ }
+
+ if l.x1 != l.x2 && l.y1 != l.y2 {
+ if math.abs(l.x1 - l.x2) != math.abs(l.y1 - l.y2) {
+ return .{ null, ((a:rawptr) => .{0,0}, false), null_proc };
+ }
+ }
+
+ c := new(Context);
+ c.l = l;
+ c.curr_t = 0;
+ c.max_t = math.max(math.abs(l.x1 - l.x2), math.abs(l.y1 - l.y2));
+ c.dx = 1 if l.x2 > l.x1 else -1 if l.x2 < l.x1 else 0;
+ c.dy = 1 if l.y2 > l.y1 else -1 if l.y2 < l.y1 else 0;
+
+ next :: (use c: ^Context) -> (Point, bool) {
+ if curr_t > max_t do return .{0,0}, false;
+
+ defer curr_t += 1;
+ return .{ l.x1 + curr_t * dx, l.y1 + curr_t * dy }, true;
+ }
+
+ return .{c, next, cfree};
+}
+
+Point :: struct {x, y: u32;}
+#match hash.to_u32 (use p: Point) => x * 146307 + y * 172363;
+#operator == (p1, p2: Point) => p1.x == p2.x && p1.y == p2.y;
+
+main :: (args) => {
+ for file: os.with_file("./tests/aoc-2021/input/day05.txt") {
+ reader := io.reader_make(file);
+
+ lines: [..] Line;
+
+ while !io.reader_empty(^reader) {
+ x1 := io.read_u32(^reader);
+ io.skip_bytes(^reader, 1);
+ y1 := io.read_u32(^reader);
+ io.skip_bytes(^reader, 4);
+
+ x2 := io.read_u32(^reader);
+ io.skip_bytes(^reader, 1);
+ y2 := io.read_u32(^reader);
+ io.skip_whitespace(^reader);
+
+ lines << .{x1, y1, x2, y2};
+ }
+
+ point_count: Map(Point, u32);
+
+ for ^line: lines {
+ for p: line_points(*line) {
+ if point_count->has(p) {
+ point_count[p] = point_count[p] + 1;
+ } else {
+ point_count[p] = 1;
+ }
+ }
+ }
+
+ count := 0;
+ for ^ point_count.entries {
+ if it.value >= 2 do count += 1;
+ }
+
+ printf("Part 2: {}\n", count);
+ }
+}
\ No newline at end of file