aoc-2020-zig

Advent of Code 2020 Solutions in Zig
git clone https://git.sinitax.com/sinitax/aoc-2020-zig
Log | Files | Refs | README | sfeed.txt

main.zig (1920B)


      1const std = @import("std");
      2const aoc = @import("aoc");
      3
      4const Entry = struct { a: u16, b: u16, char: u8, pass: []u8 };
      5
      6fn freeEntries(allocator: std.mem.Allocator, entries: *const std.ArrayList(Entry)) void {
      7    for (entries.items) |item|
      8        allocator.free(item.pass);
      9    entries.deinit();
     10}
     11
     12fn parse(allocator: std.mem.Allocator, input: []u8) !std.ArrayList(Entry) {
     13    var entries = std.ArrayList(Entry).init(allocator);
     14    errdefer freeEntries(allocator, &entries);
     15
     16    var lineit = std.mem.tokenize(u8, input, "\n");
     17    while (lineit.next()) |line| {
     18        var entry: Entry = undefined;
     19        var it = std.mem.tokenize(u8, line, " -");
     20        entry.a = try std.fmt.parseInt(u16, it.next().?, 10);
     21        entry.b = try std.fmt.parseInt(u16, it.next().?, 10);
     22        entry.char = it.next().?[0];
     23        entry.pass = try allocator.dupe(u8, it.next().?);
     24        try entries.append(entry);
     25    }
     26
     27    return entries;
     28}
     29
     30fn part1(allocator: std.mem.Allocator, input: []u8, args: [][]u8) !?[]u8 {
     31    _ = args;
     32
     33    const entries = try parse(allocator, input);
     34    defer freeEntries(allocator, &entries);
     35
     36    var valid: u32 = 0;
     37    for (entries.items) |entry| {
     38        var count: u16 = 0;
     39        for (entry.pass) |c| count += @boolToInt(c == entry.char);
     40        valid += @boolToInt(count >= entry.a and count <= entry.b);
     41    }
     42
     43    return try std.fmt.allocPrint(allocator, "{d}", .{valid});
     44}
     45
     46fn part2(allocator: std.mem.Allocator, input: []u8, args: [][]u8) !?[]u8 {
     47    _ = args;
     48
     49    const entries = try parse(allocator, input);
     50    defer freeEntries(allocator, &entries);
     51
     52    var valid: u32 = 0;
     53    for (entries.items) |entry| {
     54        valid += @boolToInt((entry.pass[entry.a - 1] == entry.char) !=
     55            (entry.pass[entry.b - 1] == entry.char));
     56    }
     57
     58    return try std.fmt.allocPrint(allocator, "{d}", .{valid});
     59}
     60
     61pub const main = aoc.main(part1, part2, .{ "603", "404" });