Compare commits
2 Commits
722811225c
...
eae81ce631
Author | SHA1 | Date | |
---|---|---|---|
eae81ce631 | |||
ff8924991c |
153
src/day19.zig
153
src/day19.zig
@ -45,7 +45,7 @@ const Rule = struct {
|
|||||||
condition: RuleCondition,
|
condition: RuleCondition,
|
||||||
property: PartProperty = .X,
|
property: PartProperty = .X,
|
||||||
next: NameString,
|
next: NameString,
|
||||||
value: u32 = 0,
|
value: u16 = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Workflow = std.ArrayList(Rule);
|
const Workflow = std.ArrayList(Rule);
|
||||||
@ -57,6 +57,43 @@ const MachinePart = struct {
|
|||||||
s: u32 = 0
|
s: u32 = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PropertyRange = struct {
|
||||||
|
min: u16,
|
||||||
|
max: u16,
|
||||||
|
|
||||||
|
fn is_empty(self: @This()) bool {
|
||||||
|
return self.min > self.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size(self: @This()) u64 {
|
||||||
|
return (self.max - self.min) + 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const MachinePartRange = struct {
|
||||||
|
x: PropertyRange,
|
||||||
|
m: PropertyRange,
|
||||||
|
a: PropertyRange,
|
||||||
|
s: PropertyRange,
|
||||||
|
|
||||||
|
fn get(self: *MachinePartRange, prop: PartProperty) *PropertyRange {
|
||||||
|
return switch (prop) {
|
||||||
|
.X => &self.x,
|
||||||
|
.M => &self.m,
|
||||||
|
.A => &self.a,
|
||||||
|
.S => &self.s,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_empty(self: MachinePartRange) bool {
|
||||||
|
return self.x.is_empty() or self.m.is_empty() or self.a.is_empty() or self.s.is_empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size(self: MachinePartRange) u64 {
|
||||||
|
return self.x.size() * self.m.size() * self.a.size() * self.s.size();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const Input = struct {
|
const Input = struct {
|
||||||
workflows: std.AutoHashMap(NameString, Workflow),
|
workflows: std.AutoHashMap(NameString, Workflow),
|
||||||
machine_parts: std.ArrayList(MachinePart),
|
machine_parts: std.ArrayList(MachinePart),
|
||||||
@ -78,17 +115,21 @@ const Input = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn print_rule(rule: Rule) void {
|
||||||
|
switch (rule.condition) {
|
||||||
|
.Always => std.debug.print("{s}", .{rule.next.slice()}),
|
||||||
|
.Less => std.debug.print("{s}<{}:{s}", .{rule.property.to_str(), rule.value, rule.next.slice()}),
|
||||||
|
.More => std.debug.print("{s}>{}:{s}", .{rule.property.to_str(), rule.value, rule.next.slice()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn print_workflow(workflow: Workflow) void {
|
fn print_workflow(workflow: Workflow) void {
|
||||||
std.debug.print("{{", .{});
|
std.debug.print("{{", .{});
|
||||||
for (0.., workflow.items) |i, rule| {
|
for (0.., workflow.items) |i, rule| {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
std.debug.print(",", .{});
|
std.debug.print(",", .{});
|
||||||
}
|
}
|
||||||
switch (rule.condition) {
|
print_rule(rule);
|
||||||
.Always => std.debug.print("{s}", .{rule.next.slice()}),
|
|
||||||
.Less => std.debug.print("{s}<{}:{s}", .{rule.property.to_str(), rule.value, rule.next.slice()}),
|
|
||||||
.More => std.debug.print("{s}>{}:{s}", .{rule.property.to_str(), rule.value, rule.next.slice()})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
std.debug.print("}}\n", .{});
|
std.debug.print("}}\n", .{});
|
||||||
}
|
}
|
||||||
@ -119,7 +160,7 @@ fn parse_workflow(allocator: Allocator, line: []const u8) !std.meta.Tuple(&.{ Na
|
|||||||
try parsed.append(Rule{
|
try parsed.append(Rule{
|
||||||
.condition = condition,
|
.condition = condition,
|
||||||
.property = PartProperty.from_str(rule_str[0..cmp_idx]) orelse return error.Invalid,
|
.property = PartProperty.from_str(rule_str[0..cmp_idx]) orelse return error.Invalid,
|
||||||
.value = try std.fmt.parseUnsigned(u32, rule_str[(cmp_idx+1)..colon], 10),
|
.value = try std.fmt.parseUnsigned(u16, rule_str[(cmp_idx+1)..colon], 10),
|
||||||
.next = try NameString.fromSlice(rule_str[(colon+1)..])
|
.next = try NameString.fromSlice(rule_str[(colon+1)..])
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -264,7 +305,101 @@ pub fn part2(input: *aoc.Input) !aoc.Result {
|
|||||||
var parsed = try parse_input(allocator, input.lines);
|
var parsed = try parse_input(allocator, input.lines);
|
||||||
defer parsed.deinit();
|
defer parsed.deinit();
|
||||||
|
|
||||||
return .{ .uint = 0 };
|
const State = struct {
|
||||||
|
name: NameString,
|
||||||
|
machine_part: MachinePartRange,
|
||||||
|
};
|
||||||
|
|
||||||
|
var stack = std.ArrayList(State).init(allocator);
|
||||||
|
defer stack.deinit();
|
||||||
|
|
||||||
|
try stack.append(State{
|
||||||
|
.name = try NameString.fromSlice("in"),
|
||||||
|
.machine_part = MachinePartRange{
|
||||||
|
.x = PropertyRange{ .min = 1, .max = 4000 },
|
||||||
|
.m = PropertyRange{ .min = 1, .max = 4000 },
|
||||||
|
.a = PropertyRange{ .min = 1, .max = 4000 },
|
||||||
|
.s = PropertyRange{ .min = 1, .max = 4000 },
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var accepted_count: u64 = 0;
|
||||||
|
|
||||||
|
while (stack.popOrNull()) |state| {
|
||||||
|
var current: MachinePartRange = state.machine_part;
|
||||||
|
|
||||||
|
const name_str = state.name.slice();
|
||||||
|
if (std.mem.eql(u8, name_str, "A")) {
|
||||||
|
accepted_count += current.size();
|
||||||
|
continue;
|
||||||
|
} else if (std.mem.eql(u8, name_str, "R")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const workflow: Workflow = parsed.workflows.get(state.name).?;
|
||||||
|
for (workflow.items) |rule| {
|
||||||
|
if (current.is_empty()) break;
|
||||||
|
|
||||||
|
if (rule.condition == .Always) {
|
||||||
|
try stack.append(State{
|
||||||
|
.name = rule.next,
|
||||||
|
.machine_part = current,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var current_property_range = current.get(rule.property);
|
||||||
|
|
||||||
|
var is_min_captured = false;
|
||||||
|
var is_max_captured = false;
|
||||||
|
if (rule.condition == .Less) {
|
||||||
|
is_min_captured = current_property_range.min < rule.value;
|
||||||
|
is_max_captured = current_property_range.max < rule.value;
|
||||||
|
} else if (rule.condition == .More) {
|
||||||
|
is_min_captured = current_property_range.min > rule.value;
|
||||||
|
is_max_captured = current_property_range.max > rule.value;
|
||||||
|
} else {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_min_captured and !is_max_captured) {
|
||||||
|
// Nothing gets captured by this rule, go to the next rule
|
||||||
|
} else if (is_min_captured and is_max_captured) {
|
||||||
|
// Everything gets captured by this rule, can skip checking other rules
|
||||||
|
try stack.append(State{
|
||||||
|
.name = rule.next,
|
||||||
|
.machine_part = current
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
} else if (!is_min_captured and is_max_captured) {
|
||||||
|
// Only the upper part is captured
|
||||||
|
var upper_machine_parts = current;
|
||||||
|
var upper_property_range = upper_machine_parts.get(rule.property);
|
||||||
|
upper_property_range.min = rule.value + 1;
|
||||||
|
current_property_range.max = rule.value;
|
||||||
|
|
||||||
|
try stack.append(State{
|
||||||
|
.name = rule.next,
|
||||||
|
.machine_part = upper_machine_parts
|
||||||
|
});
|
||||||
|
} else if (is_min_captured and !is_max_captured) {
|
||||||
|
// Only the lower part is captured
|
||||||
|
var lower_machine_parts = current;
|
||||||
|
var lower_property_range = lower_machine_parts.get(rule.property);
|
||||||
|
lower_property_range.max = rule.value - 1;
|
||||||
|
current_property_range.min = rule.value;
|
||||||
|
|
||||||
|
try stack.append(State{
|
||||||
|
.name = rule.next,
|
||||||
|
.machine_part = lower_machine_parts
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{ .uint = accepted_count };
|
||||||
}
|
}
|
||||||
|
|
||||||
const example_input = [_][]const u8{
|
const example_input = [_][]const u8{
|
||||||
@ -292,5 +427,5 @@ test "part 1 example" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "part 2 example" {
|
test "part 2 example" {
|
||||||
try aoc.expectAnswerUInt(part1, 167409079868000, &example_input);
|
try aoc.expectAnswerUInt(part2, 167409079868000, &example_input);
|
||||||
}
|
}
|
||||||
|
336
src/day20.zig
Normal file
336
src/day20.zig
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const aoc = @import("./aoc.zig");
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
|
const NameString = std.BoundedArray(u8, 12);
|
||||||
|
|
||||||
|
const ModuleType = enum {
|
||||||
|
None,
|
||||||
|
FlipFlop,
|
||||||
|
Conjunction,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Module = struct {
|
||||||
|
name: NameString,
|
||||||
|
module_type: ModuleType,
|
||||||
|
outputs: std.ArrayList(NameString),
|
||||||
|
|
||||||
|
fn deinit(self: Module) void {
|
||||||
|
self.outputs.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print(self: Module) void {
|
||||||
|
if (self.module_type == .FlipFlop) {
|
||||||
|
std.debug.print("%", .{});
|
||||||
|
} else if (self.module_type == .Conjunction) {
|
||||||
|
std.debug.print("&", .{});
|
||||||
|
}
|
||||||
|
std.debug.print("{s} -> ", .{self.name.slice()});
|
||||||
|
for (0.., self.outputs.items) |i, output| {
|
||||||
|
if (i > 0) {
|
||||||
|
std.debug.print(", ", .{});
|
||||||
|
}
|
||||||
|
std.debug.print("{s}", .{output.slice()});
|
||||||
|
}
|
||||||
|
std.debug.print("\n", .{});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Input = struct {
|
||||||
|
modules: std.ArrayList(Module),
|
||||||
|
|
||||||
|
fn init(allocator: Allocator) Input {
|
||||||
|
return Input{
|
||||||
|
.modules = std.ArrayList(Module).init(allocator)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deinit(self: Input) void {
|
||||||
|
for (self.modules.items) |module| {
|
||||||
|
module.deinit();
|
||||||
|
}
|
||||||
|
self.modules.deinit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const ModuleId = u8;
|
||||||
|
|
||||||
|
const InternalModule = struct {
|
||||||
|
const max_inputs = 12;
|
||||||
|
|
||||||
|
module_type: ModuleType,
|
||||||
|
state: std.bit_set.IntegerBitSet(max_inputs),
|
||||||
|
inputs: []ModuleId,
|
||||||
|
outputs: []ModuleId,
|
||||||
|
|
||||||
|
fn flip_flop(self: *@This()) bool {
|
||||||
|
self.state.mask = ~self.state.mask;
|
||||||
|
return self.state.mask != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_input(self: *@This(), module_index: ModuleId, is_high: bool) bool {
|
||||||
|
const index = std.mem.indexOfScalar(ModuleId, self.inputs, module_index);
|
||||||
|
assert(index != null);
|
||||||
|
|
||||||
|
self.state.setValue(index.?, is_high);
|
||||||
|
return self.state.count() != self.inputs.len;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn append_if_new(names: *std.ArrayList(NameString), name: NameString) !void {
|
||||||
|
for (names.items) |other_name| {
|
||||||
|
if (std.mem.eql(u8, other_name.slice(), name.slice())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try names.append(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const MachineState = struct {
|
||||||
|
allocator: Allocator,
|
||||||
|
names: []NameString,
|
||||||
|
state: []InternalModule,
|
||||||
|
|
||||||
|
fn init(allocator: Allocator, modules: []Module) !MachineState {
|
||||||
|
assert(modules.len < (1 << @bitSizeOf(ModuleId)));
|
||||||
|
|
||||||
|
var names = std.ArrayList(NameString).init(allocator);
|
||||||
|
defer names.deinit();
|
||||||
|
for (modules) |module| {
|
||||||
|
try append_if_new(&names, module.name);
|
||||||
|
for (module.outputs.items) |output| {
|
||||||
|
try append_if_new(&names, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var self = MachineState {
|
||||||
|
.state = try allocator.alloc(InternalModule, names.items.len),
|
||||||
|
.names = try allocator.dupe(NameString, names.items),
|
||||||
|
.allocator = allocator
|
||||||
|
};
|
||||||
|
errdefer self.deinit();
|
||||||
|
|
||||||
|
@memset(self.state, InternalModule{
|
||||||
|
.module_type = .None,
|
||||||
|
.state = std.bit_set.IntegerBitSet(12).initEmpty(),
|
||||||
|
.inputs = &[0]ModuleId{},
|
||||||
|
.outputs = &[0]ModuleId{},
|
||||||
|
});
|
||||||
|
|
||||||
|
for (modules) |module| {
|
||||||
|
const module_idx = self.get_name_idx(module.name).?;
|
||||||
|
var internal_module = &self.state[module_idx];
|
||||||
|
|
||||||
|
internal_module.module_type = module.module_type;
|
||||||
|
internal_module.outputs = try allocator.alloc(ModuleId, module.outputs.items.len);
|
||||||
|
for (0.., module.outputs.items) |output_idx, output_name| {
|
||||||
|
const index = self.get_name_idx(output_name);
|
||||||
|
assert(index != null);
|
||||||
|
internal_module.outputs[output_idx] = @intCast(index.?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (0.., self.state) |i, *module| {
|
||||||
|
var input_count: usize = 0;
|
||||||
|
for (self.state) |other_module| {
|
||||||
|
if (std.mem.indexOfScalar(ModuleId, other_module.outputs, @intCast(i)) != null) {
|
||||||
|
input_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input_count == 0) continue;
|
||||||
|
|
||||||
|
var index: usize = 0;
|
||||||
|
assert(input_count <= InternalModule.max_inputs);
|
||||||
|
module.inputs = try allocator.alloc(ModuleId, input_count);
|
||||||
|
for (0.., self.state) |other_i, other_module| {
|
||||||
|
if (std.mem.indexOfScalar(ModuleId, other_module.outputs, @intCast(i)) != null) {
|
||||||
|
module.inputs[index] = @intCast(other_i);
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deinit(self: MachineState) void {
|
||||||
|
for (self.state) |module| {
|
||||||
|
if (module.inputs.len > 0) {
|
||||||
|
self.allocator.free(module.inputs);
|
||||||
|
}
|
||||||
|
if (module.outputs.len > 0) {
|
||||||
|
self.allocator.free(module.outputs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.allocator.free(self.state);
|
||||||
|
self.allocator.free(self.names);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_name_idx(self: MachineState, name: NameString) ?ModuleId {
|
||||||
|
for (0.., self.names) |i, other_name| {
|
||||||
|
if (std.mem.eql(u8, other_name.slice(), name.slice())) {
|
||||||
|
return @intCast(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn parse_module(allocator: Allocator, line: []const u8) !Module {
|
||||||
|
var arrow_split_iter = std.mem.splitSequence(u8, line, "->");
|
||||||
|
|
||||||
|
const name_with_type = arrow_split_iter.next() orelse return error.NoName;
|
||||||
|
var name = std.mem.trim(u8, name_with_type, " ");
|
||||||
|
|
||||||
|
var module_type = ModuleType.None;
|
||||||
|
if (name_with_type[0] == '&') {
|
||||||
|
module_type = .Conjunction;
|
||||||
|
name = name[1..];
|
||||||
|
} else if (name_with_type[0] == '%') {
|
||||||
|
module_type = .FlipFlop;
|
||||||
|
name = name[1..];
|
||||||
|
}
|
||||||
|
|
||||||
|
var outputs = std.ArrayList(NameString).init(allocator);
|
||||||
|
errdefer outputs.deinit();
|
||||||
|
|
||||||
|
var output_split_iter = std.mem.splitScalar(u8, arrow_split_iter.rest(), ',');
|
||||||
|
while (output_split_iter.next()) |output_str| {
|
||||||
|
const trimmed_name = std.mem.trim(u8, output_str, " ");
|
||||||
|
try outputs.append(try NameString.fromSlice(trimmed_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Module{
|
||||||
|
.name = try NameString.fromSlice(name),
|
||||||
|
.module_type = module_type,
|
||||||
|
.outputs = outputs
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input(allocator: Allocator, lines: []const []const u8) !Input {
|
||||||
|
var parsed = Input.init(allocator);
|
||||||
|
errdefer parsed.deinit();
|
||||||
|
|
||||||
|
for (lines) |line| {
|
||||||
|
try parsed.modules.append(try parse_module(allocator, line));
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Pulse = struct {
|
||||||
|
is_high: bool,
|
||||||
|
from: ModuleId,
|
||||||
|
to: ModuleId,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn simulate_pulse(pulse_queue: *std.ArrayList(Pulse), machine_state: *MachineState, pulse: Pulse) !void {
|
||||||
|
var to_module = &machine_state.state[pulse.to];
|
||||||
|
|
||||||
|
var output_is_high = false;
|
||||||
|
if (to_module.module_type == .None) {
|
||||||
|
output_is_high = pulse.is_high;
|
||||||
|
} else if (to_module.module_type == .FlipFlop) {
|
||||||
|
if (pulse.is_high) return;
|
||||||
|
output_is_high = to_module.flip_flop();
|
||||||
|
} else if (to_module.module_type == .Conjunction) {
|
||||||
|
output_is_high = to_module.update_input(pulse.from, pulse.is_high);
|
||||||
|
} else {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (to_module.outputs) |output| {
|
||||||
|
try pulse_queue.append(Pulse{
|
||||||
|
.is_high = output_is_high,
|
||||||
|
.to = output,
|
||||||
|
.from = pulse.to
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn simulate_button_press(allocator: Allocator, machine_state: *MachineState, broadcaster: ModuleId) !struct { low: u64, high: u64 } {
|
||||||
|
var pulses = std.ArrayList(Pulse).init(allocator);
|
||||||
|
defer pulses.deinit();
|
||||||
|
|
||||||
|
var low_pulse_count: u64 = 0;
|
||||||
|
var high_pulse_count: u64 = 0;
|
||||||
|
|
||||||
|
try pulses.append(Pulse{
|
||||||
|
.is_high = false,
|
||||||
|
.to = broadcaster,
|
||||||
|
.from = broadcaster,
|
||||||
|
});
|
||||||
|
|
||||||
|
while (pulses.items.len > 0) {
|
||||||
|
const pulse: Pulse = pulses.orderedRemove(0);
|
||||||
|
|
||||||
|
if (pulse.is_high) {
|
||||||
|
high_pulse_count += 1;
|
||||||
|
} else {
|
||||||
|
low_pulse_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
try simulate_pulse(&pulses, machine_state, pulse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{ .low = low_pulse_count, .high = high_pulse_count };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part1(input: *aoc.Input) !aoc.Result {
|
||||||
|
const allocator = input.allocator;
|
||||||
|
const parsed = try parse_input(allocator, input.lines);
|
||||||
|
defer parsed.deinit();
|
||||||
|
|
||||||
|
var machine_state = try MachineState.init(allocator, parsed.modules.items);
|
||||||
|
defer machine_state.deinit();
|
||||||
|
|
||||||
|
const broadcaster_idx = machine_state.get_name_idx(try NameString.fromSlice("broadcaster")).?;
|
||||||
|
|
||||||
|
var low_count: u64 = 0;
|
||||||
|
var high_count: u64 = 0;
|
||||||
|
for (0..1000) |_| {
|
||||||
|
const high_low_count = try simulate_button_press(allocator, &machine_state, broadcaster_idx);
|
||||||
|
low_count += high_low_count.low;
|
||||||
|
high_count += high_low_count.high;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{ .uint = low_count * high_count };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part2(input: *aoc.Input) !aoc.Result {
|
||||||
|
const allocator = input.allocator;
|
||||||
|
const parsed = try parse_input(allocator, input.lines);
|
||||||
|
defer parsed.deinit();
|
||||||
|
|
||||||
|
var machine_state = try MachineState.init(allocator, parsed.modules.items);
|
||||||
|
defer machine_state.deinit();
|
||||||
|
|
||||||
|
return .{ .uint = 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
const example_input1 = [_][]const u8{
|
||||||
|
"broadcaster -> a, b, c",
|
||||||
|
"%a -> b",
|
||||||
|
"%b -> c",
|
||||||
|
"%c -> inv",
|
||||||
|
"&inv -> a",
|
||||||
|
};
|
||||||
|
|
||||||
|
const example_input2 = [_][]const u8{
|
||||||
|
"broadcaster -> a",
|
||||||
|
"%a -> inv, con",
|
||||||
|
"&inv -> b",
|
||||||
|
"%b -> con",
|
||||||
|
"&con -> output",
|
||||||
|
};
|
||||||
|
|
||||||
|
test "part 1 example 1" {
|
||||||
|
try aoc.expectAnswerUInt(part1, 32000000, &example_input1);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "part 1 example 2" {
|
||||||
|
try aoc.expectAnswerUInt(part1, 11687500, &example_input2);
|
||||||
|
}
|
@ -40,6 +40,7 @@ const Days = [_]aoc.Day{
|
|||||||
create_day(@import("./day17.zig")),
|
create_day(@import("./day17.zig")),
|
||||||
create_day(@import("./day18.zig")),
|
create_day(@import("./day18.zig")),
|
||||||
create_day(@import("./day19.zig")),
|
create_day(@import("./day19.zig")),
|
||||||
|
create_day(@import("./day20.zig")),
|
||||||
};
|
};
|
||||||
|
|
||||||
fn kilobytes(count: u32) u32 {
|
fn kilobytes(count: u32) u32 {
|
||||||
@ -202,4 +203,5 @@ test {
|
|||||||
_ = @import("./day17.zig");
|
_ = @import("./day17.zig");
|
||||||
_ = @import("./day18.zig");
|
_ = @import("./day18.zig");
|
||||||
_ = @import("./day19.zig");
|
_ = @import("./day19.zig");
|
||||||
|
_ = @import("./day20.zig");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user