IQVDJCKL3I7FOUWFEYI4HOUZQP3P7LAWOW5PPN7XYG2IX6M63NDQC const std = @import("std");const PATH = "../input/day12.txt";const CardinalType = u2;const Cardinal = enum(CardinalType) {north,east,south,west,};const Ship = struct {dir: Cardinal = .east,x: isize = 0,y: isize = 0,fn manhattan(self: @This()) usize {const absx = std.math.absInt(self.x) catch unreachable;const absy = std.math.absInt(self.y) catch unreachable;return @intCast(usize, absx + absy);}};pub fn first(allocator: ?std.mem.Allocator) anyerror!usize {_ = allocator;const file = @embedFile(PATH);var lines = std.mem.tokenize(u8, file, "\n");var ship = Ship{};while (lines.next()) |line| {var op = line[0];if (op == 'F') {switch (ship.dir) {.north => op = 'N',.east => op = 'E',.west => op = 'W',.south => op = 'S',}}switch (op) {'N' => ship.y -= try std.fmt.parseUnsigned(isize, line[1..], 0),'S' => ship.y += try std.fmt.parseUnsigned(isize, line[1..], 0),'W' => ship.x -= try std.fmt.parseUnsigned(isize, line[1..], 0),'E' => ship.x += try std.fmt.parseUnsigned(isize, line[1..], 0),'R' => {const deg = try std.fmt.parseUnsigned(u9, line[1..], 0);const pos: i4 = @enumToInt(ship.dir);ship.dir = @intToEnum(Cardinal, @mod(pos + @intCast(i4, deg / 90), std.math.maxInt(CardinalType) + 1));},'L' => {const deg = try std.fmt.parseUnsigned(u9, line[1..], 0);const pos: i4 = @enumToInt(ship.dir);ship.dir = @intToEnum(Cardinal, @mod(pos - @intCast(i4, deg / 90), std.math.maxInt(CardinalType) + 1));},else => unreachable,}}return ship.manhattan();}const Waypoint = struct {x: isize = 10,y: isize = -1,};pub fn second(allocator: ?std.mem.Allocator) anyerror!usize {_ = allocator;var file = @embedFile(PATH);var lines = std.mem.tokenize(u8, file, "\n");var ship = Ship{};var wp = Waypoint{};while (lines.next()) |line| {switch (line[0]) {'N' => wp.y -= try std.fmt.parseUnsigned(isize, line[1..], 0),'S' => wp.y += try std.fmt.parseUnsigned(isize, line[1..], 0),'W' => wp.x -= try std.fmt.parseUnsigned(isize, line[1..], 0),'E' => wp.x += try std.fmt.parseUnsigned(isize, line[1..], 0),'R', 'L' => {var deg = try std.fmt.parseUnsigned(u9, line[1..], 0);// R90 == L270 and R270 == L90if (deg == 90 and line[0] == 'L')deg = 270else if (deg == 270 and line[0] == 'L')deg = 90;// Rotate right with `deg` degreesswitch (deg) {0 => {},90 => {const tmp = wp.x;wp.x = -wp.y;wp.y = tmp;},180 => {wp.x *= -1;wp.y *= -1;},270 => {const tmp = wp.x;wp.x = wp.y;wp.y = -tmp;},else => unreachable,}},'F' => {const times = try std.fmt.parseUnsigned(isize, line[1..], 0);ship.x += wp.x * times;ship.y += wp.y * times;},else => unreachable,}}return ship.manhattan();}test "day12a" {try std.testing.expectEqual(@as(usize, 1589), try first(std.testing.allocator));}test "day12b" {try std.testing.expectEqual(@as(usize, 23960), try second(std.testing.allocator));}
R180S4L90S2R90W3F30R90W3L90F68L90E5F88S1L90F46W5F51S2L90F53S5F19W2L90F91E2S3F83N5F79W1S3F11E4F53W4S5R90E1F76R90F47E5R90W3R90S5L180W5N4F10S2R90S4W4F29S5F34E2S4R90F73N2F43W1N4R90S3F26S5W1N5R90W3F29R90W4F81R90E5S4W1F73N2E1F66L90E4S4E3N2F34L90W1F13S4E2F21N5E5N2F65L90N3R270F49E5L90E5R90F20S4F99W3N2E5L90F94R90S2R90S3F47S3R90F71W1R90N4E5S1F72L90F18E5F94L270F80W5R180N1F40R180N1E3N5F29R90E1R90E3L180E3R90S2L90E3L180F80E2S5E1N2L180F25N2L90F66R90F48N3L180N3R90E5R90F52R180S5L270S4L90F53S4W3W4F36W2N2N4L90W1R90E4F30N5W1S2W5F98W1N1F92L180N2R90S4L90F66N3L90F33W2S2E4F8W2L180F15S1E1F14S1W2L270F86E1R180W5R90N3L90N5E1F78N1L90F1F73R90F68W4F79F34N5R180E5L180S3W5F27R180F70R90S4F62L180N3R90S5F4R90S5W2N5R90F81L90N1F32E2N1W2L180E5R180S3E3R90S3F1N5E3F60W2F58L180S2E3L90F36L90E4E1F29W2R90R180N3L90R180S5W1F13R90W5S2R180F16W4L90W2S5F25R90F40L90L90F76S2R180N2R180W4S5F61N4E1F57E5F72W4F61R90S4F52W2N1F30L90F59N1L90W2N2F51E5F16S1W3L90F92E3N2F22L180N3F10E4N2F43R90F99S3R180E1S1W2L180F56N3F6N4F21L90N4L180N4F15E5S3W1F57E3S4W3L90S3L90F41E1S5L90F63N4F89F57S1L90S4L180F96L180N5E4L90E1S1F77S3L90E4L90E5L90N3L180S1N2L90N3R90F45R180F57N3R90E4L180F37L90W2R90S1R90N3F77W5F80S1S5R90N5E5S3L270F15L180W5F48E1L180S4E1S4W5F76S1E1S1F55L90F70R180R90E4R90S3E2S3F84S4W3F100R90S1L90F37W4F3R180N3R90L90W2F28R270N5R180S2E4F54L90W5R90F79N3R90F34W1N3F76W3F2W1L90R90F72N1E3F79W1L90F8E4F87E2F4S3L90F100F94E4R270S1E2F70E4L90S2W5L90S5W2S2W5F19E2E1F62L90F55E3R180F74S3W2F66L180F32W5F66W1F48S3R90N5W2N2F18E3F41L90N4F56L90R90F42R90S3L90E2S2F7W3N5L180L90L90N5L90W4F82W2F68S1E3S2F87L90F93L90F16L90S4L90N3E2R90S2R180F94W1S3F68S2F70S3W4F29E5R180S2F63L180F65R90W1F64E1L180L90S5F65L90N3N4L270S1E2S3W3N1E5F16E2L90N1L90E1S4W2R180F27N1R180E2L90F20N1W3N1R90W5R90E3S2F48N1R180N3W1S4F92S3R90S5E1W5R90S2W1L90R180E3N3E1R180E4L90E5L90W3L270E1S5W5L180W3S2F16W5S4R90N3L90N4F43N2F83S2W5F58W4N5R180E3F81L90F61L90W4F41E3N2F74R90F6R90W1F18R90R90N2F87S4F16S3E3F67R90E2L90S4R90F5W1R90W4F54S1W1F100S5E2L90W3F61L180W2S3F68F35N3R180E4R270S5E4L180S3R90N5E4F60W4S1L90L180N5L180W3S1E3S1N2E4R180N4F7N3W4F89N4E3L90F97