const std = @import("std"); pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = gpa.allocator(); defer _ = gpa.deinit(); const stdin = std.io.getStdIn(); var buf_io = std.io.bufferedReader(stdin.reader()); var reader = buf_io.reader(); const text = try reader.readAllAlloc(allocator, 100000); defer allocator.free(text); std.debug.print("{}", .{try visit(allocator, text)}); } fn visit(allocator: std.mem.Allocator, seq: []const u8) !u32 { var visited = std.AutoHashMap([2]i32, void).init(allocator); defer visited.deinit(); var santa: [2]i32 = .{ 0, 0 }; var robosanta: [2]i32 = .{ 0, 0 }; // Set origin as visited try visited.put(santa, {}); for (0.., seq) |i, c| { if (i % 2 == 0) { santa = move(santa, c); try visited.put(santa, {}); } else { robosanta = move(robosanta, c); try visited.put(robosanta, {}); } } return visited.count(); } fn move(current: [2]i32, c: u8) [2]i32 { return switch (c) { '>' => .{ current[0] + 1, current[1] }, '<' => .{ current[0] - 1, current[1] }, '^' => .{ current[0], current[1] + 1 }, 'v' => .{ current[0], current[1] - 1 }, else => current, }; } test "day-tests" { try std.testing.expectEqual(try visit(std.testing.allocator, "^v"), 3); try std.testing.expectEqual(try visit(std.testing.allocator, "^>v<"), 3); try std.testing.expectEqual(try visit(std.testing.allocator, "^v^v^v^v^v"), 11); }