aboutsummaryrefslogtreecommitdiff
path: root/day1.zig
blob: 5258b4e83fa1e88be714c76db30f4453b9b56a24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
const std = @import("std");
const digits = "0123456789";
const Setup = @import("common.zig").Setup;

const words = [_][]const u8{
    "0",
    "1",
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "8",
    "9",
    "zero",
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven",
    "eight",
    "nine",
    "ten",
};
const w2d = std.comptime_string_map.ComptimeStringMap(u8, .{
    .{ "0", 0 },
    .{ "1", 1 },
    .{ "2", 2 },
    .{ "3", 3 },
    .{ "4", 4 },
    .{ "5", 5 },
    .{ "6", 6 },
    .{ "7", 7 },
    .{ "8", 8 },
    .{ "9", 9 },
    .{ "zero", 0 },
    .{ "one", 1 },
    .{ "two", 2 },
    .{ "three", 3 },
    .{ "four", 4 },
    .{ "five", 5 },
    .{ "six", 6 },
    .{ "seven", 7 },
    .{ "eight", 8 },
    .{ "nine", 9 },
});

pub fn main() !void {
    var s = try Setup.get();
    defer s.deinit();
    var l = std.mem.splitScalar(u8, s.input, '\n');
    var t: u64 = 0;
    while (l.next()) |n| {
        switch (s.part) {
            .pt1 => {
                const ix1 = std.mem.indexOfAny(u8, n, digits) orelse return error.NoDigits;
                const ix2 = std.mem.lastIndexOfAny(u8, n, digits) orelse return error.NoDigits;
                const v1 = n[ix1] - '0'; // ascii -> number
                const v2 = n[ix2] - '0';
                const x = 10 * v1 + v2;
                t += x;
            },
            .pt2 => {
                var ix1: ?usize = null;
                var v1: u8 = 0;
                var ix2: ?usize = null;
                var v2: u8 = 0;
                for (words) |word| {
                    if (std.mem.indexOf(u8, n, word)) |mix1| {
                        if (ix1) |rix1| {
                            if (mix1 < rix1) {
                                ix1 = mix1;
                                v1 = w2d.get(word) orelse return error.Wtf;
                            }
                        } else {
                            ix1 = mix1;
                            v1 = w2d.get(word) orelse return error.Wtf;
                        }
                    }
                    if (std.mem.lastIndexOf(u8, n, word)) |mix2| {
                        if (ix2) |rix2| {
                            if (mix2 > rix2) {
                                ix2 = mix2;
                                v2 = w2d.get(word) orelse return error.Wtf;
                            }
                        } else {
                            ix2 = mix2;
                            v2 = w2d.get(word) orelse return error.Wtf;
                        }
                    }
                }
                //std.log.warn("n {s} v1 {} v2 {}", .{ n, v1, v2 });
                if (ix1 == null or ix2 == null) return error.NoDigits;
                t += (10 * v1) + v2;
            },
        }
    }
    try std.fmt.format(std.io.getStdOut().writer(), "sum of calibration values: {}\n", .{t});
}