diff --git a/day03-easy/src/main.zig b/day03-easy/src/main.zig index 3b5f069..5df8165 100644 --- a/day03-easy/src/main.zig +++ b/day03-easy/src/main.zig @@ -1,20 +1,27 @@ const std = @import("std"); -fn isSymbol(char: u8) bool { - return switch (char) { - '0'...'9' => false, - '.' => false, - else => true, - }; -} +const Char = enum(u4) { + Zero = 0, + One = 1, + Two = 2, + Three = 3, + Four = 4, + Five = 5, + Six = 6, + Seven = 7, + Eight = 8, + Nine = 9, + Dot = 12, + Symbol = 13, +}; const CharInfo = struct { - adjacents: [8]u8, - this: u8, + adjacents: [8]Char, + this: Char, fn isAdjacentToSymbol(self: *const CharInfo) bool { for (0..8) |i| { - if (isSymbol(self.adjacents[i])) { + if (self.adjacents[i] == .Symbol) { return true; } } @@ -28,7 +35,7 @@ const State = struct { is_adjacent_to_symbol: bool = false, fn addDigit(self: *State, char_info: CharInfo) void { - self.number = self.number * 10 + (char_info.this - '0'); + self.number = self.number * 10 + @intFromEnum(char_info.this); self.is_adjacent_to_symbol = self.is_adjacent_to_symbol or char_info.isAdjacentToSymbol(); } }; @@ -42,10 +49,10 @@ fn solve(engine: [][]const CharInfo) u32 { for (line) |char_info| { //std.debug.print("handling: {s}({s})\n", .{ [_]u8{char_info.this}, char_info.adjacents }); switch (char_info.this) { - '0'...'9' => { + .Zero, .One, .Two, .Three, .Four, .Five, .Six, .Seven, .Eight, .Nine => { current_state.addDigit(char_info); }, - else => { + .Dot, .Symbol => { if (current_state.is_adjacent_to_symbol) { //std.debug.print("adding: {d}\n", .{current_state.number}); result += current_state.number; @@ -67,21 +74,21 @@ fn solve(engine: [][]const CharInfo) u32 { return result; } -fn charLinesToCharInfoLines(allocator: std.mem.Allocator, char_lines: [][]const u8) ![][]const CharInfo { +fn charLinesToCharInfoLines(allocator: std.mem.Allocator, char_lines: [][]const Char) ![][]const CharInfo { var char_info_lines = try allocator.alloc([]CharInfo, char_lines.len); for (0..char_lines.len) |i| { const char_line = char_lines[i]; var char_info_line = try allocator.alloc(CharInfo, char_line.len); for (0..char_line.len) |j| { char_info_line[j] = CharInfo{ .this = char_line[j], .adjacents = .{ - if (i > 0 and j > 0) char_lines[i - 1][j - 1] else '.', - if (i > 0) char_lines[i - 1][j] else '.', - if (i > 0 and j + 1 < char_line.len) char_lines[i - 1][j + 1] else '.', - if (j > 0) char_line[j - 1] else '.', - if (j + 1 < char_line.len) char_line[j + 1] else '.', - if (i + 1 < char_lines.len and j > 0) char_lines[i + 1][j - 1] else '.', - if (i + 1 < char_lines.len) char_lines[i + 1][j] else '.', - if (i + 1 < char_lines.len and j + 1 < char_line.len) char_lines[i + 1][j + 1] else '.', + if (i > 0 and j > 0) char_lines[i - 1][j - 1] else .Dot, + if (i > 0) char_lines[i - 1][j] else .Dot, + if (i > 0 and j + 1 < char_line.len) char_lines[i - 1][j + 1] else .Dot, + if (j > 0) char_line[j - 1] else .Dot, + if (j + 1 < char_line.len) char_line[j + 1] else .Dot, + if (i + 1 < char_lines.len and j > 0) char_lines[i + 1][j - 1] else .Dot, + if (i + 1 < char_lines.len) char_lines[i + 1][j] else .Dot, + if (i + 1 < char_lines.len and j + 1 < char_line.len) char_lines[i + 1][j + 1] else .Dot, } }; } @@ -91,11 +98,18 @@ fn charLinesToCharInfoLines(allocator: std.mem.Allocator, char_lines: [][]const return char_info_lines; } -fn readInput(allocator: std.mem.Allocator, reader: anytype) ![][]const u8 { - var lines = std.ArrayList([]u8).init(allocator); +fn readInput(allocator: std.mem.Allocator, reader: anytype) ![][]const Char { + var lines = std.ArrayList([]Char).init(allocator); var line_buffer: [1000]u8 = undefined; while (try reader.readUntilDelimiterOrEof(&line_buffer, '\n')) |line_ref| { - const line = try allocator.dupe(u8, line_ref); + var line = try allocator.alloc(Char, line_ref.len); + for (line_ref, line) |raw_char, *char| { + char.* = switch (raw_char) { + '0'...'9' => @enumFromInt(raw_char - '0'), + '.' => .Dot, + else => .Symbol, + }; + } try lines.append(line); }