Finish day 8 challenge
This commit is contained in:
		
							parent
							
								
									59f432a8ef
								
							
						
					
					
						commit
						b38bd5f0ac
					
				|  | @ -0,0 +1,634 @@ | ||||||
|  | acc +15 | ||||||
|  | acc +2 | ||||||
|  | acc -14 | ||||||
|  | jmp +362 | ||||||
|  | acc +22 | ||||||
|  | nop +236 | ||||||
|  | jmp +474 | ||||||
|  | acc +10 | ||||||
|  | jmp +1 | ||||||
|  | acc +0 | ||||||
|  | jmp +236 | ||||||
|  | acc +10 | ||||||
|  | acc +14 | ||||||
|  | jmp +334 | ||||||
|  | acc +12 | ||||||
|  | acc -1 | ||||||
|  | jmp +478 | ||||||
|  | jmp +90 | ||||||
|  | jmp +208 | ||||||
|  | acc +49 | ||||||
|  | jmp +94 | ||||||
|  | acc +2 | ||||||
|  | acc -8 | ||||||
|  | jmp +375 | ||||||
|  | nop +21 | ||||||
|  | acc +0 | ||||||
|  | acc +10 | ||||||
|  | nop +25 | ||||||
|  | jmp +492 | ||||||
|  | nop +182 | ||||||
|  | acc +49 | ||||||
|  | acc -12 | ||||||
|  | jmp -14 | ||||||
|  | acc -16 | ||||||
|  | jmp +140 | ||||||
|  | acc -3 | ||||||
|  | acc -18 | ||||||
|  | acc +28 | ||||||
|  | acc -6 | ||||||
|  | jmp +558 | ||||||
|  | acc +2 | ||||||
|  | acc +27 | ||||||
|  | nop +438 | ||||||
|  | acc +41 | ||||||
|  | jmp +508 | ||||||
|  | acc +13 | ||||||
|  | jmp +117 | ||||||
|  | acc +21 | ||||||
|  | acc -13 | ||||||
|  | acc +34 | ||||||
|  | jmp +1 | ||||||
|  | jmp +1 | ||||||
|  | nop +451 | ||||||
|  | acc +28 | ||||||
|  | acc +31 | ||||||
|  | acc +31 | ||||||
|  | jmp +280 | ||||||
|  | acc +32 | ||||||
|  | acc +35 | ||||||
|  | acc -18 | ||||||
|  | jmp +509 | ||||||
|  | acc -15 | ||||||
|  | acc -8 | ||||||
|  | nop +288 | ||||||
|  | acc -16 | ||||||
|  | jmp +376 | ||||||
|  | acc -19 | ||||||
|  | acc -8 | ||||||
|  | acc +11 | ||||||
|  | acc +10 | ||||||
|  | jmp +50 | ||||||
|  | acc +19 | ||||||
|  | nop -58 | ||||||
|  | acc -9 | ||||||
|  | jmp +43 | ||||||
|  | acc +10 | ||||||
|  | acc +2 | ||||||
|  | nop -63 | ||||||
|  | jmp +280 | ||||||
|  | acc -7 | ||||||
|  | jmp +175 | ||||||
|  | jmp +69 | ||||||
|  | acc +16 | ||||||
|  | acc +9 | ||||||
|  | acc -2 | ||||||
|  | acc -5 | ||||||
|  | jmp +276 | ||||||
|  | nop +195 | ||||||
|  | acc +50 | ||||||
|  | acc -8 | ||||||
|  | jmp -55 | ||||||
|  | nop +1 | ||||||
|  | nop -78 | ||||||
|  | acc +31 | ||||||
|  | jmp +535 | ||||||
|  | acc +9 | ||||||
|  | acc +33 | ||||||
|  | acc +4 | ||||||
|  | acc +48 | ||||||
|  | jmp +8 | ||||||
|  | acc +30 | ||||||
|  | acc +42 | ||||||
|  | acc +18 | ||||||
|  | acc +37 | ||||||
|  | jmp -69 | ||||||
|  | nop +121 | ||||||
|  | jmp +44 | ||||||
|  | acc +3 | ||||||
|  | acc +33 | ||||||
|  | acc -6 | ||||||
|  | acc +37 | ||||||
|  | jmp +403 | ||||||
|  | acc -6 | ||||||
|  | jmp +245 | ||||||
|  | jmp -93 | ||||||
|  | acc +5 | ||||||
|  | jmp +406 | ||||||
|  | jmp -26 | ||||||
|  | nop -47 | ||||||
|  | jmp +239 | ||||||
|  | acc +7 | ||||||
|  | acc +31 | ||||||
|  | acc +14 | ||||||
|  | acc +0 | ||||||
|  | jmp +291 | ||||||
|  | acc +46 | ||||||
|  | jmp +394 | ||||||
|  | acc +44 | ||||||
|  | acc +36 | ||||||
|  | nop +45 | ||||||
|  | jmp +137 | ||||||
|  | acc -16 | ||||||
|  | acc +10 | ||||||
|  | acc -4 | ||||||
|  | acc +7 | ||||||
|  | jmp +76 | ||||||
|  | acc +24 | ||||||
|  | jmp +93 | ||||||
|  | acc +17 | ||||||
|  | acc +0 | ||||||
|  | acc +6 | ||||||
|  | acc +4 | ||||||
|  | jmp +385 | ||||||
|  | acc -8 | ||||||
|  | acc +49 | ||||||
|  | acc +28 | ||||||
|  | jmp +95 | ||||||
|  | nop +12 | ||||||
|  | acc +33 | ||||||
|  | jmp +153 | ||||||
|  | nop +254 | ||||||
|  | acc +18 | ||||||
|  | acc -16 | ||||||
|  | acc +50 | ||||||
|  | jmp +299 | ||||||
|  | acc +27 | ||||||
|  | acc +47 | ||||||
|  | acc -17 | ||||||
|  | jmp -15 | ||||||
|  | acc +35 | ||||||
|  | acc +14 | ||||||
|  | jmp +204 | ||||||
|  | jmp +93 | ||||||
|  | acc +46 | ||||||
|  | nop -5 | ||||||
|  | nop -158 | ||||||
|  | jmp +221 | ||||||
|  | jmp +321 | ||||||
|  | acc -2 | ||||||
|  | acc +49 | ||||||
|  | acc +3 | ||||||
|  | acc -17 | ||||||
|  | jmp -52 | ||||||
|  | jmp +7 | ||||||
|  | nop +52 | ||||||
|  | acc +25 | ||||||
|  | jmp +376 | ||||||
|  | acc -3 | ||||||
|  | nop -133 | ||||||
|  | jmp +32 | ||||||
|  | jmp +328 | ||||||
|  | nop +374 | ||||||
|  | acc +37 | ||||||
|  | acc +6 | ||||||
|  | jmp +92 | ||||||
|  | acc +47 | ||||||
|  | nop +394 | ||||||
|  | jmp -13 | ||||||
|  | jmp -170 | ||||||
|  | acc +9 | ||||||
|  | jmp -47 | ||||||
|  | acc -18 | ||||||
|  | acc +27 | ||||||
|  | jmp +1 | ||||||
|  | acc +3 | ||||||
|  | acc -5 | ||||||
|  | jmp +337 | ||||||
|  | acc +21 | ||||||
|  | jmp +364 | ||||||
|  | acc +24 | ||||||
|  | acc +43 | ||||||
|  | acc +50 | ||||||
|  | jmp +58 | ||||||
|  | jmp -18 | ||||||
|  | acc +30 | ||||||
|  | jmp +144 | ||||||
|  | nop +5 | ||||||
|  | acc +50 | ||||||
|  | nop +245 | ||||||
|  | nop +133 | ||||||
|  | jmp +270 | ||||||
|  | jmp -22 | ||||||
|  | nop -76 | ||||||
|  | jmp +398 | ||||||
|  | acc +40 | ||||||
|  | acc +30 | ||||||
|  | jmp +361 | ||||||
|  | acc +36 | ||||||
|  | acc +30 | ||||||
|  | jmp +392 | ||||||
|  | acc -17 | ||||||
|  | nop +71 | ||||||
|  | acc -12 | ||||||
|  | jmp +102 | ||||||
|  | acc +17 | ||||||
|  | jmp +283 | ||||||
|  | acc -16 | ||||||
|  | jmp +65 | ||||||
|  | nop -2 | ||||||
|  | jmp +149 | ||||||
|  | jmp -103 | ||||||
|  | jmp -179 | ||||||
|  | acc +46 | ||||||
|  | jmp +289 | ||||||
|  | acc +48 | ||||||
|  | jmp +114 | ||||||
|  | acc +13 | ||||||
|  | jmp +114 | ||||||
|  | nop +215 | ||||||
|  | nop -89 | ||||||
|  | jmp +337 | ||||||
|  | acc -2 | ||||||
|  | acc +2 | ||||||
|  | acc -7 | ||||||
|  | jmp -18 | ||||||
|  | jmp -51 | ||||||
|  | acc +30 | ||||||
|  | acc +43 | ||||||
|  | acc +28 | ||||||
|  | jmp -188 | ||||||
|  | acc +36 | ||||||
|  | acc +7 | ||||||
|  | acc -5 | ||||||
|  | acc +38 | ||||||
|  | jmp +88 | ||||||
|  | jmp +225 | ||||||
|  | acc -14 | ||||||
|  | acc -3 | ||||||
|  | acc -15 | ||||||
|  | jmp +66 | ||||||
|  | acc +7 | ||||||
|  | acc +43 | ||||||
|  | nop -210 | ||||||
|  | acc -9 | ||||||
|  | jmp +109 | ||||||
|  | acc -10 | ||||||
|  | jmp +242 | ||||||
|  | acc -5 | ||||||
|  | acc +15 | ||||||
|  | acc +8 | ||||||
|  | jmp +310 | ||||||
|  | acc +31 | ||||||
|  | acc -2 | ||||||
|  | acc +11 | ||||||
|  | acc -15 | ||||||
|  | jmp +103 | ||||||
|  | acc +32 | ||||||
|  | jmp -92 | ||||||
|  | acc -10 | ||||||
|  | acc +6 | ||||||
|  | acc -1 | ||||||
|  | jmp -131 | ||||||
|  | acc +43 | ||||||
|  | acc +30 | ||||||
|  | acc +13 | ||||||
|  | acc +33 | ||||||
|  | jmp +25 | ||||||
|  | acc +9 | ||||||
|  | acc -14 | ||||||
|  | acc +19 | ||||||
|  | acc +44 | ||||||
|  | jmp -50 | ||||||
|  | acc -8 | ||||||
|  | acc +9 | ||||||
|  | jmp +312 | ||||||
|  | jmp -96 | ||||||
|  | acc -3 | ||||||
|  | acc -3 | ||||||
|  | acc +24 | ||||||
|  | jmp +94 | ||||||
|  | acc -15 | ||||||
|  | jmp +61 | ||||||
|  | acc +19 | ||||||
|  | nop -89 | ||||||
|  | acc +24 | ||||||
|  | nop -94 | ||||||
|  | jmp +5 | ||||||
|  | acc -13 | ||||||
|  | acc +25 | ||||||
|  | acc +42 | ||||||
|  | jmp +1 | ||||||
|  | jmp +137 | ||||||
|  | acc +44 | ||||||
|  | acc +44 | ||||||
|  | acc +41 | ||||||
|  | jmp +152 | ||||||
|  | jmp +144 | ||||||
|  | acc -1 | ||||||
|  | nop +293 | ||||||
|  | jmp -120 | ||||||
|  | acc -17 | ||||||
|  | nop -171 | ||||||
|  | acc +27 | ||||||
|  | jmp -173 | ||||||
|  | jmp +231 | ||||||
|  | acc +3 | ||||||
|  | jmp +109 | ||||||
|  | acc +18 | ||||||
|  | acc +32 | ||||||
|  | acc -14 | ||||||
|  | acc -8 | ||||||
|  | jmp +177 | ||||||
|  | acc +28 | ||||||
|  | jmp -134 | ||||||
|  | nop +277 | ||||||
|  | jmp -124 | ||||||
|  | jmp +167 | ||||||
|  | nop +274 | ||||||
|  | acc +6 | ||||||
|  | acc +43 | ||||||
|  | acc +10 | ||||||
|  | jmp -320 | ||||||
|  | acc +28 | ||||||
|  | acc -9 | ||||||
|  | acc +22 | ||||||
|  | jmp -90 | ||||||
|  | jmp -203 | ||||||
|  | jmp -133 | ||||||
|  | jmp -6 | ||||||
|  | jmp -181 | ||||||
|  | jmp +170 | ||||||
|  | acc +40 | ||||||
|  | acc +5 | ||||||
|  | jmp -274 | ||||||
|  | acc +36 | ||||||
|  | acc +24 | ||||||
|  | nop +6 | ||||||
|  | jmp -339 | ||||||
|  | jmp -251 | ||||||
|  | acc +10 | ||||||
|  | acc +10 | ||||||
|  | jmp -347 | ||||||
|  | jmp +263 | ||||||
|  | acc +37 | ||||||
|  | jmp -201 | ||||||
|  | acc -11 | ||||||
|  | acc +42 | ||||||
|  | jmp +153 | ||||||
|  | nop -179 | ||||||
|  | acc -9 | ||||||
|  | jmp +8 | ||||||
|  | jmp -289 | ||||||
|  | jmp -25 | ||||||
|  | acc +45 | ||||||
|  | jmp -142 | ||||||
|  | acc +42 | ||||||
|  | acc -10 | ||||||
|  | jmp +83 | ||||||
|  | acc +43 | ||||||
|  | acc +3 | ||||||
|  | acc -6 | ||||||
|  | jmp -222 | ||||||
|  | acc +41 | ||||||
|  | acc +14 | ||||||
|  | acc +7 | ||||||
|  | acc +2 | ||||||
|  | jmp -35 | ||||||
|  | jmp +168 | ||||||
|  | acc +11 | ||||||
|  | acc +18 | ||||||
|  | acc +8 | ||||||
|  | acc -4 | ||||||
|  | jmp -203 | ||||||
|  | acc +44 | ||||||
|  | jmp +10 | ||||||
|  | nop -184 | ||||||
|  | acc +0 | ||||||
|  | jmp +91 | ||||||
|  | acc -5 | ||||||
|  | nop +226 | ||||||
|  | acc +46 | ||||||
|  | acc -10 | ||||||
|  | jmp -15 | ||||||
|  | jmp -321 | ||||||
|  | acc +0 | ||||||
|  | acc +33 | ||||||
|  | jmp +82 | ||||||
|  | jmp +1 | ||||||
|  | acc -12 | ||||||
|  | acc +30 | ||||||
|  | jmp +152 | ||||||
|  | acc +6 | ||||||
|  | jmp -208 | ||||||
|  | acc +43 | ||||||
|  | jmp +39 | ||||||
|  | acc +23 | ||||||
|  | acc +23 | ||||||
|  | acc +24 | ||||||
|  | acc +26 | ||||||
|  | jmp -390 | ||||||
|  | acc +15 | ||||||
|  | acc +3 | ||||||
|  | acc +14 | ||||||
|  | acc +46 | ||||||
|  | jmp -239 | ||||||
|  | acc -10 | ||||||
|  | acc +19 | ||||||
|  | jmp +167 | ||||||
|  | acc +46 | ||||||
|  | acc +0 | ||||||
|  | jmp -280 | ||||||
|  | acc -7 | ||||||
|  | jmp -107 | ||||||
|  | acc +13 | ||||||
|  | jmp -76 | ||||||
|  | acc +48 | ||||||
|  | jmp -65 | ||||||
|  | nop +23 | ||||||
|  | nop -89 | ||||||
|  | acc +47 | ||||||
|  | jmp -304 | ||||||
|  | acc -5 | ||||||
|  | jmp +1 | ||||||
|  | acc +50 | ||||||
|  | acc +37 | ||||||
|  | jmp -129 | ||||||
|  | acc +27 | ||||||
|  | jmp +1 | ||||||
|  | jmp -212 | ||||||
|  | acc +18 | ||||||
|  | acc +29 | ||||||
|  | acc +1 | ||||||
|  | jmp -74 | ||||||
|  | acc +24 | ||||||
|  | acc -12 | ||||||
|  | jmp -173 | ||||||
|  | acc -18 | ||||||
|  | acc -6 | ||||||
|  | nop -156 | ||||||
|  | jmp -309 | ||||||
|  | acc +46 | ||||||
|  | acc -13 | ||||||
|  | acc +41 | ||||||
|  | acc +11 | ||||||
|  | jmp -188 | ||||||
|  | acc +32 | ||||||
|  | jmp -190 | ||||||
|  | acc +31 | ||||||
|  | acc +30 | ||||||
|  | jmp -122 | ||||||
|  | acc -7 | ||||||
|  | jmp +37 | ||||||
|  | acc +2 | ||||||
|  | acc +16 | ||||||
|  | acc +45 | ||||||
|  | acc +44 | ||||||
|  | jmp -376 | ||||||
|  | acc +47 | ||||||
|  | jmp +1 | ||||||
|  | jmp -147 | ||||||
|  | acc +47 | ||||||
|  | acc -18 | ||||||
|  | acc -1 | ||||||
|  | acc +2 | ||||||
|  | jmp -152 | ||||||
|  | acc +12 | ||||||
|  | acc -8 | ||||||
|  | jmp +90 | ||||||
|  | nop +67 | ||||||
|  | acc +9 | ||||||
|  | jmp +1 | ||||||
|  | jmp -377 | ||||||
|  | jmp +1 | ||||||
|  | jmp -238 | ||||||
|  | jmp +1 | ||||||
|  | acc +47 | ||||||
|  | acc +7 | ||||||
|  | acc +31 | ||||||
|  | jmp -427 | ||||||
|  | acc +10 | ||||||
|  | acc +13 | ||||||
|  | nop +13 | ||||||
|  | jmp -8 | ||||||
|  | nop -292 | ||||||
|  | acc +11 | ||||||
|  | nop -203 | ||||||
|  | jmp -164 | ||||||
|  | jmp -19 | ||||||
|  | acc +31 | ||||||
|  | jmp -289 | ||||||
|  | acc -7 | ||||||
|  | acc -16 | ||||||
|  | acc +35 | ||||||
|  | jmp -333 | ||||||
|  | jmp -500 | ||||||
|  | acc +32 | ||||||
|  | acc +29 | ||||||
|  | acc +18 | ||||||
|  | acc +14 | ||||||
|  | jmp -161 | ||||||
|  | jmp -60 | ||||||
|  | jmp +6 | ||||||
|  | acc +4 | ||||||
|  | nop -108 | ||||||
|  | acc +27 | ||||||
|  | jmp +2 | ||||||
|  | jmp -133 | ||||||
|  | acc +2 | ||||||
|  | jmp -103 | ||||||
|  | acc +40 | ||||||
|  | nop -512 | ||||||
|  | acc +48 | ||||||
|  | jmp -196 | ||||||
|  | acc +47 | ||||||
|  | acc +40 | ||||||
|  | nop -346 | ||||||
|  | acc -2 | ||||||
|  | jmp -530 | ||||||
|  | acc +17 | ||||||
|  | nop -31 | ||||||
|  | acc +1 | ||||||
|  | jmp -74 | ||||||
|  | acc -15 | ||||||
|  | acc +4 | ||||||
|  | nop -330 | ||||||
|  | acc +32 | ||||||
|  | jmp -115 | ||||||
|  | acc -3 | ||||||
|  | jmp +1 | ||||||
|  | acc +14 | ||||||
|  | acc +31 | ||||||
|  | jmp -352 | ||||||
|  | jmp -10 | ||||||
|  | acc +18 | ||||||
|  | jmp -322 | ||||||
|  | acc +41 | ||||||
|  | jmp +59 | ||||||
|  | acc -16 | ||||||
|  | nop -359 | ||||||
|  | acc +29 | ||||||
|  | acc +26 | ||||||
|  | jmp -418 | ||||||
|  | acc +10 | ||||||
|  | acc +47 | ||||||
|  | jmp -519 | ||||||
|  | acc -5 | ||||||
|  | nop +40 | ||||||
|  | acc +30 | ||||||
|  | jmp -195 | ||||||
|  | acc +31 | ||||||
|  | acc +3 | ||||||
|  | acc +8 | ||||||
|  | jmp -10 | ||||||
|  | acc -12 | ||||||
|  | acc +21 | ||||||
|  | acc -1 | ||||||
|  | jmp +30 | ||||||
|  | jmp -341 | ||||||
|  | acc -5 | ||||||
|  | jmp -405 | ||||||
|  | acc -13 | ||||||
|  | jmp -170 | ||||||
|  | acc +24 | ||||||
|  | acc -16 | ||||||
|  | acc +20 | ||||||
|  | acc +17 | ||||||
|  | jmp -145 | ||||||
|  | acc +42 | ||||||
|  | acc +33 | ||||||
|  | jmp -395 | ||||||
|  | nop -142 | ||||||
|  | acc +45 | ||||||
|  | acc +15 | ||||||
|  | jmp -399 | ||||||
|  | nop -223 | ||||||
|  | jmp -299 | ||||||
|  | jmp -453 | ||||||
|  | acc -6 | ||||||
|  | nop -498 | ||||||
|  | acc +42 | ||||||
|  | jmp -112 | ||||||
|  | acc +39 | ||||||
|  | acc +46 | ||||||
|  | acc +4 | ||||||
|  | acc +27 | ||||||
|  | jmp -234 | ||||||
|  | jmp +1 | ||||||
|  | acc +45 | ||||||
|  | acc +47 | ||||||
|  | jmp -307 | ||||||
|  | jmp -378 | ||||||
|  | jmp -431 | ||||||
|  | acc +13 | ||||||
|  | acc +29 | ||||||
|  | jmp -282 | ||||||
|  | acc +4 | ||||||
|  | acc -3 | ||||||
|  | acc +37 | ||||||
|  | acc +40 | ||||||
|  | jmp -32 | ||||||
|  | nop -148 | ||||||
|  | acc +38 | ||||||
|  | acc +40 | ||||||
|  | acc +18 | ||||||
|  | jmp -171 | ||||||
|  | nop -546 | ||||||
|  | jmp -490 | ||||||
|  | acc +36 | ||||||
|  | jmp -514 | ||||||
|  | acc +27 | ||||||
|  | acc -10 | ||||||
|  | nop -560 | ||||||
|  | acc +44 | ||||||
|  | jmp +1 | ||||||
|  | @ -1,5 +1,222 @@ | ||||||
| const std = @import("std"); | const std = @import("std"); | ||||||
| 
 | 
 | ||||||
