aoc2023

Advent of Code 2023
Log | Files | Refs | README

day1.zig (2995B)


      1 const std = @import("std");
      2 const digits = "0123456789";
      3 const Setup = @import("common.zig").Setup;
      4 
      5 const words = [_][]const u8{
      6     "0",
      7     "1",
      8     "2",
      9     "3",
     10     "4",
     11     "5",
     12     "6",
     13     "7",
     14     "8",
     15     "9",
     16     "zero",
     17     "one",
     18     "two",
     19     "three",
     20     "four",
     21     "five",
     22     "six",
     23     "seven",
     24     "eight",
     25     "nine",
     26     "ten",
     27 };
     28 const w2d = std.comptime_string_map.ComptimeStringMap(u8, .{
     29     .{ "0", 0 },
     30     .{ "1", 1 },
     31     .{ "2", 2 },
     32     .{ "3", 3 },
     33     .{ "4", 4 },
     34     .{ "5", 5 },
     35     .{ "6", 6 },
     36     .{ "7", 7 },
     37     .{ "8", 8 },
     38     .{ "9", 9 },
     39     .{ "zero", 0 },
     40     .{ "one", 1 },
     41     .{ "two", 2 },
     42     .{ "three", 3 },
     43     .{ "four", 4 },
     44     .{ "five", 5 },
     45     .{ "six", 6 },
     46     .{ "seven", 7 },
     47     .{ "eight", 8 },
     48     .{ "nine", 9 },
     49 });
     50 
     51 pub fn main() !void {
     52     var gpa = std.heap.GeneralPurposeAllocator(.{}){};
     53     defer _ = gpa.deinit();
     54     var s = try Setup.get(gpa.allocator());
     55     defer s.deinit();
     56     var l = std.mem.splitScalar(u8, s.input, '\n');
     57     var t: u64 = 0;
     58     while (l.next()) |n| {
     59         switch (s.part) {
     60             .pt1 => {
     61                 const ix1 = std.mem.indexOfAny(u8, n, digits) orelse return error.NoDigits;
     62                 const ix2 = std.mem.lastIndexOfAny(u8, n, digits) orelse return error.NoDigits;
     63                 const v1 = n[ix1] - '0'; // ascii -> number
     64                 const v2 = n[ix2] - '0';
     65                 const x = 10 * v1 + v2;
     66                 t += x;
     67             },
     68             .pt2 => {
     69                 var ix1: ?usize = null;
     70                 var v1: u8 = 0;
     71                 var ix2: ?usize = null;
     72                 var v2: u8 = 0;
     73                 for (words) |word| {
     74                     if (std.mem.indexOf(u8, n, word)) |mix1| {
     75                         if (ix1) |rix1| {
     76                             if (mix1 < rix1) {
     77                                 ix1 = mix1;
     78                                 v1 = w2d.get(word) orelse return error.Wtf;
     79                             }
     80                         } else {
     81                             ix1 = mix1;
     82                             v1 = w2d.get(word) orelse return error.Wtf;
     83                         }
     84                     }
     85                     if (std.mem.lastIndexOf(u8, n, word)) |mix2| {
     86                         if (ix2) |rix2| {
     87                             if (mix2 > rix2) {
     88                                 ix2 = mix2;
     89                                 v2 = w2d.get(word) orelse return error.Wtf;
     90                             }
     91                         } else {
     92                             ix2 = mix2;
     93                             v2 = w2d.get(word) orelse return error.Wtf;
     94                         }
     95                     }
     96                 }
     97                 //std.log.warn("n {s} v1 {} v2 {}", .{ n, v1, v2 });
     98                 if (ix1 == null or ix2 == null) return error.NoDigits;
     99                 t += (10 * v1) + v2;
    100             },
    101         }
    102     }
    103     try std.fmt.format(std.io.getStdOut().writer(), "sum of calibration values: {}\n", .{t});
    104 }