Add '2019/' from commit 'fc21396bc86bc0f706225f4f6e1d8294d344ca53'

git-subtree-dir: 2019
git-subtree-mainline: f1be11fca8
git-subtree-split: fc21396bc8
This commit is contained in:
2022-01-09 17:07:24 +00:00
36 changed files with 2978 additions and 0 deletions

1
2019/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
zig-cache

14
2019/01/build.zig Normal file
View File

@@ -0,0 +1,14 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("01", "src/main.zig");
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

100
2019/01/input Normal file
View File

@@ -0,0 +1,100 @@
109067
75007
66030
93682
83818
108891
139958
129246
80272
119897
112804
69495
95884
85402
148361
75986
120063
127683
146962
76907
61414
98452
134330
53858
82662
143258
82801
60279
131782
105989
102464
96563
71172
113731
90645
94830
133247
110149
54792
134863
125919
145490
69836
108808
87954
148957
110182
126668
148024
96915
117727
147378
75967
91915
60130
85331
66800
103419
72627
72687
61606
113160
107082
110793
61589
105005
73952
65705
117243
140944
117091
113482
91379
148185
113853
119822
78179
85407
119886
109230
68783
63914
51101
93549
53361
127984
106315
54997
138941
81075
120272
120307
98414
115245
105649
89793
88421
121104
97084
56928

33
2019/01/src/main.zig Normal file
View File

@@ -0,0 +1,33 @@
const std = @import("std");
fn rocket(in: i64) i64 {
var x: i64 = @divFloor(in, 3) - 2;
if (x < 0) {
x = 0;
}
return x;
}
pub fn main() anyerror!void {
const file = std.io.getStdIn();
const stream = &file.inStream().stream;
var buf: [20]u8 = undefined;
var sum1: i64 = 0; // part 1
var sum2: i64 = 0; // part 2
while (try stream.readUntilDelimiterOrEof(&buf, '\n')) |line| {
const mass = try std.fmt.parseInt(i64, line, 10);
var rock = rocket(mass);
sum1 += rock;
while (rock > 0) {
sum2 += rock;
rock = rocket(rock);
}
}
std.debug.warn("Part 1: {}\n", sum1);
std.debug.warn("Part 2: {}\n", sum2);
}

15
2019/02/build.zig Normal file
View File

@@ -0,0 +1,15 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("part-02", "src/main.zig");
exe.addPackagePath("intcode", "../lib/intcode/intcode.zig");
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

1
2019/02/input Normal file
View File

@@ -0,0 +1 @@
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,13,19,2,9,19,23,1,23,6,27,1,13,27,31,1,31,10,35,1,9,35,39,1,39,9,43,2,6,43,47,1,47,5,51,2,10,51,55,1,6,55,59,2,13,59,63,2,13,63,67,1,6,67,71,1,71,5,75,2,75,6,79,1,5,79,83,1,83,6,87,2,10,87,91,1,9,91,95,1,6,95,99,1,99,6,103,2,103,9,107,2,107,10,111,1,5,111,115,1,115,6,119,2,6,119,123,1,10,123,127,1,127,5,131,1,131,2,135,1,135,5,0,99,2,0,14,0

56
2019/02/src/main.zig Normal file
View File

@@ -0,0 +1,56 @@
const std = @import("std");
const intcode = @import("intcode");
fn run(alloc: *std.mem.Allocator, program: []intcode.Word, noun: intcode.Word, verb: intcode.Word) !intcode.Word {
program[1] = noun;
program[2] = verb;
var machine = try intcode.Machine.Run(alloc, program);
defer machine.deinit();
return machine.memory[0];
}
fn runCopy(alloc: *std.mem.Allocator, program: []intcode.Word, noun: intcode.Word, verb: intcode.Word) !intcode.Word {
return run(alloc, program, noun, verb);
}
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);
// Part 1
std.debug.warn("Day 2, Part 1: {}\n", try runCopy(alloc, program, 12, 2));
// Part 2: 100*100 = 10,000 combinations to try.
var memory: []intcode.Word = try alloc.alloc(intcode.Word, program.len);
var done: bool = false;
var noun: intcode.Word = 0;
var verb: intcode.Word = 0;
std.debug.warn("Day 2, Part 2: ");
while (!done) {
std.mem.copy(intcode.Word, memory, program);
const result = try run(alloc, memory, noun, verb);
// Too high: 250800 (noun=33, verb=76)
if (result == 19690720) {
std.debug.warn("noun={} verb={}\n", noun, verb);
done = true;
}
noun += 1;
if (noun > 100) {
noun = 0;
verb += 1;
if (verb > 100) {
std.debug.warn("failed!\n");
}
}
}
}

14
2019/03/build.zig Normal file
View File

@@ -0,0 +1,14 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("03", "src/main.zig");
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

2
2019/03/input Normal file
View File

@@ -0,0 +1,2 @@
R1004,U520,R137,D262,L403,U857,R50,U679,R788,D98,L717,D1,R367,U608,L125,U703,L562,D701,L718,U357,R742,D860,R557,D117,R950,U546,L506,U836,R951,D460,L38,U893,L1,D217,R262,D950,R239,U384,R971,D289,R323,U878,L525,U687,L831,U523,R94,D33,L879,D318,R633,D775,R879,D351,L120,D8,R31,U49,R328,D598,L380,D160,R261,D716,R459,U533,L444,U412,L326,U93,L193,D621,R236,U769,L319,D885,L559,U509,L62,U321,L667,D505,R556,U159,L5,U126,L262,D946,L168,U491,L56,D831,R926,U926,R562,D270,R785,U436,R852,D629,R872,U716,R549,U435,R462,U191,R318,U91,L637,D682,R647,D53,L789,D725,R312,D366,L287,U29,R85,D657,R88,U300,R795,U378,R800,D391,L594,U791,R205,U352,L510,D975,R47,D311,R319,U579,R214,D112,R996,U874,R328,D578,R37,U689,L543,U16,L580,D230,L714,D58,L580,D658,R218,U535,R149,U996,L173,D316,L90,D372,L364,U700,L60,D70,L250,U276,R580,U505,L682,U943,R336,U847,R810,U963,R874,D740,R732,D328,R926,D447,R638,D102,R696,U211,L594,D354,R384,U81,L884,U916,L168,U759,R631,D702,L598,D382,L647,U642,R537,U53,R897,U954,R263,U445,L41,D91,L51,D338,R219,U269,L689,D172,R627,D287,L440,D504,L253,D252,R815,D108,L282,U835,L243,U638,R910,D306,R755,D202,R69,D862,L537,D947,L180,D835,L111,U832,R939,D449,R180,U105,R892,D837,L153,U215,L695,U957,R923,U496,R608,U739,L711,U700,L838,D117,R479,U852,R795,D955,L386,D70,R728,D40,R580,U777,L877,U284,R414,D300,R105,D372,L317,D91,R653,U920,R956,D496,L543,D363,R374,D283,L696,U466,R467,D878,R660,U590,L962,U619,R991,U848,L648,D191,R459,U125,L998,U19,L214,U947,R188,U103,R916
L1008,U717,R288,D770,R270,U514,R109,D538,L719,U179,R466,D792,R421,U723,L22,U705,L284,U14,L478,U367,R727,U880,R620,D46,R377,U897,L731,U840,L910,D385,L257,U311,L596,D991,L668,D730,L707,D816,R47,U948,R84,D700,R299,U707,R261,D928,R358,D504,R309,U369,R931,U20,L940,U326,L362,D52,R98,D475,L907,D918,R931,D468,R279,D586,R592,U973,R753,D365,R694,U278,R934,U712,R441,U996,L989,D693,L211,D561,R105,D425,R53,U168,L451,U865,L585,D412,L857,U988,R724,U774,R295,U588,R329,D810,L698,D118,R277,U193,R309,U933,R186,D535,R409,U322,L849,U606,R590,U892,L542,D237,R475,D920,R679,U602,L477,D634,L988,D540,L323,U791,L375,U625,L621,U567,L943,U512,L239,D90,L66,U151,R83,U435,R612,D865,L177,U368,R326,U574,L241,U197,R499,U419,R297,U207,L311,D243,L559,D281,R513,U748,L884,U207,R71,D441,R133,D993,L4,D977,L669,U523,L564,U186,R477,U737,L685,U338,L456,U939,R774,U674,L97,D827,R237,D451,R618,D143,R750,U196,L559,D178,L693,D916,R334,U231,L651,U249,R620,U283,L387,U352,L915,U959,L693,U909,R320,U119,L617,U177,L993,D265,R667,U204,R59,D601,L579,U483,R155,D484,L44,D751,R915,U510,L552,U308,R505,U394,R585,U872,L617,U202,R928,U941,R235,U768,R666,D547,L244,D270,R353,D612,R384,U430,L685,D536,R103,U147,R794,D621,L52,U96,L557,D455,L635,D58,R265,U545,R938,D266,L173,U746,L672,D237,R286,U131,R487,U837,R394,D702,R49,U579,L699,U819,L448,D223,L982,D906,L397,U807,L737,D223,L791,D965,R436,U29,R908,D273,R194,U91,R232,U591,L336,D70,R467,U505,L341,U989,R278,U387,L442,U950,R487,D384,L534,D514,L433,U627,R381,U54,L847,U231,L590

