const std = @import("std"); pub fn main() void { const input = @embedFile("input"); var iter = std.mem.split(u8, input, "\n"); var totalPoints: usize = 0; while (iter.next()) |round| { // Not a valid round. Not necessary, but just in case if (round.len < 3) continue; if (round[0] < 'A' or round[0] > 'C') continue; if (round[2] < 'X' or round[2] > 'Z') continue; // Convert letters to numbers const them = round[0] - 'A'; const me = round[2] - 'X'; // Points per shape chosen is easy. // {0,1,2} + 1 == {1,2,3} // which is what we want. const shapePoints = me + 1; // Now this is a bit more complex. // We notice that 'them - me' gives: // // tie = 0; // die = both -2 or 1; // win = both -1 or 2; // // If we wrap the results (adding 3 before because // we can't have negatives) 'result = (result+3)%3' // we get // // tie = 0; -> 3 points // die = 1; -> 0 points // win = 2; -> 6 points // // Ideally we would want {0,1,2} to be {0,3,6}, not // {3,0,6}. If we adjust it to '(result+4)%3' we get: // // win = 0; -> 6 points // tie = 1; -> 3 points // die = 2; -> 0 points // // That's closer but not ideal. If we invert the // numbers then we do get there '2-(result+4)%3': // // die = 0; -> 0 points // tie = 1; -> 3 points // win = 2; -> 6 points // // Now we multiply by three so '(2-(result+4)%3)*3' // and boom, points per result per match. const resultPoints = (2 - ((4 + them) - me) % 3) * 3; totalPoints += resultPoints + shapePoints; } std.debug.print("{}\n", .{totalPoints}); }