const std = @import("std"); const print = std.debug.print; const assert = std.debug.assert; const ArrayList = std.ArrayList; const HashMap = std.HashMap; const mem = std.mem; const fin = mem.trim(u8, @embedFile("./example.txt"), &std.ascii.whitespace); var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = gpa.allocator(); const Direction = [_][2]u64{ [_]i64{ -1, 0 }, [_]i64{ 0, 1 }, [_]i64{ 1, 0 }, [_]i64{ 0, -1 }, }; const Move = struct { dir: usize, dist: isize, color: []const u8, }; fn abs(a: i64, b: i64) u64 { return @as(u64, @bitCast(@max(a, b) - @min(a, b))); } fn evaluate(moves: []const Move) !u64 { var polygon = ArrayList([2]i64).init(allocator); defer polygon.deinit(); var curr = [_]i64{ 0, 0 }; var bl: u64 = 0; for (moves) |m| { const next = switch (m.dir) { 'U' => .{ curr[0] - m.dist, curr[1], }, 'R' => .{ curr[0], curr[1] + m.dist, }, 'D' => .{ curr[0] + m.dist, curr[1], }, 'L' => .{ curr[0], curr[1] - m.dist, }, else => unreachable, }; bl += abs(curr[0], next[0]) + abs(curr[1], next[1]); try polygon.append(next); curr = next; } const points = polygon.items; const nPoints = points.len; var a2: i64 = 0; for (points, 1..) |f, j| { const s = points[j % nPoints]; a2 += f[0] * s[1] - f[1] * s[0]; } const a: usize = @bitCast(@divTrunc(if (a2 > 0) a2 else -a2, 2)); return a + 1 + bl / 2; } pub fn solve(moves: []const Move) !void { const part1 = try evaluate(moves); print("{d}\n", .{part1}); var movespt2 = ArrayList(Move).init(allocator); defer movespt2.deinit(); for (moves) |m| { const dist = try std.fmt.parseInt(i64, m.color[0..5], 16); const dir: u8 = switch (m.color[5]) { '0' => 'R', '1' => 'D', '2' => 'L', '3' => 'U', else => unreachable, }; try movespt2.append(Move{ .dist = dist, .dir = dir, .color = m.color, }); } const part2 = try evaluate(movespt2.items); print("{d}\n", .{part2}); } pub fn main() !void { var splitLines = mem.splitScalar(u8, fin, '\n'); var moves = ArrayList(Move).init(allocator); while (splitLines.next()) |line| { var toks = mem.tokenizeAny(u8, line, " (#)"); const dir = toks.next().?[0]; const dist = try std.fmt.parseInt(i64, toks.next().?, 10); const color = toks.next().?; try moves.append(Move{ .dir = dir, .dist = dist, .color = color, }); } try solve(moves.items); }