160
2019/03/src/main.zig Normal file
View File

@@ -0,0 +1,160 @@
const std = @import("std");
const Error = error{ParseError};
const Point = struct {
X: i32,
Y: i32,
Steps: i32, // number of steps taken to reach this point
};
const Points = std.ArrayList(Point);
const Direction = enum(u8) {
Up = 'U',
Right = 'R',
Down = 'D',
Left = 'L',
pub fn parse(in: u8) anyerror!Direction {
return switch (in) {
'U' => .Up,
'R' => .Right,
'D' => .Down,
'L' => .Left,
else => Error.ParseError,
};
}
};
const Step = struct {
d: Direction,
l: i32,
pub fn parse(in: []const u8) anyerror!Step {
if (in.len < 2) {
return error.ParseError;
}
return Step{
.d = try Direction.parse(in[0]),
.l = try std.fmt.parseInt(i32, in[1..in.len], 10),
};
}
};
const World = struct {
entries: Points,
ticks: i32,
x: i32,
y: i32,
pub fn step(self: *World, in: Step) void {
std.debug.warn("Step {}: {}\n", self.ticks, in);
var i: i32 = 0;
switch (in.d) {
.Up => {
while (i < in.l) : (i += 1) {
self.y -= 1;
self.fill();
}
},
.Down => {
while (i < in.l) : (i += 1) {
self.y += 1;
self.fill();
}
},
.Left => {
while (i < in.l) : (i += 1) {
self.x -= 1;
self.fill();
}
},
.Right => {
while (i < in.l) : (i += 1) {
self.x += 1;
self.fill();
}
},
}
}
fn fill(self: *World) void {
self.ticks += 1;
const point = Point{ .X = self.x, .Y = self.y, .Steps = self.ticks };
std.debug.warn("\t{}\n", point);
self.entries.appendAssumeCapacity(point);
}
};
fn getLine(stream: *std.fs.File.InStream.Stream) anyerror![]Step {
var buf: [10240]u8 = undefined;
var out: [1000]Step = undefined;
var i: u32 = 0;
var line = (try stream.readUntilDelimiterOrEof(&buf, '\n')) orelse return Error.ParseError;
var iter = std.mem.separate(line, ",");
while (iter.next()) |value| {
std.debug.assert(i < out.len);
out[i] = try Step.parse(value);
i += 1;
}
return out[0..i];
}
fn manhattan(x: i32, y: i32) u32 {
return std.math.absCast(x) + std.math.absCast(y);
}
const maxEntries = 1024 * 1024;
pub fn main() anyerror!void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const alloc = &arena.allocator;
const file = std.io.getStdIn();
const stream = &file.inStream().stream;
var world: World = World{
.entries = try Points.initCapacity(alloc, maxEntries),
.ticks = 0,
.x = 0,
.y = 0,
};
// Line 1
for (try getLine(stream)) |item| {
world.step(item);
}
// reset to origin
const entriesA = world.entries;
world.entries = try Points.initCapacity(alloc, maxEntries);
world.ticks = 0;
world.x = 0;
world.y = 0;
// Line 2
for (try getLine(stream)) |item| {
world.step(item);
}
const entriesB = world.entries;
std.debug.warn("A: {} entries\nB: {} entries\n", entriesA.len, entriesB.len);
for (entriesA.toSlice()) |a| {
for (entriesB.toSlice()) |b| {
if (a.X == b.X and a.Y == b.Y) {
std.debug.warn("Match! {}, {} => {} : {}\n", a, b, manhattan(a.X, a.Y), a.Steps + b.Steps);
}
}
}
}

14
2019/04/build.zig Normal file
View File

@@ -0,0 +1,14 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("04", "src/main.zig");
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

53
2019/04/src/main.zig Normal file
View File

@@ -0,0 +1,53 @@
const std = @import("std");
const first = 171309;
const last = 643603;
// - [x] It is a six-digit number (implied)
// - [x] The value is within the range given in your puzzle input (implied)
// - [x] Two adjacent digits are the same (like 22 in 122345).
// - [x] Going from left to right, the digits never decrease; they only ever increase or stay the same (like 111123 or 135679).
inline fn tests1(num: i32, str: []u8) bool {
if (str[0] > str[1] or str[1] > str[2] or
str[2] > str[3] or str[3] > str[4] or
str[4] > str[5]) return false;
return str[0] == str[1] or str[1] == str[2] or
str[2] == str[3] or str[3] == str[4] or
str[4] == str[5];
}
inline fn tests2(num: i32, str: []u8) bool {
if (str[0] == str[1] and str[1] != str[2]) return true; // [0 1]2 3 4 5
if (str[1] == str[2] and str[0] != str[1] and str[2] != str[3]) return true; // 0[1 2]3 4 5
if (str[2] == str[3] and str[1] != str[2] and str[3] != str[4]) return true; // 0 1[2 3]4 5
if (str[3] == str[4] and str[2] != str[3] and str[4] != str[5]) return true; // 0 1 2[3 4]5
if (str[4] == str[5] and str[3] != str[4]) return true; // 0 1 2 3[4 5]
return false;
}
pub fn main() anyerror!void {
var count1: i32 = 0;
var count2: i32 = 0;
var i: i32 = first;
while (i <= last) : (i += 1) {
var buf: [6]u8 = undefined;
var numStr = try std.fmt.bufPrint(&buf, "{}", i);
if (tests1(i, numStr)) {
count1 += 1;
if (tests2(i, numStr)) {
count2 += 1;
}
}
}
//std.debug.warn(" 012345\n");
std.debug.warn("Part 1: matches: {}\n", count1);
std.debug.warn("Part 2: matches: {}\n", count2);
}

15
2019/05/build.zig Normal file
View File

@@ -0,0 +1,15 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("05", "src/main.zig");
exe.addPackagePath("intcode", "../lib/intcode/intcode.zig");
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

1
2019/05/input Normal file
View File

