A Day 8 solution I'm pretty happy with.
This commit is contained in:
641
inputs/day8.txt
Normal file
641
inputs/day8.txt
Normal file
@@ -0,0 +1,641 @@
|
|||||||
|
acc -8
|
||||||
|
acc +19
|
||||||
|
nop +178
|
||||||
|
jmp +493
|
||||||
|
acc +7
|
||||||
|
jmp +267
|
||||||
|
jmp +604
|
||||||
|
acc +30
|
||||||
|
acc +11
|
||||||
|
acc -17
|
||||||
|
nop +402
|
||||||
|
jmp +81
|
||||||
|
acc +20
|
||||||
|
acc +19
|
||||||
|
acc +36
|
||||||
|
jmp +6
|
||||||
|
acc +43
|
||||||
|
acc +6
|
||||||
|
acc +10
|
||||||
|
nop +326
|
||||||
|
jmp +228
|
||||||
|
nop +371
|
||||||
|
acc +49
|
||||||
|
nop +140
|
||||||
|
acc -11
|
||||||
|
jmp +3
|
||||||
|
nop +366
|
||||||
|
jmp +74
|
||||||
|
nop +229
|
||||||
|
jmp +554
|
||||||
|
acc +12
|
||||||
|
acc +6
|
||||||
|
jmp +163
|
||||||
|
acc +43
|
||||||
|
acc +23
|
||||||
|
jmp +310
|
||||||
|
acc -6
|
||||||
|
nop +341
|
||||||
|
acc +50
|
||||||
|
acc +44
|
||||||
|
jmp +378
|
||||||
|
acc +28
|
||||||
|
acc +29
|
||||||
|
nop +76
|
||||||
|
jmp +136
|
||||||
|
nop +445
|
||||||
|
acc +27
|
||||||
|
acc -8
|
||||||
|
acc +34
|
||||||
|
jmp +199
|
||||||
|
acc +39
|
||||||
|
acc +25
|
||||||
|
acc -14
|
||||||
|
acc +1
|
||||||
|
jmp +189
|
||||||
|
acc +2
|
||||||
|
acc -9
|
||||||
|
jmp -7
|
||||||
|
acc +28
|
||||||
|
acc +28
|
||||||
|
jmp +458
|
||||||
|
jmp +1
|
||||||
|
nop +299
|
||||||
|
jmp +427
|
||||||
|
acc +10
|
||||||
|
acc +32
|
||||||
|
jmp +340
|
||||||
|
acc +26
|
||||||
|
jmp +563
|
||||||
|
jmp +1
|
||||||
|
acc +9
|
||||||
|
jmp +42
|
||||||
|
acc +4
|
||||||
|
jmp +468
|
||||||
|
acc +1
|
||||||
|
acc +3
|
||||||
|
jmp +258
|
||||||
|
acc +29
|
||||||
|
acc +7
|
||||||
|
acc -5
|
||||||
|
jmp +288
|
||||||
|
acc +22
|
||||||
|
acc +32
|
||||||
|
acc -6
|
||||||
|
jmp +173
|
||||||
|
acc +48
|
||||||
|
acc +42
|
||||||
|
acc +26
|
||||||
|
jmp +380
|
||||||
|
jmp +126
|
||||||
|
acc +45
|
||||||
|
jmp -27
|
||||||
|
acc +50
|
||||||
|
jmp +14
|
||||||
|
jmp +472
|
||||||
|
acc -19
|
||||||
|
jmp +363
|
||||||
|
acc +19
|
||||||
|
acc -8
|
||||||
|
acc +25
|
||||||
|
jmp +450
|
||||||
|
acc -7
|
||||||
|
acc +27
|
||||||
|
acc +44
|
||||||
|
acc +17
|
||||||
|
jmp +487
|
||||||
|
jmp +89
|
||||||
|
nop +216
|
||||||
|
nop +345
|
||||||
|
acc -1
|
||||||
|
acc +37
|
||||||
|
jmp +455
|
||||||
|
jmp +294
|
||||||
|
acc +20
|
||||||
|
acc +38
|
||||||
|
jmp +419
|
||||||
|
acc +17
|
||||||
|
acc +17
|
||||||
|
jmp +125
|
||||||
|
jmp +81
|
||||||
|
acc +37
|
||||||
|
acc -8
|
||||||
|
acc +9
|
||||||
|
acc +31
|
||||||
|
jmp +218
|
||||||
|
acc +24
|
||||||
|
acc +28
|
||||||
|
acc -4
|
||||||
|
acc -12
|
||||||
|
jmp -40
|
||||||
|
acc +40
|
||||||
|
nop +359
|
||||||
|
nop +182
|
||||||
|
nop +306
|
||||||
|
jmp +296
|
||||||
|
acc -8
|
||||||
|
jmp +1
|
||||||
|
nop +43
|
||||||
|
acc -14
|
||||||
|
jmp +239
|
||||||
|
acc +13
|
||||||
|
acc +10
|
||||||
|
jmp +1
|
||||||
|
jmp -36
|
||||||
|
acc -16
|
||||||
|
acc +2
|
||||||
|
jmp +344
|
||||||
|
jmp +442
|
||||||
|
acc +35
|
||||||
|
acc +2
|
||||||
|
acc +27
|
||||||
|
acc +17
|
||||||
|
jmp -27
|
||||||
|
nop +478
|
||||||
|
acc +6
|
||||||
|
acc +7
|
||||||
|
jmp +454
|
||||||
|
nop -145
|
||||||
|
acc +20
|
||||||
|
acc -6
|
||||||
|
jmp +182
|
||||||
|
nop +251
|
||||||
|
jmp -37
|
||||||
|
acc +26
|
||||||
|
jmp +300
|
||||||
|
acc +29
|
||||||
|
acc +44
|
||||||
|
acc +32
|
||||||
|
nop +56
|
||||||
|
jmp +31
|
||||||
|
acc -16
|
||||||
|
jmp +53
|
||||||
|
acc -9
|
||||||
|
jmp +84
|
||||||
|
jmp +1
|
||||||
|
nop +30
|
||||||
|
acc -15
|
||||||
|
jmp +262
|
||||||
|
acc -19
|
||||||
|
jmp +163
|
||||||
|
jmp +441
|
||||||
|
acc +27
|
||||||
|
jmp +449
|
||||||
|
acc +42
|
||||||
|
acc +45
|
||||||
|
acc +21
|
||||||
|
acc +22
|
||||||
|
jmp +338
|
||||||
|
acc +24
|
||||||
|
jmp +301
|
||||||
|
acc +42
|
||||||
|
acc +42
|
||||||
|
acc +26
|
||||||
|
jmp +348
|
||||||
|
jmp +361
|
||||||
|
acc -5
|
||||||
|
acc -19
|
||||||
|
acc +4
|
||||||
|
jmp -117
|
||||||
|
jmp +254
|
||||||
|
jmp +1
|
||||||
|
acc +47
|
||||||
|
acc -3
|
||||||
|
jmp +271
|
||||||
|
jmp +388
|
||||||
|
acc +2
|
||||||
|
acc -17
|
||||||
|
acc +37
|
||||||
|
jmp -73
|
||||||
|
acc +37
|
||||||
|
acc +34
|
||||||
|
jmp +1
|
||||||
|
jmp -148
|
||||||
|
jmp -56
|
||||||
|
jmp +103
|
||||||
|
acc -5
|
||||||
|
acc +23
|
||||||
|
acc +3
|
||||||
|
jmp +405
|
||||||
|
nop +255
|
||||||
|
acc +14
|
||||||
|
nop -41
|
||||||
|
acc +12
|
||||||
|
jmp +94
|
||||||
|
acc +22
|
||||||
|
acc +30
|
||||||
|
jmp -107
|
||||||
|
acc +12
|
||||||
|
acc -2
|
||||||
|
jmp +65
|
||||||
|
acc +35
|
||||||
|
acc -4
|
||||||
|
jmp -174
|
||||||
|
nop -159
|
||||||
|
acc +47
|
||||||
|
jmp -52
|
||||||
|
acc +35
|
||||||
|
jmp +73
|
||||||
|
acc +1
|
||||||
|
acc +19
|
||||||
|
acc +35
|
||||||
|
acc +15
|
||||||
|
jmp -59
|
||||||
|
jmp +312
|
||||||
|
acc +20
|
||||||
|
acc +25
|
||||||
|
acc +45
|
||||||
|
jmp -4
|
||||||
|
acc -4
|
||||||
|
nop -160
|
||||||
|
acc -8
|
||||||
|
acc +31
|
||||||
|
jmp +166
|
||||||
|
acc +20
|
||||||
|
acc +16
|
||||||
|
acc -1
|
||||||
|
jmp +234
|
||||||
|
acc +0
|
||||||
|
jmp -45
|
||||||
|
acc +47
|
||||||
|
acc +17
|
||||||
|
nop -187
|
||||||
|
nop +206
|
||||||
|
jmp +17
|
||||||
|
acc +36
|
||||||
|
acc +0
|
||||||
|
acc +7
|
||||||
|
jmp +263
|
||||||
|
acc +32
|
||||||
|
acc -6
|
||||||
|
nop +35
|
||||||
|
jmp -101
|
||||||
|
acc +49
|
||||||
|
nop -60
|
||||||
|
jmp +118
|
||||||
|
acc -1
|
||||||
|
acc -7
|
||||||
|
nop -94
|
||||||
|
acc +21
|
||||||
|
jmp +82
|
||||||
|
nop +216
|
||||||
|
acc +5
|
||||||
|
nop -99
|
||||||
|
jmp -47
|
||||||
|
acc +31
|
||||||
|
acc +2
|
||||||
|
acc +26
|
||||||
|
acc +27
|
||||||
|
jmp -224
|
||||||
|
acc +15
|
||||||
|
acc +48
|
||||||
|
jmp +220
|
||||||
|
nop +152
|
||||||
|
jmp -69
|
||||||
|
acc +4
|
||||||
|
acc +24
|
||||||
|
jmp +200
|
||||||
|
acc +14
|
||||||
|
jmp +126
|
||||||
|
acc +48
|
||||||
|
acc +47
|
||||||
|
acc +10
|
||||||
|
jmp +26
|
||||||
|
acc +16
|
||||||
|
jmp -203
|
||||||
|
acc +21
|
||||||
|
jmp -158
|
||||||
|
acc -15
|
||||||
|
acc -13
|
||||||
|
jmp -94
|
||||||
|
jmp -136
|
||||||
|
nop -247
|
||||||
|
acc +16
|
||||||
|
jmp -130
|
||||||
|
acc +31
|
||||||
|
jmp +115
|
||||||
|
jmp -159
|
||||||
|
acc +7
|
||||||
|
acc +50
|
||||||
|
jmp +52
|
||||||
|
acc +22
|
||||||
|
acc +26
|
||||||
|
jmp +249
|
||||||
|
acc -18
|
||||||
|
jmp +1
|
||||||
|
jmp -251
|
||||||
|
nop +254
|
||||||
|
jmp -127
|
||||||
|
acc +37
|
||||||
|
jmp -93
|
||||||
|
nop +73
|
||||||
|
acc +11
|
||||||
|
acc +36
|
||||||
|
jmp +277
|
||||||
|
acc +29
|
||||||
|
acc +16
|
||||||
|
jmp -88
|
||||||
|
nop +8
|
||||||
|
acc +18
|
||||||
|
acc +47
|
||||||
|
acc -9
|
||||||
|
jmp +184
|
||||||
|
jmp -142
|
||||||
|
acc +50
|
||||||
|
jmp +287
|
||||||
|
jmp -250
|
||||||
|
jmp -296
|
||||||
|
jmp -83
|
||||||
|
acc +13
|
||||||
|
acc +29
|
||||||
|
acc +28
|
||||||
|
acc +16
|
||||||
|
jmp +40
|
||||||
|
acc +33
|
||||||
|
acc -13
|
||||||
|
jmp +43
|
||||||
|
nop +275
|
||||||
|
acc +24
|
||||||
|
nop -257
|
||||||
|
nop -65
|
||||||
|
jmp -112
|
||||||
|
acc +4
|
||||||
|
acc +38
|
||||||
|
jmp -193
|
||||||
|
jmp +1
|
||||||
|
acc -18
|
||||||
|
acc +15
|
||||||
|
jmp -223
|
||||||
|
acc -18
|
||||||
|
jmp -55
|
||||||
|
jmp -207
|
||||||
|
acc -6
|
||||||
|
jmp -215
|
||||||
|
acc +16
|
||||||
|
acc +44
|
||||||
|
jmp +1
|
||||||
|
acc +47
|
||||||
|
jmp -35
|
||||||
|
acc +47
|
||||||
|
acc +47
|
||||||
|
acc +35
|
||||||
|
jmp +144
|
||||||
|
jmp +1
|
||||||
|
acc +45
|
||||||
|
acc +25
|
||||||
|
jmp -293
|
||||||
|
acc +32
|
||||||
|
jmp -381
|
||||||
|
nop +65
|
||||||
|
jmp +1
|
||||||
|
acc +2
|
||||||
|
jmp -74
|
||||||
|
acc -13
|
||||||
|
acc -9
|
||||||
|
acc +4
|
||||||
|
jmp -251
|
||||||
|
jmp +1
|
||||||
|
jmp +71
|
||||||
|
acc -12
|
||||||
|
acc +7
|
||||||
|
acc +15
|
||||||
|
jmp +11
|
||||||
|
jmp -68
|
||||||
|
acc +33
|
||||||
|
jmp -330
|
||||||
|
jmp +48
|
||||||
|
acc -15
|
||||||
|
acc -11
|
||||||
|
jmp +97
|
||||||
|
acc -9
|
||||||
|
acc -10
|
||||||
|
jmp +100
|
||||||
|
acc +29
|
||||||
|
acc +21
|
||||||
|
jmp -134
|
||||||
|
acc -18
|
||||||
|
acc +38
|
||||||
|
jmp +67
|
||||||
|
jmp -12
|
||||||
|
acc +27
|
||||||
|
acc +26
|
||||||
|
acc -8
|
||||||
|
acc -2
|
||||||
|
jmp -124
|
||||||
|
jmp +165
|
||||||
|
nop -245
|
||||||
|
acc -16
|
||||||
|
acc +25
|
||||||
|
acc -19
|
||||||
|
jmp -328
|
||||||
|
nop -182
|
||||||
|
acc -7
|
||||||
|
acc +46
|
||||||
|
jmp -250
|
||||||
|
acc +45
|
||||||
|
acc -7
|
||||||
|
nop -256
|
||||||
|
acc -2
|
||||||
|
jmp +21
|
||||||
|
acc +21
|
||||||
|
acc +37
|
||||||
|
jmp +156
|
||||||
|
nop +32
|
||||||
|
jmp -195
|
||||||
|
nop -355
|
||||||
|
acc -14
|
||||||
|
nop -302
|
||||||
|
acc +48
|
||||||
|
jmp -407
|
||||||
|
acc +50
|
||||||
|
acc -9
|
||||||
|
acc +47
|
||||||
|
jmp -110
|
||||||
|
acc +31
|
||||||
|
acc +37
|
||||||
|
acc +15
|
||||||
|
jmp -162
|
||||||
|
acc -14
|
||||||
|
jmp -437
|
||||||
|
acc +44
|
||||||
|
jmp +1
|
||||||
|
acc +24
|
||||||
|
jmp -139
|
||||||
|
jmp -362
|
||||||
|
acc +40
|
||||||
|
jmp -41
|
||||||
|
acc +38
|
||||||
|
jmp -231
|
||||||
|
acc +31
|
||||||
|
acc +23
|
||||||
|
jmp +135
|
||||||
|
acc -19
|
||||||
|
acc +15
|
||||||
|
jmp +148
|
||||||
|
acc +16
|
||||||
|
acc -18
|
||||||
|
acc -3
|
||||||
|
acc +1
|
||||||
|
jmp -189
|
||||||
|
acc -12
|
||||||
|
acc -6
|
||||||
|
acc -18
|
||||||
|
nop -454
|
||||||
|
jmp +83
|
||||||
|
nop -190
|
||||||
|
jmp -17
|
||||||
|
acc -7
|
||||||
|
acc +34
|
||||||
|
acc -1
|
||||||
|
jmp +94
|
||||||
|
acc +42
|
||||||
|
jmp +34
|
||||||
|
nop -150
|
||||||
|
nop +90
|
||||||
|
nop -126
|
||||||
|
jmp -161
|
||||||
|
acc +5
|
||||||
|
acc +11
|
||||||
|
acc +20
|
||||||
|
acc +38
|
||||||
|
jmp -97
|
||||||
|
acc +49
|
||||||
|
acc +29
|
||||||
|
acc +26
|
||||||
|
jmp -36
|
||||||
|
acc +4
|
||||||
|
acc -14
|
||||||
|
acc +30
|
||||||
|
acc +42
|
||||||
|
jmp -192
|
||||||
|
jmp -336
|
||||||
|
acc +34
|
||||||
|
acc +31
|
||||||
|
acc +2
|
||||||
|
acc +33
|
||||||
|
jmp +65
|
||||||
|
acc +4
|
||||||
|
jmp -459
|
||||||
|
nop -399
|
||||||
|
acc -6
|
||||||
|
nop -256
|
||||||
|
jmp -420
|
||||||
|
acc -12
|
||||||
|
acc -17
|
||||||
|
jmp -276
|
||||||
|
acc +45
|
||||||
|
acc +40
|
||||||
|
jmp -180
|
||||||
|
acc +50
|
||||||
|
jmp -501
|
||||||
|
acc +17
|
||||||
|
jmp -232
|
||||||
|
acc +12
|
||||||
|
jmp -109
|
||||||
|
nop -291
|
||||||
|
nop -345
|
||||||
|
jmp +100
|
||||||
|
acc +36
|
||||||
|
acc +2
|
||||||
|
acc -2
|
||||||
|
jmp +1
|
||||||
|
acc +23
|
||||||
|
nop -299
|
||||||
|
acc +24
|
||||||
|
acc +30
|
||||||
|
jmp -476
|
||||||
|
acc +0
|
||||||
|
acc +6
|
||||||
|
acc +49
|
||||||
|
jmp +6
|
||||||
|
nop -461
|
||||||
|
jmp -539
|
||||||
|
nop -62
|
||||||
|
acc +48
|
||||||
|
jmp -526
|
||||||
|
jmp -365
|
||||||
|
acc +47
|
||||||
|
acc +10
|
||||||
|
acc +32
|
||||||
|
jmp -490
|
||||||
|
nop -148
|
||||||
|
acc +42
|
||||||
|
acc +5
|
||||||
|
jmp -358
|
||||||
|
acc -5
|
||||||
|
jmp -101
|
||||||
|
jmp -502
|
||||||
|
acc +15
|
||||||
|
acc +45
|
||||||
|
nop -399
|
||||||
|
jmp +1
|
||||||
|
acc +31
|
||||||
|
acc +47
|
||||||
|
acc +49
|
||||||
|
jmp -269
|
||||||
|
acc +6
|
||||||
|
acc +45
|
||||||
|
acc -8
|
||||||
|
acc -6
|
||||||
|
jmp +36
|
||||||
|
jmp +51
|
||||||
|
acc +39
|
||||||
|
jmp -64
|
||||||
|
acc +47
|
||||||
|
jmp +1
|
||||||
|
acc -8
|
||||||
|
jmp -102
|
||||||
|
acc -8
|
||||||
|
jmp -202
|
||||||
|
jmp -18
|
||||||
|
acc +1
|
||||||
|
jmp -484
|
||||||
|
acc +35
|
||||||
|
acc +30
|
||||||
|
acc +49
|
||||||
|
jmp -562
|
||||||
|
jmp -515
|
||||||
|
acc -13
|
||||||
|
nop -6
|
||||||
|
jmp -369
|
||||||
|
acc +27
|
||||||
|
acc +18
|
||||||
|
nop -477
|
||||||
|
acc -10
|
||||||
|
jmp -430
|
||||||
|
jmp +1
|
||||||
|
acc +7
|
||||||
|
nop -111
|
||||||
|
jmp -445
|
||||||
|
jmp +12
|
||||||
|
jmp -50
|
||||||
|
acc +7
|
||||||
|
acc +3
|
||||||
|
nop -433
|
||||||
|
jmp -390
|
||||||
|
acc -5
|
||||||
|
acc +50
|
||||||
|
jmp -67
|
||||||
|
acc +45
|
||||||
|
acc -10
|
||||||
|
jmp -446
|
||||||
|
jmp -496
|
||||||
|
jmp -17
|
||||||
|
acc +14
|
||||||
|
acc +33
|
||||||
|
jmp -239
|
||||||
|
acc +3
|
||||||
|
acc -3
|
||||||
|
acc +27
|
||||||
|
acc -3
|
||||||
|
jmp -162
|
||||||
|
jmp -16
|
||||||
|
acc +23
|
||||||
|
acc +26
|
||||||
|
acc +25
|
||||||
|
jmp -346
|
||||||
|
acc +40
|
||||||
|
acc +45
|
||||||
|
acc +42
|
||||||
|
acc -4
|
||||||
|
jmp +1
|
||||||
9
inputs/day8_test.txt
Normal file
9
inputs/day8_test.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
nop +0
|
||||||
|
acc +1
|
||||||
|
jmp +4
|
||||||
|
acc +3
|
||||||
|
jmp -3
|
||||||
|
acc -99
|
||||||
|
acc +1
|
||||||
|
jmp -4
|
||||||
|
acc +6
|
||||||
186
src/bin/machine.rs
Normal file
186
src/bin/machine.rs
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
use advent2020::errors::{ExecutionError, InstructionParseError, TopLevelError};
|
||||||
|
use std::{collections::HashSet, env};
|
||||||
|
use std::fmt;
|
||||||
|
use std::fs;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Machine {
|
||||||
|
instructions: Vec<Instruction>,
|
||||||
|
accumulator: isize,
|
||||||
|
location: isize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum Instruction {
|
||||||
|
NOP(isize),
|
||||||
|
ACC(isize),
|
||||||
|
JMP(isize),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Instruction {
|
||||||
|
type Err = InstructionParseError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let mut lowered = s.to_string();
|
||||||
|
|
||||||
|
lowered.make_ascii_lowercase();
|
||||||
|
|
||||||
|
let mut items = s.split(' ');
|
||||||
|
let instruction = items.next().ok_or(InstructionParseError::EmptyInstruction)?;
|
||||||
|
let operand = items.next().ok_or(InstructionParseError::MissingOperand(instruction.to_string()))?;
|
||||||
|
let operand_value = isize::from_str(operand)?;
|
||||||
|
|
||||||
|
match instruction {
|
||||||
|
"nop" => Ok(Instruction::NOP(operand_value)),
|
||||||
|
"acc" => Ok(Instruction::ACC(operand_value)),
|
||||||
|
"jmp" => Ok(Instruction::JMP(operand_value)),
|
||||||
|
_ => Err(InstructionParseError::UnknownOpcode(instruction.to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Instruction {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Instruction::NOP(s) => write!(f, "NOP {:+}", s),
|
||||||
|
Instruction::ACC(s) => write!(f, "ACC {:+}", s),
|
||||||
|
Instruction::JMP(s) => write!(f, "JMP {:+}", s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Machine {
|
||||||
|
type Err = InstructionParseError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let mut instructions = Vec::new();
|
||||||
|
|
||||||
|
for line in s.lines() {
|
||||||
|
let instruction = Instruction::from_str(line)?;
|
||||||
|
instructions.push(instruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Machine {
|
||||||
|
instructions,
|
||||||
|
accumulator: 0,
|
||||||
|
location: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Machine {
|
||||||
|
fn pretty_print(&self) {
|
||||||
|
for (idx, instr) in self.instructions.iter().enumerate() {
|
||||||
|
let pointer = if (idx as isize) == self.location { "--> " } else { " " };
|
||||||
|
println!("{} {:04}: {}", pointer, idx, instr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step(&mut self) -> Result<(), ExecutionError> {
|
||||||
|
if self.location < 0 || self.location >= (self.instructions.len() as isize) {
|
||||||
|
return Err(ExecutionError::NonExistentLocation(self.location));
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.instructions[self.location as usize] {
|
||||||
|
Instruction::NOP(_) => self.location += 1,
|
||||||
|
Instruction::JMP(x) => self.location += x,
|
||||||
|
Instruction::ACC(x) => {
|
||||||
|
self.location += 1;
|
||||||
|
self.accumulator += x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn terminates(&mut self) -> Result<(bool, isize), ExecutionError> {
|
||||||
|
let mut visited_locations = HashSet::new();
|
||||||
|
loop {
|
||||||
|
let current_location = self.location;
|
||||||
|
let current_accumulator = self.accumulator;
|
||||||
|
|
||||||
|
visited_locations.insert(current_location);
|
||||||
|
self.step()?;
|
||||||
|
|
||||||
|
if visited_locations.contains(&self.location) {
|
||||||
|
return Ok((false, current_accumulator));
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.location == (self.instructions.len() as isize) {
|
||||||
|
return Ok((true, self.accumulator));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn variants(&self) -> VariantGenerator {
|
||||||
|
VariantGenerator {
|
||||||
|
next_offset: 0,
|
||||||
|
base_machine: self.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VariantGenerator {
|
||||||
|
next_offset: usize,
|
||||||
|
base_machine: Machine,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for VariantGenerator {
|
||||||
|
type Item = Machine;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
loop {
|
||||||
|
if self.next_offset >= self.base_machine.instructions.len() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.base_machine.instructions[self.next_offset] {
|
||||||
|
Instruction::ACC(_) => self.next_offset += 1,
|
||||||
|
Instruction::JMP(x) => {
|
||||||
|
let mut retval = self.base_machine.clone();
|
||||||
|
retval.instructions[self.next_offset] = Instruction::NOP(x);
|
||||||
|
self.next_offset += 1;
|
||||||
|
return Some(retval);
|
||||||
|
}
|
||||||
|
Instruction::NOP(x) => {
|
||||||
|
let mut retval = self.base_machine.clone();
|
||||||
|
retval.instructions[self.next_offset] = Instruction::JMP(x);
|
||||||
|
self.next_offset += 1;
|
||||||
|
return Some(retval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn real_main() -> Result<(), TopLevelError> {
|
||||||
|
let filename = env::args().skip(1).next().expect("No file argument given.");
|
||||||
|
let contents = fs::read_to_string(filename)?;
|
||||||
|
let machine = Machine::from_str(&contents)?;
|
||||||
|
|
||||||
|
machine.pretty_print();
|
||||||
|
|
||||||
|
// this is part 1
|
||||||
|
let (terminated, last_accum) = machine.clone().terminates()?;
|
||||||
|
if terminated {
|
||||||
|
println!("WARNING: Somehow the initial input terminated.");
|
||||||
|
}
|
||||||
|
println!("Last accumulator before looping forever: {}", last_accum);
|
||||||
|
|
||||||
|
// this is part 2
|
||||||
|
for mut variant in machine.variants() {
|
||||||
|
if let Ok((true, final_value)) = variant.terminates() {
|
||||||
|
println!("\nFound a variant that halts! Its last value is {}", final_value);
|
||||||
|
variant.pretty_print();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if let Err(e) = real_main() {
|
||||||
|
eprintln!("ERROR: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,16 @@ pub enum TopLevelError {
|
|||||||
#[from]
|
#[from]
|
||||||
source: BaggageRuleParseError,
|
source: BaggageRuleParseError,
|
||||||
},
|
},
|
||||||
|
#[error("Failed to parse instruction: {source}")]
|
||||||
|
InstructionParseError {
|
||||||
|
#[from]
|
||||||
|
source: InstructionParseError,
|
||||||
|
},
|
||||||
|
#[error("Error executing machine: {source}")]
|
||||||
|
MachineExecutionError {
|
||||||
|
#[from]
|
||||||
|
source: ExecutionError,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
@@ -97,3 +107,24 @@ impl<'a> From<nom::Err<nom::error::Error<&'a str>>> for BaggageRuleParseError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Error,Debug)]
|
||||||
|
pub enum InstructionParseError {
|
||||||
|
#[error("Unknown opcode {0}")]
|
||||||
|
UnknownOpcode(String),
|
||||||
|
#[error("Couldn't convert number: {source}")]
|
||||||
|
NumConversionError {
|
||||||
|
#[from]
|
||||||
|
source: ParseIntError
|
||||||
|
},
|
||||||
|
#[error("Encountered an empty instruction (?)")]
|
||||||
|
EmptyInstruction,
|
||||||
|
#[error("Instruction '{0}' missing an operand")]
|
||||||
|
MissingOperand(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error,Debug)]
|
||||||
|
pub enum ExecutionError {
|
||||||
|
#[error("Tried to execute non-existent instruction at {0}")]
|
||||||
|
NonExistentLocation(isize),
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user