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");
|
||||
|
||||
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