@@ -0,0 +1 @@
3,225,1,225,6,6,1100,1,238,225,104,0,1102,40,93,224,1001,224,-3720,224,4,224,102,8,223,223,101,3,224,224,1,224,223,223,1101,56,23,225,1102,64,78,225,1102,14,11,225,1101,84,27,225,1101,7,82,224,1001,224,-89,224,4,224,1002,223,8,223,1001,224,1,224,1,224,223,223,1,35,47,224,1001,224,-140,224,4,224,1002,223,8,223,101,5,224,224,1,224,223,223,1101,75,90,225,101,9,122,224,101,-72,224,224,4,224,1002,223,8,223,101,6,224,224,1,224,223,223,1102,36,63,225,1002,192,29,224,1001,224,-1218,224,4,224,1002,223,8,223,1001,224,7,224,1,223,224,223,102,31,218,224,101,-2046,224,224,4,224,102,8,223,223,101,4,224,224,1,224,223,223,1001,43,38,224,101,-52,224,224,4,224,1002,223,8,223,101,5,224,224,1,223,224,223,1102,33,42,225,2,95,40,224,101,-5850,224,224,4,224,1002,223,8,223,1001,224,7,224,1,224,223,223,1102,37,66,225,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1007,226,677,224,1002,223,2,223,1005,224,329,1001,223,1,223,1007,226,226,224,1002,223,2,223,1006,224,344,101,1,223,223,1107,677,226,224,102,2,223,223,1006,224,359,1001,223,1,223,108,677,677,224,1002,223,2,223,1006,224,374,1001,223,1,223,107,677,677,224,1002,223,2,223,1005,224,389,101,1,223,223,8,677,677,224,1002,223,2,223,1005,224,404,1001,223,1,223,108,226,226,224,1002,223,2,223,1005,224,419,101,1,223,223,1008,677,677,224,1002,223,2,223,1005,224,434,101,1,223,223,1008,226,226,224,1002,223,2,223,1005,224,449,101,1,223,223,7,677,226,224,1002,223,2,223,1006,224,464,1001,223,1,223,7,226,226,224,1002,223,2,223,1005,224,479,1001,223,1,223,1007,677,677,224,102,2,223,223,1005,224,494,101,1,223,223,1108,677,226,224,102,2,223,223,1006,224,509,1001,223,1,223,8,677,226,224,102,2,223,223,1005,224,524,1001,223,1,223,1107,226,226,224,102,2,223,223,1006,224,539,1001,223,1,223,1008,226,677,224,1002,223,2,223,1006,224,554,1001,223,1,223,1107,226,677,224,1002,223,2,223,1006,224,569,1001,223,1,223,1108,677,677,224,102,2,223,223,1005,224,584,101,1,223,223,7,226,677,224,102,2,223,223,1006,224,599,1001,223,1,223,1108,226,677,224,102,2,223,223,1006,224,614,101,1,223,223,107,226,677,224,1002,223,2,223,1005,224,629,101,1,223,223,108,226,677,224,1002,223,2,223,1005,224,644,101,1,223,223,8,226,677,224,1002,223,2,223,1005,224,659,1001,223,1,223,107,226,226,224,1002,223,2,223,1006,224,674,101,1,223,223,4,223,99,226

29
2019/05/src/main.zig Normal file
View File

@@ -0,0 +1,29 @@
const std = @import("std");
const intcode = @import("intcode");
pub fn main() anyerror!void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const alloc = &arena.allocator;
var p1 = try intcode.loadFromStdIn(alloc);
var p2 = try alloc.alloc(intcode.Word, p1.len);
std.mem.copy(intcode.Word, p2, p1);
var m1 = try intcode.Machine.init(alloc, p1);
var m2 = try intcode.Machine.init(alloc, p2);
try m1.writeToInput(1); // Air conditioner unit
try m1.run();
var out: intcode.Word = 0;
while (out == 0) : (out = try m1.readFromOutput()) {}
std.debug.warn("Day 5, Part 1: {}\n", out);
try m2.writeToInput(5); // Thermal radiator controller
try m2.run();
std.debug.warn("Day 5, Part 2: {}\n", try m2.readFromOutput());
}

14
2019/06/build.zig Normal file
View File

@@ -0,0 +1,14 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("06", "src/main.zig");
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

1062
2019/06/input Normal file

File diff suppressed because it is too large Load Diff

138
2019/06/src/main.zig Normal file
View File

@@ -0,0 +1,138 @@
const std = @import("std");
const Link = struct {
a: [3]u8 = [3]u8{ 0, 0, 0 },
b: [3]u8 = [3]u8{ 0, 0, 0 },
};
const Node = struct {
name: [3]u8 = [3]u8{ 0, 0, 0 },
depth: u32 = 0,
parent: ?*Node,
};
const Links = std.ArrayList(Link);
const NodeList = std.ArrayList(*Node);
const Nodes = std.StringHashMap(*Node);
fn parse(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.Stream) !Links {
var list: Links = Links.init(alloc);
var buf: [8]u8 = undefined;
var i: u32 = 0;
while (try stream.readUntilDelimiterOrEof(&buf, '\n')) |line| {
std.debug.assert(line.len == 7 and line[3] == ')');
var out: Link = Link{};
std.mem.copy(u8, &out.a, line[0..3]);
std.mem.copy(u8, &out.b, line[4..7]);
try list.append(out);
}
return list;
}
fn getOrCreateNode(alloc: *std.mem.Allocator, nodes: var, name: [3]u8) !*Node {
if (nodes.get(name)) |kv| {
return kv.value;
} else {
var node: *Node = try alloc.create(Node);
node.parent = null;
node.depth = 0;
std.mem.copy(u8, &node.name, name);
var kv = try nodes.put(name, node);
return node;
}
}
fn getParents(alloc: *std.mem.Allocator, node: *Node) !NodeList {
var out = NodeList.init(alloc);
var n: *Node = node;
while (n.parent) |p| {
try out.append(p);
n = p;
}
return out;
}
// Assumes n1 is a parent of n2
fn distance(n1: *Node, n2: *Node) u32 {
return n2.depth - n1.depth - 1;
}
pub fn main() anyerror!void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const alloc = &arena.allocator;
const file = std.io.getStdIn();
const stream = &file.inStream().stream;
var links = try parse(alloc, stream);
// name -> node
var nodes = Nodes.init(alloc);
// The input isn't ordered, so we need to pass over it several times
// Pass 1: create all nodes
for (links.toSlice()) |link| {
var a = try getOrCreateNode(alloc, &nodes, link.a);
var b = try getOrCreateNode(alloc, &nodes, link.b);
}
// Pass 2: link all nodes to their parents
for (links.toSlice()) |link| {
var a = try getOrCreateNode(alloc, &nodes, link.a);
var b = try getOrCreateNode(alloc, &nodes, link.b);
std.debug.assert(b.parent == null);
b.parent = a;
}
// Pass 3: The tree is fully constructed, so we can count parents
var count: u32 = 0;
var iter = nodes.iterator();
while (iter.next()) |kv| {
var node = kv.value;
// Count number of orbits
var n: *Node = node;
while (n.parent) |p| {
node.depth += 1;
n = p;
}
count += node.depth;
}
std.debug.warn("Part 1: {}\n", count);
// We need to find the node that both you and santa have in common
var you = (nodes.get("YOU") orelse unreachable).value;
var san = (nodes.get("SAN") orelse unreachable).value;
var yP = try getParents(alloc, you);
var sP = try getParents(alloc, san);
var inCommon = NodeList.init(alloc);
for (yP.toSlice()) |p1| {
for (sP.toSlice()) |p2| {
if (p1 == p2) try inCommon.append(p1);
}
}
std.debug.warn("Part 2: you have {} parents, santa has {}, {} in common\n", yP.count(), sP.count(), inCommon.count());
for (inCommon.toSlice()) |p| {
const d1 = distance(p, you);
const d2 = distance(p, san);
std.debug.warn("\t{} - ({}) {} ({}) - {}: {}\n", you.name, d1, p.name, d2, san.name, d1 + d2);
}
}

15
2019/07/build.zig Normal file
View File

@@ -0,0 +1,15 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("07", "src/main.zig");
exe.addPackagePath("intcode", "../lib/intcode/intcode.zig");
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

1
2019/07/input Normal file
View File

@@ -0,0 +1 @@
3,8,1001,8,10,8,105,1,0,0,21,34,55,68,85,106,187,268,349,430,99999,3,9,1001,9,5,9,1002,9,5,9,4,9,99,3,9,1002,9,2,9,1001,9,2,9,1002,9,5,9,1001,9,2,9,4,9,99,3,9,101,3,9,9,102,3,9,9,4,9,99,3,9,1002,9,5,9,101,3,9,9,102,5,9,9,4,9,99,3,9,1002,9,4,9,1001,9,2,9,102,3,9,9,101,3,9,9,4,9,99,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,99

344
2019/07/src/main.zig Normal file
View File

