summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--day_10.zig73
-rw-r--r--day_11.zig160
-rw-r--r--inputs/day_10140
-rw-r--r--inputs/day_1155
-rw-r--r--main.zig2
-rw-r--r--util/aoc.zig2
6 files changed, 431 insertions, 1 deletions
diff --git a/day_10.zig b/day_10.zig
new file mode 100644
index 0000000..b8cacc7
--- /dev/null
+++ b/day_10.zig
@@ -0,0 +1,73 @@
+const std = @import("std");
+const Result = @import("util/aoc.zig").Result;
+
+pub fn puzzle_1(input: []const u8) Result {
+ var cycle: u16 = 1;
+ var register: i16 = 1;
+ var sum: u16 = 0;
+
+ var iter = std.mem.split(u8, input, "\n");
+ while (iter.next()) |line| {
+ if (cycle % 40 == 20) sum += cycle * @intCast(u16, register);
+ cycle += 1;
+
+ if (line[0] != 'a') continue;
+
+ const n = std.fmt.parseInt(i16, line[5..], 0) catch unreachable;
+
+ if (cycle % 40 == 20) sum += cycle * @intCast(u16, register);
+ cycle += 1;
+
+ register += n;
+ }
+
+ return .{ .int = sum };
+}
+
+fn crt(cycle: u16, register: i16, screen: *[6][40]bool) void {
+ const pixel_id = (cycle - 1) % 240;
+ const pixel_row = pixel_id / 40;
+ const pixel_col = pixel_id % 40;
+
+ if (pixel_col == register or pixel_col == (register - 1) or pixel_col == (register + 1)) {
+ screen.*[pixel_row][pixel_col] = true;
+ } else {
+ screen.*[pixel_row][pixel_col] = false;
+ }
+}
+
+pub fn puzzle_2(input: []const u8) Result {
+ var cycle: u16 = 1;
+ var register: i16 = 1;
+ var screen = [_][40]bool{[_]bool{false} ** 40} ** 6;
+
+ var iter = std.mem.split(u8, input, "\n");
+ while (iter.next()) |line| {
+ crt(cycle, register, &screen);
+ cycle += 1;
+ crt(cycle, register, &screen);
+ if (line[0] != 'a') continue;
+ const n = std.fmt.parseInt(i16, line[5..], 0) catch unreachable;
+ cycle += 1;
+ crt(cycle, register, &screen);
+ register += n;
+ }
+
+ //for (screen) |row| {
+ //for (row) |pixel| {
+ //if (pixel) {
+ //std.debug.print("@", .{});
+ //} else {
+ //std.debug.print(" ", .{});
+ //}
+ //}
+ //std.debug.print("\n", .{});
+ //}
+
+ var r: usize = 0;
+ for (screen) |row, x| {
+ for (row) |pixel, y| r += y * x * @boolToInt(pixel);
+ }
+
+ return .{ .int = @intCast(i32, r) };
+}
diff --git a/day_11.zig b/day_11.zig
new file mode 100644
index 0000000..dc68190
--- /dev/null
+++ b/day_11.zig
@@ -0,0 +1,160 @@
+const std = @import("std");
+const Result = @import("util/aoc.zig").Result;
+
+const Operation = struct {
+ symbol: u8,
+ fixed: bool = false,
+ fixed_number: u8 = 0,
+
+ fn exe(self: Operation, b: u64) u64 {
+ if (self.symbol == '*') {
+ switch (self.fixed) {
+ true => return self.fixed_number * b,
+ false => return b * b,
+ }
+ }
+
+ switch (self.fixed) {
+ true => return self.fixed_number + b,
+ false => return b + b,
+ }
+ }
+};
+
+const Monkey = struct {
+ const Throw_rules = struct {
+ multiple_of: u8,
+ true: u8,
+ false: u8,
+ };
+
+ id: u8,
+ inspect_count: usize = 0,
+ items: std.ArrayList(u64),
+ operation: Operation,
+ throw_rules: Throw_rules,
+
+ fn throws_to(self: Monkey, worry_level: u64) usize {
+ if (worry_level % self.throw_rules.multiple_of == 0) return self.throw_rules.true;
+ return self.throw_rules.false;
+ }
+
+ fn inspect(self: *Monkey) u64 {
+ self.inspect_count += 1;
+ return self.operation.exe(self.items.orderedRemove(0));
+ }
+};
+
+fn answer(monkeys: []Monkey) u64 {
+ var max: [2]u64 = std.mem.zeroes([2]u64);
+ for (monkeys) |*monkey| {
+ if (monkey.inspect_count > max[0] and monkey.inspect_count > max[1]) {
+ max[1] = max[0];
+ max[0] = monkey.inspect_count;
+ } else if (monkey.inspect_count > max[1]) {
+ max[1] = monkey.inspect_count;
+ }
+
+ monkey.items.deinit();
+ }
+ return max[0] * max[1];
+}
+
+fn parse(allocator: std.mem.Allocator, input: []const u8) []Monkey {
+ var monkeys = std.ArrayList(Monkey).init(allocator);
+
+ var monkey_iter = std.mem.split(u8, input, "\n\n");
+ while (monkey_iter.next()) |monkey_data| {
+ var monkey = std.mem.split(u8, monkey_data, "\n");
+
+ var line = monkey.next().?;
+ var id = std.fmt.parseInt(u8, line[7 .. line.len - 1], 0) catch unreachable;
+
+ var items = std.ArrayList(u64).init(allocator);
+ line = monkey.next().?;
+ var items_iter = std.mem.split(u8, line[18..], ", ");
+ while (items_iter.next()) |item| {
+ items.append(std.fmt.parseInt(u64, item, 0) catch unreachable) catch unreachable;
+ }
+
+ const operation = blk: {
+ line = monkey.next().?;
+ var op = Operation{ .symbol = line[23] };
+
+ if (line[25] != 'o') {
+ op.fixed = true;
+ op.fixed_number = std.fmt.parseInt(u8, line[25..], 0) catch unreachable;
+ }
+
+ break :blk op;
+ };
+
+ const throw_rules = blk: {
+ line = monkey.next().?;
+ const multiple_of = std.fmt.parseInt(u8, line[21..], 0) catch unreachable;
+
+ line = monkey.next().?;
+ const iftrue = std.fmt.parseInt(u8, line[29..], 0) catch unreachable;
+
+ line = monkey.next().?;
+ const iffalse = std.fmt.parseInt(u8, line[30..], 0) catch unreachable;
+
+ break :blk Monkey.Throw_rules{
+ .multiple_of = multiple_of,
+ .true = iftrue,
+ .false = iffalse,
+ };
+ };
+
+ monkeys.append(Monkey{
+ .id = id,
+ .items = items,
+ .operation = operation,
+ .throw_rules = throw_rules,
+ }) catch unreachable;
+ }
+
+ return monkeys.toOwnedSlice() catch unreachable;
+}
+
+pub fn puzzle_1(allocator: std.mem.Allocator, input: []const u8) Result {
+ var monkeys = parse(allocator, input);
+ defer allocator.free(monkeys);
+
+ var i: usize = 0;
+ while (i < 20) : (i += 1) {
+ for (monkeys) |*monkey| {
+ while (monkey.items.items.len > 0) {
+ const new_worry_level = monkey.inspect();
+ const throw_to = monkey.throws_to(new_worry_level / 3);
+ monkeys[throw_to].items.append(new_worry_level / 3) catch unreachable;
+ }
+ }
+ }
+
+ return .{ .int = @intCast(i32, answer(monkeys)) };
+}
+
+pub fn puzzle_2(allocator: std.mem.Allocator, input: []const u8) Result {
+ var monkeys = parse(allocator, input);
+ defer allocator.free(monkeys);
+
+ const mod = blk: {
+ var r: u64 = 1;
+ for (monkeys) |monkey| r *= monkey.throw_rules.multiple_of;
+ break :blk r;
+ };
+
+ var i: usize = 0;
+ while (i < 10000) : (i += 1) {
+ for (monkeys) |*monkey| {
+ while (monkey.items.items.len > 0) {
+ const new_worry_level = monkey.inspect();
+ const throw_to = monkey.throws_to(new_worry_level % mod);
+ monkeys[throw_to].items.append(new_worry_level % mod) catch unreachable;
+ }
+ }
+ }
+
+ return .{ .int = @intCast(i64, answer(monkeys)) };
+}
diff --git a/inputs/day_10 b/inputs/day_10
new file mode 100644
index 0000000..5fab235
--- /dev/null
+++ b/inputs/day_10
@@ -0,0 +1,140 @@
+noop
+addx 25
+addx -5
+addx -14
+addx 4
+noop
+addx 2
+addx 3
+noop
+noop
+noop
+noop
+addx 3
+addx 5
+addx 2
+noop
+noop
+addx 5
+noop
+noop
+noop
+addx 1
+addx 2
+addx 5
+addx -40
+addx 5
+noop
+addx 26
+addx -20
+addx -3
+addx 2
+noop
+addx -4
+addx 9
+addx 5
+addx 2
+addx 11
+addx -10
+addx 2
+addx 5
+addx 2
+addx 5
+noop
+noop
+noop
+addx -31
+addx 32
+addx -37
+addx 1
+addx 8
+addx 13
+addx -15
+addx 4
+noop
+addx 5
+noop
+addx 3
+addx -2
+addx 4
+addx 1
+addx 4
+addx -14
+addx 15
+addx 4
+noop
+noop
+noop
+addx 3
+addx 5
+addx -40
+noop
+addx 5
+addx 8
+addx -3
+noop
+addx 2
+addx 9
+addx -4
+noop
+noop
+noop
+noop
+addx 5
+addx -9
+addx 10
+addx 4
+noop
+noop
+addx 5
+addx -19
+addx 24
+addx -2
+addx 5
+addx -40
+addx 22
+addx -19
+addx 2
+addx 5
+addx 2
+addx 5
+noop
+noop
+addx -2
+addx 2
+addx 5
+addx 3
+noop
+addx 2
+addx 2
+addx 3
+addx -2
+addx 10
+addx -3
+addx 3
+noop
+addx -40
+addx 2
+addx 11
+addx -5
+addx -1
+noop
+addx 3
+addx 7
+noop
+addx -2
+addx 5
+addx 2
+addx 3
+noop
+addx 2
+addx 6
+addx -5
+addx 2
+addx -18
+addx 26
+addx -1
+noop
+noop
+noop
+noop
diff --git a/inputs/day_11 b/inputs/day_11
new file mode 100644
index 0000000..f505c2e
--- /dev/null
+++ b/inputs/day_11
@@ -0,0 +1,55 @@
+Monkey 0:
+ Starting items: 83, 97, 95, 67
+ Operation: new = old * 19
+ Test: divisible by 17
+ If true: throw to monkey 2
+ If false: throw to monkey 7
+
+Monkey 1:
+ Starting items: 71, 70, 79, 88, 56, 70
+ Operation: new = old + 2
+ Test: divisible by 19
+ If true: throw to monkey 7
+ If false: throw to monkey 0
+
+Monkey 2:
+ Starting items: 98, 51, 51, 63, 80, 85, 84, 95
+ Operation: new = old + 7
+ Test: divisible by 7
+ If true: throw to monkey 4
+ If false: throw to monkey 3
+
+Monkey 3:
+ Starting items: 77, 90, 82, 80, 79
+ Operation: new = old + 1
+ Test: divisible by 11
+ If true: throw to monkey 6
+ If false: throw to monkey 4
+
+Monkey 4:
+ Starting items: 68
+ Operation: new = old * 5
+ Test: divisible by 13
+ If true: throw to monkey 6
+ If false: throw to monkey 5
+
+Monkey 5:
+ Starting items: 60, 94
+ Operation: new = old + 5
+ Test: divisible by 3
+ If true: throw to monkey 1
+ If false: throw to monkey 0
+
+Monkey 6:
+ Starting items: 81, 51, 85
+ Operation: new = old * old
+ Test: divisible by 5
+ If true: throw to monkey 5
+ If false: throw to monkey 1
+
+Monkey 7:
+ Starting items: 98, 81, 63, 65, 84, 71, 84
+ Operation: new = old + 3
+ Test: divisible by 2
+ If true: throw to monkey 2
+ If false: throw to monkey 3
diff --git a/main.zig b/main.zig
index 5108467..cb602a5 100644
--- a/main.zig
+++ b/main.zig
@@ -15,6 +15,8 @@ const t = [_]struct {
.{ .day = @import("day_07.zig"), .input = @embedFile("inputs/day_07"), .expect = &[_]Result{ .{ .int = 1427048 }, .{ .int = 2940614 } } },
.{ .day = @import("day_08.zig"), .input = @embedFile("inputs/day_08"), .expect = &[_]Result{ .{ .int = 1859 }, .{ .int = 332640 } } },
.{ .day = @import("day_09.zig"), .input = @embedFile("inputs/day_09"), .expect = &[_]Result{ .{ .int = 6087 }, .{ .int = 2493 } } },
+ .{ .day = @import("day_10.zig"), .input = @embedFile("inputs/day_10"), .expect = &[_]Result{ .{ .int = 14620 }, .{ .int = 4210 } } },
+ .{ .day = @import("day_11.zig"), .input = @embedFile("inputs/day_11"), .expect = &[_]Result{ .{ .int = 108240 }, .{ .int = 25712998901 } } },
};
pub fn main() !void {
diff --git a/util/aoc.zig b/util/aoc.zig
index 0c3e668..0f32c54 100644
--- a/util/aoc.zig
+++ b/util/aoc.zig
@@ -1,7 +1,7 @@
const std = @import("std");
pub const Result = union(enum) {
- int: i32,
+ int: i64,
string: []const u8,
pub fn cmp(self: Result, result: Result) bool {