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 (2221B)


      1const std = @import("std");
      2const aoc = @import("aoc");
      3
      4const preamble_size = 25;
      5
      6fn preambleHasSum(preamble: []u64, target: u64) bool {
      7    for (preamble) |v1| {
      8        for (preamble) |v2| {
      9            if (v1 != v2 and v1 + v2 == target)
     10                return true;
     11        }
     12    }
     13    return false;
     14}
     15
     16fn getInvalid(allocator: std.mem.Allocator, input: []u8) !u64 {
     17    var preamble = std.ArrayList(u64).init(allocator);
     18    defer preamble.deinit();
     19
     20    var i: u64 = 0;
     21    var numit = std.mem.tokenize(u8, input, "\n");
     22    while (numit.next()) |numstr| : (i += 1) {
     23        const num = try std.fmt.parseInt(u64, numstr, 10);
     24        if (i > preamble_size) {
     25            if (!preambleHasSum(preamble.items, num)) {
     26                return num;
     27            }
     28            preamble.items[(i - 1) % preamble_size] = num;
     29        } else {
     30            try preamble.append(num);
     31        }
     32    }
     33
     34    return aoc.Error.InvalidInput;
     35}
     36
     37fn listSum(items: []u64) u64 {
     38    var sum: u64 = 0;
     39    for (items) |i|
     40        sum += i;
     41    return sum;
     42}
     43
     44fn part1(allocator: std.mem.Allocator, input: []u8, args: [][]u8) !?[]u8 {
     45    _ = args;
     46
     47    const answer = try getInvalid(allocator, input);
     48
     49    return try std.fmt.allocPrint(allocator, "{d}", .{answer});
     50}
     51
     52fn part2(allocator: std.mem.Allocator, input: []u8, args: [][]u8) !?[]u8 {
     53    _ = args;
     54
     55    const invalid = try getInvalid(allocator, input);
     56
     57    var numset = std.ArrayList(u64).init(allocator);
     58    defer numset.deinit();
     59
     60    var numit = std.mem.tokenize(u8, input, "\n");
     61    while (true) {
     62        const sum = listSum(numset.items);
     63        if (sum < invalid) {
     64            const numstr = numit.next();
     65            if (numstr == null) break;
     66            const num = try std.fmt.parseInt(u64, numstr.?, 10);
     67            try numset.append(num);
     68        } else if (sum > invalid) {
     69            _ = numset.orderedRemove(0);
     70        } else {
     71            break;
     72        }
     73    }
     74
     75    if (numset.items.len > 0) {
     76        const answer = std.mem.min(u64, numset.items) + std.mem.max(u64, numset.items);
     77        return try std.fmt.allocPrint(allocator, "{d}", .{answer});
     78    }
     79
     80    return null;
     81}
     82
     83pub const main = aoc.main(part1, part2, .{ "466456641", "55732936" });