@@ -0,0 +1,344 @@
const std = @import("std");
const intcode = @import("intcode");
// TODO: it would be awesome if we could make this a comptime function
const perm1 = [120][5]intcode.Word{
.{ 0, 1, 2, 3, 4 },
.{ 0, 1, 2, 4, 3 },
.{ 0, 1, 3, 2, 4 },
.{ 0, 1, 3, 4, 2 },
.{ 0, 1, 4, 2, 3 },
.{ 0, 1, 4, 3, 2 },
.{ 0, 2, 1, 3, 4 },
.{ 0, 2, 1, 4, 3 },
.{ 0, 2, 3, 1, 4 },
.{ 0, 2, 3, 4, 1 },
.{ 0, 2, 4, 1, 3 },
.{ 0, 2, 4, 3, 1 },
.{ 0, 3, 1, 2, 4 },
.{ 0, 3, 1, 4, 2 },
.{ 0, 3, 2, 1, 4 },
.{ 0, 3, 2, 4, 1 },
.{ 0, 3, 4, 1, 2 },
.{ 0, 3, 4, 2, 1 },
.{ 0, 4, 1, 2, 3 },
.{ 0, 4, 1, 3, 2 },
.{ 0, 4, 2, 1, 3 },
.{ 0, 4, 2, 3, 1 },
.{ 0, 4, 3, 1, 2 },
.{ 0, 4, 3, 2, 1 },
.{ 1, 0, 2, 3, 4 },
.{ 1, 0, 2, 4, 3 },
.{ 1, 0, 3, 2, 4 },
.{ 1, 0, 3, 4, 2 },
.{ 1, 0, 4, 2, 3 },
.{ 1, 0, 4, 3, 2 },
.{ 1, 2, 0, 3, 4 },
.{ 1, 2, 0, 4, 3 },
.{ 1, 2, 3, 0, 4 },
.{ 1, 2, 3, 4, 0 },
.{ 1, 2, 4, 0, 3 },
.{ 1, 2, 4, 3, 0 },
.{ 1, 3, 0, 2, 4 },
.{ 1, 3, 0, 4, 2 },
.{ 1, 3, 2, 0, 4 },
.{ 1, 3, 2, 4, 0 },
.{ 1, 3, 4, 0, 2 },
.{ 1, 3, 4, 2, 0 },
.{ 1, 4, 0, 2, 3 },
.{ 1, 4, 0, 3, 2 },
.{ 1, 4, 2, 0, 3 },
.{ 1, 4, 2, 3, 0 },
.{ 1, 4, 3, 0, 2 },
.{ 1, 4, 3, 2, 0 },
.{ 2, 0, 1, 3, 4 },
.{ 2, 0, 1, 4, 3 },
.{ 2, 0, 3, 1, 4 },
.{ 2, 0, 3, 4, 1 },
.{ 2, 0, 4, 1, 3 },
.{ 2, 0, 4, 3, 1 },
.{ 2, 1, 0, 3, 4 },
.{ 2, 1, 0, 4, 3 },
.{ 2, 1, 3, 0, 4 },
.{ 2, 1, 3, 4, 0 },
.{ 2, 1, 4, 0, 3 },
.{ 2, 1, 4, 3, 0 },
.{ 2, 3, 0, 1, 4 },
.{ 2, 3, 0, 4, 1 },
.{ 2, 3, 1, 0, 4 },
.{ 2, 3, 1, 4, 0 },
.{ 2, 3, 4, 0, 1 },
.{ 2, 3, 4, 1, 0 },
.{ 2, 4, 0, 1, 3 },
.{ 2, 4, 0, 3, 1 },
.{ 2, 4, 1, 0, 3 },
.{ 2, 4, 1, 3, 0 },
.{ 2, 4, 3, 0, 1 },
.{ 2, 4, 3, 1, 0 },
.{ 3, 0, 1, 2, 4 },
.{ 3, 0, 1, 4, 2 },
.{ 3, 0, 2, 1, 4 },
.{ 3, 0, 2, 4, 1 },
.{ 3, 0, 4, 1, 2 },
.{ 3, 0, 4, 2, 1 },
.{ 3, 1, 0, 2, 4 },
.{ 3, 1, 0, 4, 2 },
.{ 3, 1, 2, 0, 4 },
.{ 3, 1, 2, 4, 0 },
.{ 3, 1, 4, 0, 2 },
.{ 3, 1, 4, 2, 0 },
.{ 3, 2, 0, 1, 4 },
.{ 3, 2, 0, 4, 1 },
.{ 3, 2, 1, 0, 4 },
.{ 3, 2, 1, 4, 0 },
.{ 3, 2, 4, 0, 1 },
.{ 3, 2, 4, 1, 0 },
.{ 3, 4, 0, 1, 2 },
.{ 3, 4, 0, 2, 1 },
.{ 3, 4, 1, 0, 2 },
.{ 3, 4, 1, 2, 0 },
.{ 3, 4, 2, 0, 1 },
.{ 3, 4, 2, 1, 0 },
.{ 4, 0, 1, 2, 3 },
.{ 4, 0, 1, 3, 2 },
.{ 4, 0, 2, 1, 3 },
.{ 4, 0, 2, 3, 1 },
.{ 4, 0, 3, 1, 2 },
.{ 4, 0, 3, 2, 1 },
.{ 4, 1, 0, 2, 3 },
.{ 4, 1, 0, 3, 2 },
.{ 4, 1, 2, 0, 3 },
.{ 4, 1, 2, 3, 0 },
.{ 4, 1, 3, 0, 2 },
.{ 4, 1, 3, 2, 0 },
.{ 4, 2, 0, 1, 3 },
.{ 4, 2, 0, 3, 1 },
.{ 4, 2, 1, 0, 3 },
.{ 4, 2, 1, 3, 0 },
.{ 4, 2, 3, 0, 1 },
.{ 4, 2, 3, 1, 0 },
.{ 4, 3, 0, 1, 2 },
.{ 4, 3, 0, 2, 1 },
.{ 4, 3, 1, 0, 2 },
.{ 4, 3, 1, 2, 0 },
.{ 4, 3, 2, 0, 1 },
.{ 4, 3, 2, 1, 0 },
};
const perm2 = [120][5]intcode.Word{
.{ 5, 6, 7, 8, 9 },
.{ 5, 6, 7, 9, 8 },
.{ 5, 6, 8, 7, 9 },
.{ 5, 6, 8, 9, 7 },
.{ 5, 6, 9, 7, 8 },
.{ 5, 6, 9, 8, 7 },
.{ 5, 7, 6, 8, 9 },
.{ 5, 7, 6, 9, 8 },
.{ 5, 7, 8, 6, 9 },
.{ 5, 7, 8, 9, 6 },
.{ 5, 7, 9, 6, 8 },
.{ 5, 7, 9, 8, 6 },
.{ 5, 8, 6, 7, 9 },
.{ 5, 8, 6, 9, 7 },
.{ 5, 8, 7, 6, 9 },
.{ 5, 8, 7, 9, 6 },
.{ 5, 8, 9, 6, 7 },
.{ 5, 8, 9, 7, 6 },
.{ 5, 9, 6, 7, 8 },
.{ 5, 9, 6, 8, 7 },
.{ 5, 9, 7, 6, 8 },
.{ 5, 9, 7, 8, 6 },
.{ 5, 9, 8, 6, 7 },
.{ 5, 9, 8, 7, 6 },
.{ 6, 5, 7, 8, 9 },
.{ 6, 5, 7, 9, 8 },
.{ 6, 5, 8, 7, 9 },
.{ 6, 5, 8, 9, 7 },
.{ 6, 5, 9, 7, 8 },
.{ 6, 5, 9, 8, 7 },
.{ 6, 7, 5, 8, 9 },
.{ 6, 7, 5, 9, 8 },
.{ 6, 7, 8, 5, 9 },
.{ 6, 7, 8, 9, 5 },
.{ 6, 7, 9, 5, 8 },
.{ 6, 7, 9, 8, 5 },
.{ 6, 8, 5, 7, 9 },
.{ 6, 8, 5, 9, 7 },
.{ 6, 8, 7, 5, 9 },
.{ 6, 8, 7, 9, 5 },
.{ 6, 8, 9, 5, 7 },
.{ 6, 8, 9, 7, 5 },
.{ 6, 9, 5, 7, 8 },
.{ 6, 9, 5, 8, 7 },
.{ 6, 9, 7, 5, 8 },
.{ 6, 9, 7, 8, 5 },
.{ 6, 9, 8, 5, 7 },
.{ 6, 9, 8, 7, 5 },
.{ 7, 5, 6, 8, 9 },
.{ 7, 5, 6, 9, 8 },
.{ 7, 5, 8, 6, 9 },
.{ 7, 5, 8, 9, 6 },
.{ 7, 5, 9, 6, 8 },
.{ 7, 5, 9, 8, 6 },
.{ 7, 6, 5, 8, 9 },
.{ 7, 6, 5, 9, 8 },
.{ 7, 6, 8, 5, 9 },
.{ 7, 6, 8, 9, 5 },
.{ 7, 6, 9, 5, 8 },
.{ 7, 6, 9, 8, 5 },
.{ 7, 8, 5, 6, 9 },
.{ 7, 8, 5, 9, 6 },
.{ 7, 8, 6, 5, 9 },
.{ 7, 8, 6, 9, 5 },
.{ 7, 8, 9, 5, 6 },
.{ 7, 8, 9, 6, 5 },
.{ 7, 9, 5, 6, 8 },
.{ 7, 9, 5, 8, 6 },
.{ 7, 9, 6, 5, 8 },
.{ 7, 9, 6, 8, 5 },
.{ 7, 9, 8, 5, 6 },
.{ 7, 9, 8, 6, 5 },
.{ 8, 5, 6, 7, 9 },
.{ 8, 5, 6, 9, 7 },
.{ 8, 5, 7, 6, 9 },
.{ 8, 5, 7, 9, 6 },
.{ 8, 5, 9, 6, 7 },
.{ 8, 5, 9, 7, 6 },
.{ 8, 6, 5, 7, 9 },
.{ 8, 6, 5, 9, 7 },
.{ 8, 6, 7, 5, 9 },
.{ 8, 6, 7, 9, 5 },
.{ 8, 6, 9, 5, 7 },
.{ 8, 6, 9, 7, 5 },
.{ 8, 7, 5, 6, 9 },
.{ 8, 7, 5, 9, 6 },
.{ 8, 7, 6, 5, 9 },
.{ 8, 7, 6, 9, 5 },
.{ 8, 7, 9, 5, 6 },
.{ 8, 7, 9, 6, 5 },
.{ 8, 9, 5, 6, 7 },
.{ 8, 9, 5, 7, 6 },
.{ 8, 9, 6, 5, 7 },
.{ 8, 9, 6, 7, 5 },
.{ 8, 9, 7, 5, 6 },
.{ 8, 9, 7, 6, 5 },
.{ 9, 5, 6, 7, 8 },
.{ 9, 5, 6, 8, 7 },
.{ 9, 5, 7, 6, 8 },
.{ 9, 5, 7, 8, 6 },
.{ 9, 5, 8, 6, 7 },
.{ 9, 5, 8, 7, 6 },
.{ 9, 6, 5, 7, 8 },
.{ 9, 6, 5, 8, 7 },
.{ 9, 6, 7, 5, 8 },
.{ 9, 6, 7, 8, 5 },
.{ 9, 6, 8, 5, 7 },
.{ 9, 6, 8, 7, 5 },
.{ 9, 7, 5, 6, 8 },
.{ 9, 7, 5, 8, 6 },
.{ 9, 7, 6, 5, 8 },
.{ 9, 7, 6, 8, 5 },
.{ 9, 7, 8, 5, 6 },
.{ 9, 7, 8, 6, 5 },
.{ 9, 8, 5, 6, 7 },
.{ 9, 8, 5, 7, 6 },
.{ 9, 8, 6, 5, 7 },
.{ 9, 8, 6, 7, 5 },
.{ 9, 8, 7, 5, 6 },
.{ 9, 8, 7, 6, 5 },
};
fn doIt(m: *intcode.Machine) void {
if (m.run()) {} else |err| {
std.debug.warn("Machine {} failed to run successfully: {}\n", m.idx, err);
}
}
fn run(program: []intcode.Word, machines: *[5]intcode.Machine, permutations: [120][5]intcode.Word) !intcode.Word {
var max: intcode.Word = 0;
for (permutations) |inputs| {
// Reset program state each time
for (machines) |*machine, i| {
std.mem.copy(intcode.Word, machine.memory, program);
machine.ip = 0;
machine.idx = i;
}
// Phase inputs
for (inputs) |input, i| {
try machines[i].writeToInput(input);
}
// Provide starting value of 0
try machines[0].writeToInput(0);
// run the machines asychronously
var f0 = try std.Thread.spawn(&machines[0], doIt);
var f1 = try std.Thread.spawn(&machines[1], doIt);
var f2 = try std.Thread.spawn(&machines[2], doIt);
var f3 = try std.Thread.spawn(&machines[3], doIt);
var f4 = try std.Thread.spawn(&machines[4], doIt);
f0.wait();
f1.wait();
f2.wait();
f3.wait();
f4.wait();
const final = try machines[4].readFromOutput();
if (final > max)
max = final;
}
return max;
}
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);
// 5 intcode computers act as the amps
var machines: [5]intcode.Machine = undefined;
// Allocate memory once only.
for (machines) |*machine| {
machine.alloc = alloc;
machine.memory = try alloc.alloc(intcode.Word, program.len);
}
// Now wire up the machines correctly. The output of each machine should be
// the input to the next.
const pipes: [6]intcode.CharDev = .{
try std.os.pipe(), try std.os.pipe(),
try std.os.pipe(), try std.os.pipe(),
try std.os.pipe(), try std.os.pipe(),
};
machines[0].input = pipes[0];
machines[0].output = pipes[1];
machines[1].input = machines[0].output;
machines[1].output = pipes[2];
machines[2].input = machines[1].output;
machines[2].output = pipes[3];
machines[3].input = machines[2].output;
machines[3].output = pipes[4];
machines[4].input = machines[3].output;
machines[4].output = pipes[5];
std.debug.warn("Day 7, Part 1: {}\n", try run(program, &machines, perm1));
// In part 2, the machines need to be wired into a feedback loop.
// To do this, drop pipe 6 and replace it with pipe 0
machines[0].input = machines[4].output;
std.debug.warn("Day 7, Part 2: {}\n", try run(program, &machines, perm2));
}

