Add '2019/' from commit 'fc21396bc86bc0f706225f4f6e1d8294d344ca53'
git-subtree-dir: 2019 git-subtree-mainline:f1be11fca8
git-subtree-split:fc21396bc8
This commit is contained in:
146
2019/11/src/main.zig
Normal file
146
2019/11/src/main.zig
Normal file
@@ -0,0 +1,146 @@
|
||||
const std = @import("std");
|
||||
const intcode = @import("intcode");
|
||||
|
||||
const boardX = 155;
|
||||
const boardY = 100;
|
||||
|
||||
const Point = struct {
|
||||
x: usize,
|
||||
y: usize,
|
||||
|
||||
fn go(self: Point, d: Compass) Point {
|
||||
var out = Point{.x = self.x, .y = self.y};
|
||||
|
||||
switch (d) {
|
||||
.North => out.y -= 1,
|
||||
.East => out.x += 1,
|
||||
.South => out.y += 1,
|
||||
.West => out.x -= 1,
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
const Compass = enum(u8) {
|
||||
North = 0,
|
||||
East = 1,
|
||||
South = 2,
|
||||
West = 3,
|
||||
|
||||
fn turn(self: Compass, direction: intcode.Word) Compass {
|
||||
return switch (direction) {
|
||||
0 => self.widdershins(),
|
||||
1 => self.deasil(),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
fn deasil(self: Compass) Compass {
|
||||
if (self == .West) return .North;
|
||||
|
||||
return @intToEnum(Compass, @enumToInt(self)+1);
|
||||
}
|
||||
|
||||
fn widdershins(self: Compass) Compass {
|
||||
if (self == .North) return .West;
|
||||
|
||||
return @intToEnum(Compass, @enumToInt(self)-1);
|
||||
}
|
||||
};
|
||||
|
||||
const Colour = enum(u8) {
|
||||
Black = 0,
|
||||
White = 1,
|
||||
};
|
||||
|
||||
const Cell = struct {
|
||||
colour: Colour,
|
||||
touched: bool = false,
|
||||
};
|
||||
|
||||
const Board = [boardY][boardX]Cell;
|
||||
|
||||
fn runMachine(m: *intcode.Machine) void {
|
||||
if (m.run()) {} else |err| {
|
||||
std.debug.warn("Machine failed to run successfully: {}\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
fn run(alloc: *std.mem.Allocator, program: []intcode.Word, part1: bool) !void {
|
||||
const part2 = !part1;
|
||||
|
||||
var board: Board = undefined;
|
||||
for (board) |*row| {
|
||||
for (row) |*cell| {
|
||||
cell.* = Cell{.colour = .Black, .touched = false};
|
||||
}
|
||||
}
|
||||
|
||||
// Current state of the robot
|
||||
var pos = Point{.x = boardX / 2, .y = boardY / 2};
|
||||
var direction = Compass.North;
|
||||
|
||||
// Start on a white panel in part 2
|
||||
if (part2) board[pos.y][pos.x].colour = .White;
|
||||
|
||||
var machine = try intcode.Machine.init(alloc, program);
|
||||
defer machine.deinit();
|
||||
var robot = try std.Thread.spawn(&machine, runMachine);
|
||||
|
||||
// Robot event loop
|
||||
while (!machine.halted) {
|
||||
// Feed it the colour at its current position
|
||||
try machine.writeToInput(@enumToInt(board[pos.y][pos.x].colour));
|
||||
|
||||
// Read back instructions
|
||||
var paintColour = try machine.readFromOutput();
|
||||
var turnDirection = try machine.readFromOutput();
|
||||
|
||||
// Paint
|
||||
board[pos.y][pos.x].colour = @intToEnum(Colour, @intCast(u8, paintColour));
|
||||
board[pos.y][pos.x].touched = true;
|
||||
|
||||
// Turn in the specified direction and move forward one square
|
||||
direction = direction.turn(turnDirection);
|
||||
pos = pos.go(direction);
|
||||
|
||||
// Ugh. Give the other thread some time to decide to halt or not.
|
||||
std.time.sleep(1000);
|
||||
}
|
||||
|
||||
robot.wait();
|
||||
|
||||
if (part1) {
|
||||
var touched: usize = 0;
|
||||
for (board) |row| {
|
||||
for (row) |cell| {
|
||||
if (cell.touched) touched += 1;
|
||||
}
|
||||
}
|
||||
|
||||
std.debug.warn("Day 11, Part 1: {}\n", touched);
|
||||
} else {
|
||||
for (board) |row| {
|
||||
for (row) |cell| {
|
||||
switch (cell.colour) {
|
||||
.Black => std.debug.warn(" "),
|
||||
.White => std.debug.warn("#"),
|
||||
}
|
||||
}
|
||||
std.debug.warn("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const alloc = &arena.allocator;
|
||||
|
||||
var program = try intcode.loadFromStdIn(alloc);
|
||||
|
||||
try run(alloc, program, true);
|
||||
try run(alloc, program, false);
|
||||
}
|
Reference in New Issue
Block a user