const std = @import("std");
const builtin = @import("builtin");
pub const CommandType = enum {
unknown,
forward,
down,
up,
};
pub const Command = struct {
cmd: CommandType,
value: i32,
};
fn readInputFile(allocator: std.mem.Allocator, filename: []const u8) anyerror![]Command {
const file = try std.fs.cwd().openFile(filename, .{ .read = true });
defer file.close();
var result = std.ArrayList(Command).init(allocator);
var index: u32 = 0;
var buffer: [16]u8 = undefined;
const reader = file.reader();
die: while (true) {
const byte = reader.readByte() catch break :die;
switch (byte) {
' ' => {
var cmd: CommandType = .unknown;
if (std.ascii.eqlIgnoreCase(buffer[0..index], "forward")) {
cmd = .forward;
} else if (std.ascii.eqlIgnoreCase(buffer[0..index], "down")) {
cmd = .down;
} else if (std.ascii.eqlIgnoreCase(buffer[0..index], "up")) {
cmd = .up;
}
const value = (try reader.readByte()) - 48;
try result.append(.{ .cmd = cmd, .value = value });
_ = reader.readByte() catch break :die;
if (builtin.os.tag == .windows) {
// NOTE: Read another byte on windows due to two-byte line-endings.
_ = reader.readByte() catch break :die;
}
index = 0;
},
else => {
buffer[index] = byte;
index += 1;
},
}
}
return result.items;
}
pub fn task1(commands: []const Command) i32 {
var horiz_pos: i32 = 0;
var depth: i32 = 0;
for (commands) |command| {
switch (command.cmd) {
.forward => {
horiz_pos += command.value;
},
.down => {
depth += command.value;
},
.up => {
depth -= command.value;
},
else => {},
}
}
return horiz_pos * depth;
}
pub fn task2(commands: []const Command) i32 {
var horiz_pos: i32 = 0;
var depth: i32 = 0;
var aim: i32 = 0;
for (commands) |command| {
switch (command.cmd) {
.forward => {
horiz_pos += command.value;
depth += aim * command.value;
},
.down => {
aim += command.value;
},
.up => {
aim -= command.value;
},
else => {},
}
}
return horiz_pos * depth;
}
pub fn main() anyerror!void {
var buffer: [65536]u8 = undefined;
const allocator = std.heap.FixedBufferAllocator.init(&buffer).allocator();
const input = try readInputFile(allocator, "input.txt");
const task_1_result = task1(input);
std.log.info("Task 1 result: {}", .{task_1_result});
const task_2_result = task2(input);
std.log.info("Task 2 result: {}", .{task_2_result});
}