14
2019/08/build.zig Normal file
View File

@@ -0,0 +1,14 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("08", "src/main.zig");
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

1
2019/08/input Normal file

File diff suppressed because one or more lines are too long

104
2019/08/src/main.zig Normal file
View File

@@ -0,0 +1,104 @@
const std = @import("std");
const depth = 100;
const width = 25;
const height = 6;
const Layer = [height][width]Colour;
const Image = [depth]Layer;
const Colour = enum(u8) {
Black = 0,
White = 1,
Trans = 2,
};
fn printLayer(l: Layer) void {
for (l) |row| {
for (row) |byte| {
switch (byte) {
.Black => {
std.debug.warn(" ");
},
.White => {
std.debug.warn("*");
},
else => {
std.debug.warn(" ");
},
}
}
std.debug.warn("\n");
}
std.debug.warn("\n");
}
fn printImage(image: Image) void {
var meta: Layer = undefined;
for (meta) |row, y| {
for (row) |_, x| {
meta[y][x] = .Trans;
}
}
for (meta) |*row, y| {
for (row) |*b, x| {
var z: usize = 0;
while (b.* == .Trans) : (z += 1) {
if (image[z][y][x] != .Trans) {
b.* = image[z][y][x];
}
}
}
}
printLayer(meta);
}
pub fn main() anyerror!void {
var img: Image = undefined;
var zeroCounts = [_]usize{0} ** depth;
const file = std.io.getStdIn();
const stream = &file.inStream().stream;
for (img) |*layer, z| {
for (layer) |*row| {
for (row) |*pixel| {
var b = try stream.readByte();
if (b == '0') zeroCounts[z] += 1;
pixel.* = @intToEnum(Colour, b - '0');
}
}
}
// Now count how many zeroes are in each layer, picking out the smallest
var minCount: usize = width * height;
var minZ: usize = 0;
for (zeroCounts) |count, i| {
if (count < minCount) {
minCount = count;
minZ = i;
}
}
var num1s: usize = 0;
var num2s: usize = 0;
for (img[minZ]) |row| {
for (row) |b| {
switch (b) {
.White => {
num1s += 1;
},
.Trans => {
num2s += 1;
},
else => {},
}
}
}
std.debug.warn("Day 8, Part 1: {} with {} zeroes, {} 1s, {} 2s. Result: {}\n\n", minZ, minCount, num1s, num2s, num1s * num2s);
printImage(img);
}

15
2019/09/build.zig Normal file
View File

@@ -0,0 +1,15 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("09", "src/main.zig");
exe.setBuildMode(mode);
exe.addPackagePath("intcode", "../lib/intcode/intcode.zig");
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

1
2019/09/input Normal file
View File