| pub fn main() anyerror!void { | pub fn main() anyerror!void { | ||||||
|     std.log.info("All your codebase are belong to us.", .{}); |     var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); | ||||||
|  |     defer arena.deinit(); | ||||||
|  |     var gpa = &arena.allocator; | ||||||
|  | 
 | ||||||
|  |     var program = try Program.init(gpa); | ||||||
|  |     defer program.*.deinit(); | ||||||
|  | 
 | ||||||
|  |     var f = try std.fs.cwd().openFile("input", .{}); | ||||||
|  |     var contents = try f.readToEndAlloc(gpa, std.math.maxInt(u32)); | ||||||
|  |     var it = std.mem.tokenize(contents, "\n"); | ||||||
|  |     while (it.next()) |line| { | ||||||
|  |         var s = try Statement.from_string(line); | ||||||
|  |         try program.code.append(s); | ||||||
|  |     } | ||||||
|  |     std.log.debug("Loaded program with {} statements", .{program.code.items.len}); | ||||||
|  |     _ = try program.run(); | ||||||
|  | 
 | ||||||
|  |     // Part 2 | ||||||
|  |     // Exactly one nop should be a jmp or a jmp a noop | ||||||
|  |     var i : usize = 0; | ||||||
|  |     while (i < program.code.items.len) : (i += 1) { | ||||||
|  |         if (program.code.items[i].op == .acc) { | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         // Mutate | ||||||
|  |         program.code.items[i].op = switch(program.code.items[i].op) { | ||||||
|  |             .acc => Operation.acc, | ||||||
|  |             .jmp => Operation.nop, | ||||||
|  |             .nop => Operation.jmp, | ||||||
|  |         }; | ||||||
|  |         // Test | ||||||
|  |         var run_ok = program.run() catch false; | ||||||
|  |         // Undo mutation | ||||||
|  |         program.code.items[i].op = switch(program.code.items[i].op) { | ||||||
|  |             .acc => Operation.acc, | ||||||
|  |             .jmp => Operation.nop, | ||||||
|  |             .nop => Operation.jmp, | ||||||
|  |         }; | ||||||
|  |         if (run_ok) { | ||||||
|  |             std.log.info("By changing statement {}, the program exited okay", .{i}); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub const Operation = enum { | ||||||
|  |     nop, | ||||||
|  |     acc, | ||||||
|  |     jmp | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | pub const ParseError = error { | ||||||
|  |     UnknownStatement, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | pub const Statement = struct { | ||||||
|  |     op: Operation, | ||||||
|  |     arg: i32, | ||||||
|  | 
 | ||||||
|  |     /// Modifies acc and returns the offset for the next operation | ||||||
|  |     pub fn execute(self: *Statement, acc: *i32) i32 { | ||||||
|  |         var delta : i32 = switch (self.op) { | ||||||
|  |             .nop => 1, | ||||||
|  |             .jmp => self.arg, | ||||||
|  |             .acc => 1, | ||||||
|  |         }; | ||||||
|  |         if (self.op == .acc) { | ||||||
|  |             acc.* += self.arg; | ||||||
|  |         } | ||||||
|  |         return delta; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn from_string(line: []const u8) !Statement { | ||||||
|  |         var arg : i32 = 0; | ||||||
|  |         var op : Operation = undefined; | ||||||
|  | 
 | ||||||
|  |         var it = std.mem.tokenize(line, " "); | ||||||
|  |         if (it.next()) |l| { | ||||||
|  |             if (std.mem.eql(u8, l, "nop")) { | ||||||
|  |                 op = Operation.nop; | ||||||
|  |             } | ||||||
|  |             else if (std.mem.eql(u8, l, "acc")) { | ||||||
|  |                 op = Operation.acc; | ||||||
|  |             } | ||||||
|  |             else if (std.mem.eql(u8, l, "jmp")) { | ||||||
|  |                 op = Operation.jmp; | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 std.log.err("Unknown statement: '{}'", .{l}); | ||||||
|  |                 return ParseError.UnknownStatement; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             // Error, and operator is required | ||||||
|  |             unreachable; | ||||||
|  |         } | ||||||
|  |         if (it.next()) |l| { | ||||||
|  |             arg = atoi(l); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             // Error, we need an arg | ||||||
|  |             unreachable; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         while(it.next()) |l| { | ||||||
|  |             // Error, there shouldn't be anything else on the line | ||||||
|  |             unreachable; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return Statement { | ||||||
|  |             .op = op, | ||||||
|  |             .arg = arg, | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | pub const Program = struct { | ||||||
|  |     code: std.ArrayList(Statement), | ||||||
|  |     allocator: *std.mem.Allocator, | ||||||
|  |     accumulator: i32 = 0, | ||||||
|  | 
 | ||||||
|  |     pub fn init(a: *std.mem.Allocator) !*Program { | ||||||
|  |         const self = try a.create(Program); | ||||||
|  |         errdefer a.destroy(self); | ||||||
|  | 
 | ||||||
|  |         self.* = Program { | ||||||
|  |             .code = std.ArrayList(Statement).init(a), | ||||||
|  |             .allocator = a, | ||||||
|  |         }; | ||||||
|  |         return self; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn deinit(self: *Program) void { | ||||||
|  |         self.code.deinit(); | ||||||
|  |         self.allocator.destroy(self); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn run(self: *Program) !bool { | ||||||
|  |         self.accumulator = 0; | ||||||
|  |         var next_statement_index : usize = 0; | ||||||
|  |         // Statement counter | ||||||
|  |         var map = std.hash_map.AutoHashMap(usize, u32).init(self.allocator); | ||||||
|  |         defer map.deinit(); | ||||||
|  | 
 | ||||||
|  |         var ended_ok = false; | ||||||
|  |         while (true) { | ||||||
|  |             // Check if we have already exectured this index | ||||||
|  |             var n_accumulator : i32 = self.accumulator; | ||||||
|  |             if (map.contains(next_statement_index)) { | ||||||
|  |                 std.log.warn("Infinite loop detected. Statement {} would have run twice", | ||||||
|  |                              .{next_statement_index}); | ||||||
|  |                 std.log.warn("Acc value at break: {}", .{self.accumulator}); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 try map.put(next_statement_index, 1); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var delta = self.code.items[next_statement_index].execute(&n_accumulator); | ||||||
|  |             //std.log.debug("Before {}, After {} [statement {} new offset {}] {}", | ||||||
|  |             //              .{self.accumulator, n_accumulator, next_statement_index, | ||||||
|  |             //                delta, self.code.items[next_statement_index]}); | ||||||
|  |             if (delta < 0) { | ||||||
|  |                 next_statement_index -= @intCast(usize, try std.math.absInt(delta)); | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 next_statement_index += @intCast(usize, delta); | ||||||
|  |             } | ||||||
|  |             std.debug.assert(next_statement_index >= 0); | ||||||
|  |             if (next_statement_index >= self.code.items.len) { | ||||||
|  |                 std.log.warn("Reached end of code, or jumping past end ({}, {} statements).", | ||||||
|  |                              .{next_statement_index, self.code.items.len}); | ||||||
|  |                 std.log.warn("Acc value at end: {}", .{self.accumulator}); | ||||||
|  |                 ended_ok = true; // maybe... | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             self.accumulator = n_accumulator; | ||||||
|  |         } | ||||||
|  |         return ended_ok; | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | fn atoi(a: []const u8) i32 { | ||||||
|  |     var i : i32 = 0; | ||||||
|  |     var mul : i32 = 1; | ||||||
|  |     var start : usize = 0; | ||||||
|  |     if (a[0] == '-' or a[0] == '+') { | ||||||
|  |         start = 1; | ||||||
|  |         if (a[0] == '-') { | ||||||
|  |             mul *= -1; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     for(a[start..]) |v, k| { | ||||||
|  |         if (! std.ascii.isDigit(v)) { | ||||||
|  |             std.log.warn("Byte {x} is not a digit", .{v}); | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         // 48 is '0' in ascii | ||||||
|  |         std.debug.assert(v >= 48 and v < 58); | ||||||
|  |         i += @as(i32, @as(i32, (v - 48)) * std.math.pow(i32, 10, @intCast(i32, a.len - k - 1 - start))); | ||||||
|  |     } | ||||||
|  |     //std.log.debug("{x} --> {}", .{a, i}); | ||||||
|  |     return i * mul; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | test "atoi_regular" { | ||||||
|  |     var i = atoi("1234"); | ||||||
|  |     std.testing.expectEqual(i, 1234); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | test "atoi_pos" { | ||||||
|  |     var i = atoi("+1234"); | ||||||
|  |     std.testing.expectEqual(i, 1234); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | test "atoi_neg" { | ||||||
|  |     var i = atoi("-1234"); | ||||||
|  |     std.testing.expectEqual(i, -1234); | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue