const std = @import("std"); const lcConversion = 'a'; const ucConversion = 'A' - 26; const charIndexer = struct { pub const Key = u8; pub const count: usize = 52; pub fn indexOf(e: u8) usize { return letterToIdx(e); } pub fn keyForIndex(i: usize) u8 { return idxToLetter(i); } }; const CharSet: type = std.enums.IndexedSet(charIndexer, std.enums.NoExtension); fn letterToIdx(char: u8) u8 { return switch (char) { 'a'...'z' => char - lcConversion, 'A'...'Z' => char - ucConversion, else => unreachable, }; } fn idxToLetter(i: usize) u8 { const char = @intCast(u8, i); return if (char < 26) char + lcConversion else char + ucConversion; } pub fn main() !void { var file = try std.fs.cwd().openFile("input.txt", .{}); defer file.close(); var a = std.io.bufferedReader(file.reader()); var readerStream = a.reader(); var buf: [200]u8 = undefined; var score: i32 = 0; while (try readerStream.readUntilDelimiterOrEof(&buf, '\n')) |line| { var bagOne: CharSet = .{}; var bagTwo: CharSet = .{}; var i: u32 = 0; while (i < line.len / 2) : (i += 1) { bagOne.setPresent(line[i], true); } while (i < line.len) : (i += 1) { bagTwo.setPresent(line[i], true); } bagOne.setIntersection(bagTwo); if (bagOne.count() != 1) unreachable; // ensure only one element in common var iter = bagOne.iterator(); score += letterToIdx(iter.next().?) + 1; } std.debug.print("{d}\n", .{score}); }