@@ -0,0 +1 @@
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1101,3,0,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1101,34,0,1013,1101,20,0,1012,1101,536,0,1023,1101,0,23,1006,1102,1,543,1022,1102,1,27,1003,1102,25,1,1014,1102,1,29,1009,1101,0,686,1025,1101,0,30,1004,1102,1,28,1017,1102,1,35,1016,1101,765,0,1028,1102,1,33,1002,1102,1,26,1000,1102,1,822,1027,1102,1,21,1001,1102,1,1,1021,1101,31,0,1007,1101,0,39,1010,1102,36,1,1019,1101,0,32,1015,1101,0,38,1018,1101,0,24,1005,1101,22,0,1011,1101,756,0,1029,1102,1,0,1020,1102,829,1,1026,1102,1,37,1008,1101,0,695,1024,109,19,1205,2,195,4,187,1105,1,199,1001,64,1,64,1002,64,2,64,109,7,1205,-6,215,1001,64,1,64,1105,1,217,4,205,1002,64,2,64,109,-16,21108,40,42,5,1005,1015,233,1106,0,239,4,223,1001,64,1,64,1002,64,2,64,109,-13,2102,1,5,63,1008,63,33,63,1005,63,261,4,245,1105,1,265,1001,64,1,64,1002,64,2,64,109,29,21101,41,0,-9,1008,1017,41,63,1005,63,291,4,271,1001,64,1,64,1105,1,291,1002,64,2,64,109,-22,2107,27,-4,63,1005,63,307,1105,1,313,4,297,1001,64,1,64,1002,64,2,64,109,7,1207,-4,30,63,1005,63,333,1001,64,1,64,1106,0,335,4,319,1002,64,2,64,109,1,21108,42,42,6,1005,1018,353,4,341,1105,1,357,1001,64,1,64,1002,64,2,64,109,14,21101,43,0,-7,1008,1019,41,63,1005,63,377,1106,0,383,4,363,1001,64,1,64,1002,64,2,64,109,-8,21102,44,1,-1,1008,1017,47,63,1005,63,407,1001,64,1,64,1105,1,409,4,389,1002,64,2,64,109,-15,2101,0,2,63,1008,63,25,63,1005,63,433,1001,64,1,64,1105,1,435,4,415,1002,64,2,64,109,7,1201,-8,0,63,1008,63,30,63,1005,63,455,1105,1,461,4,441,1001,64,1,64,1002,64,2,64,109,-12,2108,37,10,63,1005,63,483,4,467,1001,64,1,64,1106,0,483,1002,64,2,64,109,13,21107,45,44,0,1005,1011,499,1105,1,505,4,489,1001,64,1,64,1002,64,2,64,109,-2,2107,20,-8,63,1005,63,523,4,511,1106,0,527,1001,64,1,64,1002,64,2,64,109,20,2105,1,-6,1001,64,1,64,1105,1,545,4,533,1002,64,2,64,109,-28,2102,1,1,63,1008,63,30,63,1005,63,565,1105,1,571,4,551,1001,64,1,64,1002,64,2,64,109,20,1206,0,583,1105,1,589,4,577,1001,64,1,64,1002,64,2,64,109,-7,1206,6,603,4,595,1106,0,607,1001,64,1,64,1002,64,2,64,109,-14,2101,0,2,63,1008,63,33,63,1005,63,629,4,613,1105,1,633,1001,64,1,64,1002,64,2,64,109,-4,1208,8,30,63,1005,63,655,4,639,1001,64,1,64,1105,1,655,1002,64,2,64,109,23,21107,46,47,0,1005,1019,673,4,661,1105,1,677,1001,64,1,64,1002,64,2,64,109,-2,2105,1,7,4,683,1001,64,1,64,1106,0,695,1002,64,2,64,109,3,21102,47,1,-7,1008,1013,47,63,1005,63,717,4,701,1105,1,721,1001,64,1,64,1002,64,2,64,109,-11,1202,-7,1,63,1008,63,32,63,1005,63,745,1001,64,1,64,1105,1,747,4,727,1002,64,2,64,109,10,2106,0,9,4,753,1001,64,1,64,1105,1,765,1002,64,2,64,109,-24,1207,8,28,63,1005,63,783,4,771,1106,0,787,1001,64,1,64,1002,64,2,64,109,5,1201,0,0,63,1008,63,26,63,1005,63,813,4,793,1001,64,1,64,1105,1,813,1002,64,2,64,109,28,2106,0,-1,1001,64,1,64,1105,1,831,4,819,1002,64,2,64,109,-22,1202,-1,1,63,1008,63,24,63,1005,63,857,4,837,1001,64,1,64,1106,0,857,1002,64,2,64,109,-9,2108,30,6,63,1005,63,873,1106,0,879,4,863,1001,64,1,64,1002,64,2,64,109,-2,1208,10,26,63,1005,63,899,1001,64,1,64,1106,0,901,4,885,4,64,99,21102,1,27,1,21101,0,915,0,1105,1,922,21201,1,25948,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,942,0,0,1106,0,922,22101,0,1,-1,21201,-2,-3,1,21102,957,1,0,1105,1,922,22201,1,-1,-2,1106,0,968,21201,-2,0,-2,109,-3,2106,0,0

22
2019/09/src/main.zig Normal file
View File

@@ -0,0 +1,22 @@
const std = @import("std");
const intcode = @import("intcode");
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);
var machine = try intcode.Machine.init(alloc, program);
try machine.writeToInput(1); // BOOST program in test mode
try machine.run();
std.debug.warn("Day 9, Part 1: {}\n", try machine.readFromOutput());
try machine.writeToInput(2); // BOOST program in sensor boost mode
try machine.run();
std.debug.warn("Day 9, Part 2: {}\n", try machine.readFromOutput());
}

14
2019/10/build.zig Normal file
View File

@@ -0,0 +1,14 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("10", "src/main.zig");
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

25
2019/10/input Normal file
View File

@@ -0,0 +1,25 @@
#..#.#.#.######..#.#...##
##.#..#.#..##.#..######.#
.#.##.#..##..#.#.####.#..
.#..##.#.#..#.#...#...#.#
#...###.##.##..##...#..#.
##..#.#.#.###...#.##..#.#
###.###.#.##.##....#####.
.#####.#.#...#..#####..#.
.#.##...#.#...#####.##...
######.#..##.#..#.#.#....
###.##.#######....##.#..#
.####.##..#.##.#.#.##...#
##...##.######..##..#.###
...###...#..#...#.###..#.
.#####...##..#..#####.###
.#####..#.#######.###.##.
#...###.####.##.##.#.##.#
.#.#.#.#.#.##.#..#.#..###
##.#.####.###....###..##.
#..##.#....#..#..#.#..#.#
##..#..#...#..##..####..#
....#.....##..#.##.#...##
.##..#.#..##..##.#..##..#
.##..#####....#####.#.#.#
#..#..#..##...#..#.#.#.##

89
2019/10/src/main.zig Normal file
View File

@@ -0,0 +1,89 @@
const std = @import("std");
// https://stackoverflow.com/a/328122
fn isBetween(a: Point, b: Point, c: Point) bool {
const crossproduct = (c.y - a.y) * (b.x - a.x) - (c.x - a.x) * (b.y - a.y);
// compare versus epsilon
if (std.math.absFloat(crossproduct) > std.math.f64_epsilon) return false;
const dotproduct = (c.x - a.x) * (b.x - a.x) + (c.y - a.y) * (b.y - a.y);
if (dotproduct < 0.0) return false;
const squaredlengthba = (b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y);
if (dotproduct > squaredlengthba) return false;
return true;
}
const Point = struct {
x: f64,
y: f64,
fn eql(self: Point, other: Point) bool {
return self.x == other.x and self.y == other.y;
}
};
const Asteroid = struct {
p: Point,
visible: usize = 0,
};
const Asteroids = std.ArrayList(Asteroid);
const input = @embedFile("../input");
fn part1(asteroids: Asteroids) void {
for (asteroids.toSlice()) |*a| {
for (asteroids.toSlice()) |b| {
if (a.p.eql(b.p)) continue;
// Check every asteroid to see if they fall between A and B
var blocked: bool = false;
for (asteroids.toSlice()) |c| {
if (a.p.eql(c.p) or b.p.eql(c.p)) continue;
//var dist = distToSegment(a.p, b.p, c.p);
if (isBetween(a.p, b.p, c.p)) {
blocked = true;
break;
}
}
// A can see B, so add it to A's score
if (!blocked) a.visible += 1;
}
}
var best: usize = 0;
for (asteroids.toSlice()) |asteroid| {
if (asteroid.visible > best) best = asteroid.visible;
}
std.debug.warn("Day 10, Part 1: {}\n", best);
}
pub fn main() anyerror!void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const alloc = &arena.allocator;
var asteroids = Asteroids.init(alloc);
var lines = std.mem.separate(input, "\n");
var y: usize = 0;
while (lines.next()) |line| {
for (line) |byte, x| {
if (byte == '#') {
const px = @intToFloat(f64, x) + 0.5;
const py = @intToFloat(f64, y) + 0.5;
try asteroids.append(Asteroid{ .p = Point{ .x = px, .y = py } });
}
}
y += 1;
}
part1(asteroids);
}

