1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
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);
}
|