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


      1const std = @import("std");
      2const aoc = @import("aoc");
      3const Console = @import("console8").Console;
      4
      5fn runTillRepeat(console: *Console, instlist: *std.ArrayList(u64), swapon: ?u64) !void {
      6    while (try console.parseNext()) |_inst| {
      7        var inst = _inst;
      8        aoc.debugfmt("{:<5}: {s} {d}\n", .{ console.instructptr, inst.opcode, inst.argval });
      9        if (std.mem.indexOfScalar(u64, instlist.items, console.instructptr) != null) {
     10            return;
     11        }
     12        if (swapon != null and swapon.? == console.instructptr) {
     13            inst.opfunc = switch (inst.opfunc) {
     14                Console.jumpInstruction => Console.nopInstruction,
     15                Console.nopInstruction => Console.jumpInstruction,
     16                else => unreachable,
     17            };
     18        }
     19        try instlist.append(console.instructptr);
     20        try console.exec(&inst);
     21    }
     22}
     23
     24fn part1(allocator: std.mem.Allocator, input: []u8, args: [][]u8) !?[]u8 {
     25    _ = args;
     26
     27    var console = try Console.init(input, allocator);
     28    defer console.deinit();
     29
     30    var instlist = std.ArrayList(u64).init(allocator);
     31    defer instlist.deinit();
     32
     33    try runTillRepeat(&console, &instlist, null);
     34
     35    return try std.fmt.allocPrint(allocator, "{d}", .{console.accumulator});
     36}
     37
     38fn part2(allocator: std.mem.Allocator, input: []u8, args: [][]u8) !?[]u8 {
     39    _ = args;
     40
     41    var console = try Console.init(input, allocator);
     42    defer console.deinit();
     43
     44    var instlist = std.ArrayList(u64).init(allocator);
     45    defer instlist.deinit();
     46
     47    try runTillRepeat(&console, &instlist, null);
     48
     49    for (instlist.items) |inst| {
     50        if (std.mem.eql(u8, "acc"[0..3], console.instlist[inst][0..3]))
     51            continue;
     52
     53        var sim_seen = std.ArrayList(u64).init(allocator);
     54        defer sim_seen.deinit();
     55
     56        console.reset();
     57        //std.debug.print("Swapping instruction: {:<5}: {}\n", .{ inst, console.instlist[inst] });
     58        runTillRepeat(&console, &sim_seen, inst) catch {};
     59        if (console.jumpAddr == console.instlist.len or console.instructptr == console.instlist.len) {
     60            return try std.fmt.allocPrint(allocator, "{d}", .{console.accumulator});
     61        }
     62    }
     63
     64    return null;
     65}
     66
     67pub const main = aoc.main(part1, part2, .{ "1766", "1639" });