16
2019/11/build.zig Normal file
View File

@@ -0,0 +1,16 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("11", "src/main.zig");
exe.setBuildMode(mode);
exe.addPackagePath("intcode", "../lib/intcode/intcode.zig");
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

1
2019/11/input Normal file
View File

@@ -0,0 +1 @@
3,8,1005,8,304,1106,0,11,0,0,0,104,1,104,0,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,1,10,4,10,1002,8,1,29,2,103,1,10,1,106,18,10,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,102,1,8,59,2,102,3,10,2,1101,12,10,3,8,102,-1,8,10,1001,10,1,10,4,10,108,0,8,10,4,10,101,0,8,88,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,101,0,8,110,2,108,9,10,1006,0,56,3,8,102,-1,8,10,1001,10,1,10,4,10,108,0,8,10,4,10,101,0,8,139,1,108,20,10,3,8,102,-1,8,10,101,1,10,10,4,10,108,0,8,10,4,10,102,1,8,165,1,104,9,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,1001,8,0,192,2,9,14,10,2,1103,5,10,1,1108,5,10,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,1,10,4,10,102,1,8,226,1006,0,73,1006,0,20,1,1106,11,10,1,1105,7,10,3,8,102,-1,8,10,1001,10,1,10,4,10,108,0,8,10,4,10,1001,8,0,261,3,8,102,-1,8,10,101,1,10,10,4,10,108,1,8,10,4,10,1002,8,1,283,101,1,9,9,1007,9,1052,10,1005,10,15,99,109,626,104,0,104,1,21101,48062899092,0,1,21101,0,321,0,1105,1,425,21101,936995300108,0,1,21101,0,332,0,1106,0,425,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21102,209382902951,1,1,21101,379,0,0,1106,0,425,21102,179544747200,1,1,21102,390,1,0,1106,0,425,3,10,104,0,104,0,3,10,104,0,104,0,21102,1,709488292628,1,21102,1,413,0,1106,0,425,21101,0,983929868648,1,21101,424,0,0,1105,1,425,99,109,2,22101,0,-1,1,21102,40,1,2,21102,456,1,3,21101,446,0,0,1106,0,489,109,-2,2106,0,0,0,1,0,0,1,109,2,3,10,204,-1,1001,451,452,467,4,0,1001,451,1,451,108,4,451,10,1006,10,483,1102,0,1,451,109,-2,2105,1,0,0,109,4,1201,-1,0,488,1207,-3,0,10,1006,10,506,21102,1,0,-3,21202,-3,1,1,21201,-2,0,2,21101,0,1,3,21101,525,0,0,1105,1,530,109,-4,2105,1,0,109,5,1207,-3,1,10,1006,10,553,2207,-4,-2,10,1006,10,553,21202,-4,1,-4,1105,1,621,21201,-4,0,1,21201,-3,-1,2,21202,-2,2,3,21102,1,572,0,1106,0,530,21201,1,0,-4,21101,0,1,-1,2207,-4,-2,10,1006,10,591,21102,0,1,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,613,22101,0,-1,1,21101,0,613,0,106,0,488,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2106,0,0

146
2019/11/src/main.zig Normal file
View 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);
}

5
2019/README.md Normal file
View File

