day02.zig (4360B)
1 const std = @import("std"); 2 const dbg = std.debug; 3 const mem = std.mem; 4 5 pub fn main() !void { 6 var arena = std.heap.ArenaAllocator.init(std.heap.direct_allocator); 7 defer arena.deinit(); 8 const allocator = &arena.allocator; 9 10 var program: [input.len]u32 = undefined; 11 mem.copy(u32, program[0..input.len], input[0..input.len]); 12 13 var initial_output = try get_program_output(allocator, program[0..program.len], 12, 2); 14 dbg.warn("02-1: {}\n", initial_output); 15 16 var noun: u32 = 0; 17 var verb: u32 = 0; 18 search: while (noun < 100) : ({ 19 verb = 0; 20 noun += 1; 21 }) { 22 while (verb < 100) : (verb += 1) { 23 if ((try get_program_output(allocator, program[0..program.len], noun, verb)) == 19690720) { 24 break :search; 25 } 26 } 27 } 28 dbg.warn("02-2: {}\n", (100 * noun) + verb); 29 } 30 31 const OpCode = enum(u32) { 32 Add = 1, 33 Mult = 2, 34 Term = 99, 35 }; 36 37 fn run_intcode_program(allocator: *mem.Allocator, program: []const u32) ![]const u32 { 38 const num_codes = program.len; 39 var memory = try allocator.alloc(u32, num_codes); 40 mem.copy(u32, memory[0..num_codes], program[0..num_codes]); 41 42 var opcode = OpCode.Add; 43 var instruction_pointer: usize = 0; 44 while (true) { 45 dbg.assert(instruction_pointer < num_codes); 46 opcode = @intToEnum(OpCode, memory[instruction_pointer]); 47 var instruction_num_values: u32 = undefined; 48 switch (opcode) { 49 .Add => { 50 instruction_num_values = 4; 51 var param1 = memory[instruction_pointer + 1]; 52 var param2 = memory[instruction_pointer + 2]; 53 var param3 = memory[instruction_pointer + 3]; 54 var a = memory[param1]; 55 var b = memory[param2]; 56 var dest_address = &memory[param3]; 57 dest_address.* = a + b; 58 }, 59 .Mult => { 60 instruction_num_values = 4; 61 var param1 = memory[instruction_pointer + 1]; 62 var param2 = memory[instruction_pointer + 2]; 63 var param3 = memory[instruction_pointer + 3]; 64 var a = memory[param1]; 65 var b = memory[param2]; 66 var dest_address = &memory[param3]; 67 dest_address.* = a * b; 68 }, 69 .Term => { 70 instruction_num_values = 1; 71 break; 72 }, 73 } 74 instruction_pointer += instruction_num_values; 75 } 76 77 return memory; 78 } 79 80 test "run intcode program" { 81 var a = dbg.global_allocator; 82 dbg.assert(mem.eql(u32, try run_intcode_program(a, [_]u32{ 1, 0, 0, 0, 99 }), [_]u32{ 2, 0, 0, 0, 99 })); 83 dbg.assert(mem.eql(u32, try run_intcode_program(a, [_]u32{ 2, 3, 0, 3, 99 }), [_]u32{ 2, 3, 0, 6, 99 })); 84 dbg.assert(mem.eql(u32, try run_intcode_program(a, [_]u32{ 2, 4, 4, 5, 99, 0 }), [_]u32{ 2, 4, 4, 5, 99, 9801 })); 85 dbg.assert(mem.eql(u32, try run_intcode_program(a, [_]u32{ 1, 1, 1, 4, 99, 5, 6, 0, 99 }), [_]u32{ 30, 1, 1, 4, 2, 5, 6, 0, 99 })); 86 } 87 88 fn get_program_output(allocator: *mem.Allocator, program: []u32, noun: u32, verb: u32) !u32 { 89 program[1] = noun; 90 program[2] = verb; 91 var final_state = try run_intcode_program(allocator, program); 92 return final_state[0]; 93 } 94 95 const input = [_]u32{ 96 1, 0, 0, 3, 97 1, 1, 2, 3, 98 1, 3, 4, 3, 99 1, 5, 0, 3, 100 2, 9, 1, 19, 101 1, 19, 5, 23, 102 1, 23, 5, 27, 103 2, 27, 10, 31, 104 1, 31, 9, 35, 105 1, 35, 5, 39, 106 1, 6, 39, 43, 107 2, 9, 43, 47, 108 1, 5, 47, 51, 109 2, 6, 51, 55, 110 1, 5, 55, 59, 111 2, 10, 59, 63, 112 1, 63, 6, 67, 113 2, 67, 6, 71, 114 2, 10, 71, 75, 115 1, 6, 75, 79, 116 2, 79, 9, 83, 117 1, 83, 5, 87, 118 1, 87, 9, 91, 119 1, 91, 9, 95, 120 1, 10, 95, 99, 121 1, 99, 13, 103, 122 2, 6, 103, 107, 123 1, 107, 5, 111, 124 1, 6, 111, 115, 125 1, 9, 115, 119, 126 1, 119, 9, 123, 127 2, 123, 10, 127, 128 1, 6, 127, 131, 129 2, 131, 13, 135, 130 1, 13, 135, 139, 131 1, 9, 139, 143, 132 1, 9, 143, 147, 133 1, 147, 13, 151, 134 1, 151, 9, 155, 135 1, 155, 13, 159, 136 1, 6, 159, 163, 137 1, 13, 163, 167, 138 1, 2, 167, 171, 139 1, 171, 13, 0, 140 99, 2, 0, 14, 141 0, 142 };