master
Raw Download raw file
 1const std = @import("std");
 2const io = std.io;
 3const fmt = std.fmt;
 4
 5const Vector = enum { forward, up, down };
 6
 7// Submarine Commands
 8const Command = struct {
 9    vector: Vector,
10    thrust: u8,
11};
12
13const Coordinate = struct {
14    aim: u16,
15    depth: u32,
16    forward: u16,
17};
18
19pub fn main() !void {
20    const stdin = io.getStdIn().reader();
21    const allocator = std.heap.page_allocator;
22
23    // Read from stdin, line by line
24    // split on " ", parse, and
25    // insert into ArrayList of Commands
26    var buf: [128]u8 = undefined;
27    var course = std.ArrayList(Command).init(allocator);
28    defer course.deinit();
29    while (try stdin.readUntilDelimiterOrEof(&buf, '\n')) |line| {
30        var line_parts = std.mem.split(u8, line, " ");
31        var c = Command{
32            .vector = undefined,
33            .thrust = undefined,
34        };
35        const raw_vector = line_parts.first();
36        if (std.mem.eql(u8, raw_vector, "forward")) {
37            c.vector = Vector.forward;
38        } else if (std.mem.eql(u8, raw_vector, "up")) {
39            c.vector = Vector.up;
40        } else if (std.mem.eql(u8, raw_vector, "down")) {
41            c.vector = Vector.down;
42        }
43        var raw_thrust = line_parts.next().?;
44        c.thrust = fmt.parseUnsigned(u8, raw_thrust, 10) catch |err| {
45            std.debug.print("PARSE ERR: {} {s}\n", .{ err, raw_thrust });
46            continue;
47        };
48
49        try course.append(c);
50        //std.debug.print("{}\n", .{c});
51    }
52    var p = Coordinate{
53        .aim = 0,
54        .depth = 0,
55        .forward = 0,
56    };
57    const cmds = course.items;
58    for (cmds) |c| {
59        p = switch (c.vector) {
60            .down => Coordinate{
61                .aim = p.aim + c.thrust,
62                .depth = p.depth,
63                .forward = p.forward,
64            },
65            .up => Coordinate{
66                .aim = p.aim - c.thrust,
67                .depth = p.depth,
68                .forward = p.forward,
69            },
70            .forward => blk: {
71                var depth_delta: u16 = 0;
72                if (@mulWithOverflow(u16, c.thrust, p.aim, &depth_delta)){
73                    return error.Overflow;
74                }
75                break :blk Coordinate{
76                    .aim = p.aim,
77                    .depth = p.depth + depth_delta,
78                    .forward = p.forward + c.thrust,
79                };
80            },
81        };
82    }
83    const ans: u32 = @as(u32, p.depth) * p.forward;
84    std.debug.print("{}, {d}\n", .{ p, ans });
85}