@@ -0,0 +1,5 @@
# [Advent Of Code 2019](https://adventofcode.com/2019)
[lupine](https://ur.gs/)'s repository
This year, I'll be working in [Zig](https://ziglang.org)

View File

@@ -0,0 +1,437 @@
const std = @import("std");
// We're using pipes as character devices
pub const CharDev = [2]i32;
pub const Word = i64;
pub const MemSize = 1024 * 2;
pub fn loadFromStream(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.Stream) anyerror![]Word {
var program = try alloc.alloc(Word, 1024);
var buf = [_]u8{0} ** 255;
var i: u32 = 0;
while (try stream.readUntilDelimiterOrEof(&buf, ',')) |num| {
var trimmed = std.mem.trimRight(u8, num, "\r\n");
program[i] = try std.fmt.parseInt(Word, trimmed, 10);
i += 1;
}
std.debug.warn("\n");
return program[0..program.len];
}
pub fn loadFromStdIn(alloc: *std.mem.Allocator) anyerror![]Word {
const file = std.io.getStdIn();
const stream = &file.inStream().stream;
return loadFromStream(alloc, stream);
}
const Opcode = enum(u8) {
ADD = 1,
MULT = 2,
IN = 3,
OUT = 4,
JNZ = 5,
JZ = 6,
LT = 7,
EQ = 8,
RBO = 9,
END = 99,
};
const Mode = enum(u8) {
Position = 0,
Immediate = 1,
Relative = 2,
};
const Instruction = struct {
op: Opcode,
// Modes for each parameter of the opcode. Parameter 0 is in position 0, etc
modes: [3]Mode,
pub fn decode(value: Word) !Instruction {
assert(value > 0 and value < 99999);
var buf: [6]u8 = undefined;
const str = try std.fmt.bufPrint(&buf, "{d:0<6}", value);
const op = ((str[4] - '0') * 10) + (str[5] - '0');
return Instruction{
.op = @intToEnum(Opcode, op),
.modes = [3]Mode{
@intToEnum(Mode, buf[3] - '0'),
@intToEnum(Mode, buf[2] - '0'),
@intToEnum(Mode, buf[1] - '0'),
},
};
}
/// Number of bytes taken up by a particular instruction
pub fn size(self: Instruction) usize {
return switch (self.op) {
.ADD => 4,
.MULT => 4,
.IN => 2,
.OUT => 2,
.JNZ => 3,
.JZ => 3,
.LT => 4,
.EQ => 4,
.RBO => 2,
.END => 1,
};
}
pub fn halt(self: Instruction) bool {
return self.op == .END;
}
};
pub const Machine = struct {
alloc: *std.mem.Allocator,
idx: usize = 0, // handy for debugging
memory: []Word,
rb: Word = 0,
ip: usize = 0,
halted: bool = false,
input: CharDev,
output: CharDev,
pub fn Run(alloc: *std.mem.Allocator, program: []Word) anyerror!Machine {
var machine = try init(alloc, program);
try machine.run();
return machine;
}
pub fn init(alloc: *std.mem.Allocator, program: []Word) anyerror!Machine {
var memory = try alloc.alloc(Word, MemSize);
std.mem.set(Word, memory, 0);
std.mem.copy(Word, memory, program);
return Machine{
.alloc = alloc,
.memory = memory,
.input = try std.os.pipe(),
.output = try std.os.pipe(),
};
}
pub fn run(self: *Machine) anyerror!void {
while (try self.step()) {}
}
pub fn deinit(self: *Machine) void {
self.alloc.free(self.memory);
std.os.close(self.input[0]);
std.os.close(self.input[1]);
std.os.close(self.output[0]);
std.os.close(self.output[1]);
}
pub fn readFromInput(self: *Machine) !Word {
return self.__in(self.input);
}
pub fn writeToInput(self: *Machine, val: Word) !void {
return self.__out(self.input, val);
}
pub fn readFromOutput(self: *Machine) !Word {
return self.__in(self.output);
}
pub fn writeToOutput(self: *Machine, val: Word) !void {
return self.__out(self.output, val);
}
fn __in(self: *Machine, dev: CharDev) !Word {
const fd = dev[0]; // Read from the pipe
var store: [8]u8 = undefined;
// std.debug.warn("{}: __in({} <- {})\n", self.idx, dev[0], dev[1]);
var n = try std.os.read(fd, &store);
std.debug.assert(n == 8); // TODO: handle partial reads
return std.mem.readIntNative(Word, &store);
}
fn __out(self: *Machine, dev: CharDev, val: Word) !void {
const fd = dev[1]; // Write to the pipe
const bytes = std.mem.asBytes(&val);
// std.debug.warn("{}: __out({} -> {}, {})\n", self.idx, dev[1], dev[0], val);
try std.os.write(fd, bytes);
}
/// Read an immediate or position value from memory. Parameter determines
/// which field following the current instruction to read from
inline fn __read(self: *Machine, parameter: usize, mode: Mode) Word {
const immediate = self.memory[self.ip + parameter + 1];
return switch (mode) {
.Immediate => immediate,
.Position => self.memory[@intCast(usize, immediate)],
.Relative => self.memory[@intCast(usize, immediate + self.rb)],
};
}
inline fn __write(self: *Machine, parameter: usize, mode: Mode, value: Word) void {
const dest = self.__read(parameter, .Immediate);
switch (mode) {
.Immediate => unreachable,
.Position => self.memory[@intCast(usize, dest)] = value,
.Relative => self.memory[@intCast(usize, dest + self.rb)] = value,
}
}
pub fn step(self: *Machine) anyerror!bool {
const insn = try Instruction.decode(self.memory[self.ip]);
const start_ip = self.ip;
const opcode = switch (insn.op) {
.ADD => {
const a = self.__read(0, insn.modes[0]);
const b = self.__read(1, insn.modes[1]);
self.__write(2, insn.modes[2], a + b);
},
.MULT => {
const a = self.__read(0, insn.modes[0]);
const b = self.__read(1, insn.modes[1]);
self.__write(2, insn.modes[2], a * b);
},
.IN => {
self.__write(0, insn.modes[0], try self.readFromInput()); // blocking read
},
.OUT => {
try self.writeToOutput(self.__read(0, insn.modes[0]));
},
.JNZ => {
if (self.__read(0, insn.modes[0]) != 0)
self.ip = @intCast(usize, self.__read(1, insn.modes[1]));
},
.JZ => {
if (self.__read(0, insn.modes[0]) == 0)
self.ip = @intCast(usize, self.__read(1, insn.modes[1]));
},
.LT => {
const a = self.__read(0, insn.modes[0]);
const b = self.__read(1, insn.modes[1]);
if (a < b) {
self.__write(2, insn.modes[2], 1);
} else {
self.__write(2, insn.modes[2], 0);
}
},
.EQ => {
const a = self.__read(0, insn.modes[0]);
const b = self.__read(1, insn.modes[1]);
if (a == b) {
self.__write(2, insn.modes[2], 1);
} else {
self.__write(2, insn.modes[2], 0);
}
},
.RBO => {
self.rb += self.__read(0, insn.modes[0]);
},
.END => self.halted = true,
};
// Only modify IP if the instruction itself has not
if (self.ip == start_ip) self.ip += insn.size();
return !insn.halt();
}
};
const assert = std.debug.assert;
const test_allocator = std.heap.page_allocator;
test "day 2 example 1" {
var before: [12]Word = .{ 1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50 };
var after: [12]Word = .{ 3500, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50 };
var machine = try Machine.Run(test_allocator, before[0..before.len]);
defer machine.deinit();
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
}
test "day 2 example 2" {
var before: [5]Word = .{ 1, 0, 0, 0, 99 };
var after: [5]Word = .{ 2, 0, 0, 0, 99 };
var machine = try Machine.Run(test_allocator, before[0..before.len]);
defer machine.deinit();
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
}
test "day 2 example 3" {
var before: [5]Word = .{ 2, 3, 0, 3, 99 };
var after: [5]Word = .{ 2, 3, 0, 6, 99 };
var machine = try Machine.Run(test_allocator, before[0..before.len]);
defer machine.deinit();
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
}
test "day 2 example 4" {
var before: [6]Word = .{ 2, 4, 4, 5, 99, 0 };
var after: [6]Word = .{ 2, 4, 4, 5, 99, 9801 };
var machine = try Machine.Run(test_allocator, before[0..before.len]);
defer machine.deinit();
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
}
test "day 2 example 5" {
var before: [9]Word = .{ 1, 1, 1, 4, 99, 5, 6, 0, 99 };
var after: [9]Word = .{ 30, 1, 1, 4, 2, 5, 6, 0, 99 };
var machine = try Machine.Run(test_allocator, before[0..before.len]);
defer machine.deinit();
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
}
test "day 5 example 1" {
var before: [5]Word = .{ 3, 0, 4, 0, 99 };
var after: [5]Word = .{ 666, 0, 4, 0, 99 };
var machine = try Machine.init(test_allocator, before[0..before.len]);
defer machine.deinit();
try machine.writeToInput(666);
try machine.run();
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
assert(666 == try machine.readFromOutput());
}
test "day 9 example 1" {
var before: [16]Word = .{ 109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99 };
var after: [16]Word = before;
var output: [16]Word = undefined;
var machine = try Machine.init(test_allocator, before[0..before.len]);
defer machine.deinit();
try machine.run();
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
for (output) |*b| {
b.* = try machine.readFromOutput();
}
// This program produces a copy of itself as output
assert(std.mem.eql(Word, machine.memory[0..before.len], output[0..after.len]));
}
test "day 9 example 2" {
var before: [8]Word = .{ 1102, 34915192, 34915192, 7, 4, 7, 99, 0 };
var after: [8]Word = .{ 1102, 34915192, 34915192, 7, 4, 7, 99, 1219070632396864 };
var machine = try Machine.init(test_allocator, before[0..before.len]);
defer machine.deinit();
try machine.run();
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
std.debug.assert(1219070632396864 == try machine.readFromOutput());
}
test "day 9 example 3" {
var before: [3]Word = .{ 104, 1125899906842624, 99 };
var after: [3]Word = before;
var machine = try Machine.init(test_allocator, before[0..before.len]);
defer machine.deinit();
try machine.run();
assert(std.mem.eql(Word, machine.memory[0..before.len], after[0..after.len]));
std.debug.assert(1125899906842624 == try machine.readFromOutput());
}
test "Instruction#decode ADD" {
const insn = try Instruction.decode(1);
assert(insn.op == Opcode.ADD);
assert(insn.modes[0] == .Position);
assert(insn.modes[1] == .Position);
assert(insn.modes[2] == .Position);
}
test "Instruction#decode MULT" {
const insn = try Instruction.decode(2);
assert(insn.op == Opcode.MULT);
assert(insn.modes[0] == .Position);
assert(insn.modes[1] == .Position);
assert(insn.modes[2] == .Position);
}
test "Instruction#decode IN" {
const insn = try Instruction.decode(3);
assert(insn.op == Opcode.IN);
assert(insn.modes[0] == .Position);
assert(insn.modes[1] == .Position);
assert(insn.modes[2] == .Position);
}
test "Instruction#decode OUT" {
const insn = try Instruction.decode(4);
assert(insn.op == Opcode.OUT);
assert(insn.modes[0] == .Position);
assert(insn.modes[1] == .Position);
assert(insn.modes[2] == .Position);
}
test "Instruction#decode END Position" {
const insn = try Instruction.decode(99);
assert(insn.op == Opcode.END);
assert(insn.modes[0] == .Position);
assert(insn.modes[1] == .Position);
assert(insn.modes[2] == .Position);
}
test "Instruction#decode END Immediate" {
const insn = try Instruction.decode(11199);
assert(insn.op == Opcode.END);
assert(insn.modes[0] == .Immediate);
assert(insn.modes[1] == .Immediate);
assert(insn.modes[2] == .Immediate);
}
test "Instruction#decode END mixed" {
const insn = try Instruction.decode(10099);
assert(insn.op == Opcode.END);
assert(insn.modes[0] == .Position);
assert(insn.modes[1] == .Position);
assert(insn.modes[2] == .Immediate);
}

6
2019/run-intcodes Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
zig test lib/intcode/intcode.zig &&
zig build --build-file 02/build.zig run < 02/input &&
zig build --build-file 05/build.zig run < 05/input &&
zig build --build-file 07/build.zig run < 07/input &&
zig build --build-file 09/build.zig run < 09/input