const std = @import("std"); const print = std.debug.print; pub const Button = struct { indicatorsConnected: []usize, }; pub const MachineScheme = struct { indicatorDiagram: []bool, buttons: []Button, joltages: []i32, }; pub fn readInputIntoString(allocator: std.mem.Allocator, fileName: []const u8) ![]u8 { const inputFile = try std.fs.cwd().openFile( fileName, .{.mode = .read_only,}); defer inputFile.close(); var inputFileReader = inputFile.reader( try allocator.alignedAlloc(u8, null, 1024)); const inputFileSize = try inputFileReader.getSize(); const inputBuffer = try allocator.alignedAlloc(u8, null, inputFileSize); try inputFileReader.interface.readSliceAll(inputBuffer); return inputBuffer; } fn parseIndicatorDiagram(allocator: std.mem.Allocator, text: []const u8) ![]bool { var indicators = std.ArrayList(bool).empty; for (text) |c| { const newIndicator = try indicators.addOne(allocator); if (c == '#') { newIndicator.* = true; } else { newIndicator.* = false; } } return indicators.items; } fn parseButton(allocator: std.mem.Allocator, text: []const u8) !Button { var indicators = std.ArrayList(usize).empty; var tokens = std.mem.tokenizeScalar(u8, text, ','); while (tokens.next()) |newIndicatorText| { const newIndicator = try indicators.addOne(allocator); newIndicator.* = try std.fmt.parseInt(usize, newIndicatorText, 10); } const button: Button = .{ .indicatorsConnected = indicators.items, }; print("Button: {[button]any}\n", .{.button = button}); return button; } pub fn readMachineScheme(allocator: std.mem.Allocator, line: []const u8) !MachineScheme { var indicatorDiagram: []bool = &.{}; var buttons = std.ArrayList(Button).empty; const joltages:[]i32 = &.{}; var tokens = std.mem.tokenizeScalar(u8, line, ' '); while (tokens.next()) |token| { const tokenContent = token[1..token.len-1]; if (token[0] == '[') { indicatorDiagram = try parseIndicatorDiagram(allocator, tokenContent); } else if (token[0] == '(') { const newButton = try buttons.addOne(allocator); newButton.* = try parseButton(allocator, tokenContent); } } const machineScheme: MachineScheme = .{ .indicatorDiagram = indicatorDiagram, .buttons = buttons.items, .joltages = joltages, }; return machineScheme; } pub fn readInput(allocator: std.mem.Allocator, fileName: []const u8) ![]MachineScheme { const inputBuffer = try readInputIntoString(allocator, fileName); var machineSchemes = std.ArrayList(MachineScheme).empty; var lines = std.mem.tokenizeScalar(u8, inputBuffer, '\n'); while (lines.next()) |line| { const newMachineScheme = try machineSchemes.addOne(allocator); newMachineScheme.* = try readMachineScheme(allocator, line); } return machineSchemes.items; }