Compare commits
1 commit
ae48e7b4fb
...
bf40754b0b
Author | SHA1 | Date | |
---|---|---|---|
Tristan Daniël Maat | bf40754b0b |
1
day-8/.gitignore
vendored
Normal file
1
day-8/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target/
|
106
day-8/Cargo.lock
generated
Normal file
106
day-8/Cargo.lock
generated
Normal file
|
@ -0,0 +1,106 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "day-8"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"indoc",
|
||||
"snafu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||
|
||||
[[package]]
|
||||
name = "indoc"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47741a8bc60fb26eb8d6e0238bbb26d8575ff623fdc97b1a2c00c050b9684ed8"
|
||||
dependencies = [
|
||||
"indoc-impl",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indoc-impl"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce046d161f000fffde5f432a0d034d0341dc152643b2598ed5bfce44c4f3a8f0"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"unindent",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snafu"
|
||||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eab12d3c261b2308b0d80c26fffb58d17eba81a4be97890101f416b478c79ca7"
|
||||
dependencies = [
|
||||
"doc-comment",
|
||||
"snafu-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snafu-derive"
|
||||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1508efa03c362e23817f96cde18abed596a25219a8b2c66e8db33c03543d315b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "unindent"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7"
|
11
day-8/Cargo.toml
Normal file
11
day-8/Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "day-8"
|
||||
version = "0.1.0"
|
||||
authors = ["Tristan Daniël Maat <tm@tlater.net>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
indoc = "0.3"
|
||||
snafu = "0.6"
|
612
day-8/input
Normal file
612
day-8/input
Normal file
|
@ -0,0 +1,612 @@
|
|||
jmp +236
|
||||
acc +43
|
||||
acc +28
|
||||
jmp +149
|
||||
acc +28
|
||||
acc +13
|
||||
acc +36
|
||||
acc +42
|
||||
jmp +439
|
||||
acc -14
|
||||
jmp +29
|
||||
jmp +154
|
||||
acc +16
|
||||
acc -13
|
||||
acc -16
|
||||
nop +317
|
||||
jmp +497
|
||||
acc +21
|
||||
jmp +386
|
||||
jmp +373
|
||||
acc +22
|
||||
jmp +311
|
||||
acc -16
|
||||
acc +27
|
||||
acc +21
|
||||
acc +43
|
||||
jmp +512
|
||||
jmp +218
|
||||
jmp +217
|
||||
acc +12
|
||||
acc +44
|
||||
nop +367
|
||||
nop +180
|
||||
jmp +134
|
||||
acc -2
|
||||
acc +42
|
||||
acc +13
|
||||
acc -11
|
||||
jmp +442
|
||||
nop +457
|
||||
jmp +151
|
||||
acc +15
|
||||
acc -4
|
||||
acc +0
|
||||
jmp +131
|
||||
acc +6
|
||||
acc -2
|
||||
acc +37
|
||||
jmp +112
|
||||
acc +32
|
||||
acc +6
|
||||
acc -15
|
||||
jmp +474
|
||||
jmp +515
|
||||
acc +12
|
||||
acc +11
|
||||
acc +4
|
||||
jmp +339
|
||||
acc -3
|
||||
acc +36
|
||||
jmp +220
|
||||
nop +91
|
||||
acc -12
|
||||
jmp +49
|
||||
acc -17
|
||||
jmp +204
|
||||
acc +40
|
||||
jmp +535
|
||||
acc +37
|
||||
acc +8
|
||||
nop +147
|
||||
nop +174
|
||||
jmp +306
|
||||
jmp +305
|
||||
acc +7
|
||||
acc +33
|
||||
jmp +305
|
||||
acc +22
|
||||
acc +17
|
||||
acc +24
|
||||
jmp +458
|
||||
jmp +1
|
||||
acc +36
|
||||
acc +34
|
||||
jmp +113
|
||||
acc -3
|
||||
nop +113
|
||||
nop -34
|
||||
jmp +506
|
||||
acc -19
|
||||
acc +21
|
||||
acc +35
|
||||
acc -1
|
||||
jmp +74
|
||||
acc +15
|
||||
acc +7
|
||||
jmp +79
|
||||
acc +29
|
||||
acc +42
|
||||
jmp +427
|
||||
acc +33
|
||||
jmp +29
|
||||
acc +6
|
||||
acc +13
|
||||
nop +477
|
||||
acc +26
|
||||
jmp +493
|
||||
acc +33
|
||||
acc +43
|
||||
acc +49
|
||||
acc +35
|
||||
jmp +409
|
||||
acc -7
|
||||
acc +35
|
||||
acc +40
|
||||
jmp +309
|
||||
acc -13
|
||||
acc -14
|
||||
acc +32
|
||||
jmp +322
|
||||
jmp +10
|
||||
jmp +44
|
||||
acc +20
|
||||
acc +25
|
||||
jmp +175
|
||||
acc +22
|
||||
acc +16
|
||||
acc +1
|
||||
acc +36
|
||||
jmp -65
|
||||
jmp +231
|
||||
acc +35
|
||||
jmp +155
|
||||
jmp +218
|
||||
acc -10
|
||||
acc -13
|
||||
acc +38
|
||||
jmp -92
|
||||
acc +15
|
||||
jmp +134
|
||||
acc -16
|
||||
acc +18
|
||||
jmp -30
|
||||
nop -41
|
||||
acc +48
|
||||
acc +49
|
||||
jmp -107
|
||||
acc +4
|
||||
acc +34
|
||||
acc +38
|
||||
acc -18
|
||||
jmp +247
|
||||
acc +45
|
||||
acc +23
|
||||
jmp +149
|
||||
nop +164
|
||||
acc +26
|
||||
jmp -24
|
||||
jmp +240
|
||||
jmp +77
|
||||
acc +30
|
||||
acc -13
|
||||
jmp -158
|
||||
nop +136
|
||||
jmp +33
|
||||
jmp +189
|
||||
jmp +143
|
||||
jmp +1
|
||||
acc +4
|
||||
acc +30
|
||||
jmp -106
|
||||
acc +16
|
||||
nop -52
|
||||
acc +37
|
||||
jmp +119
|
||||
acc -11
|
||||
acc -9
|
||||
acc +15
|
||||
acc +4
|
||||
jmp +301
|
||||
jmp +1
|
||||
acc -3
|
||||
jmp +188
|
||||
nop +86
|
||||
nop +125
|
||||
acc -10
|
||||
jmp -105
|
||||
acc +36
|
||||
acc +9
|
||||
acc +0
|
||||
jmp +317
|
||||
jmp +347
|
||||
acc +48
|
||||
nop +380
|
||||
acc -18
|
||||
acc +28
|
||||
jmp +398
|
||||
jmp -152
|
||||
jmp -86
|
||||
acc +22
|
||||
acc +11
|
||||
acc +39
|
||||
jmp -173
|
||||
jmp +343
|
||||
nop +194
|
||||
nop +98
|
||||
nop +382
|
||||
jmp +300
|
||||
acc +35
|
||||
nop +287
|
||||
acc -8
|
||||
jmp +302
|
||||
acc +19
|
||||
acc +45
|
||||
jmp +95
|
||||
acc +29
|
||||
jmp +274
|
||||
acc +18
|
||||
acc -13
|
||||
acc +23
|
||||
acc +7
|
||||
jmp +164
|
||||
acc +17
|
||||
acc +36
|
||||
acc -5
|
||||
jmp +153
|
||||
acc +21
|
||||
jmp +105
|
||||
jmp +1
|
||||
nop +267
|
||||
jmp +277
|
||||
jmp +88
|
||||
acc +2
|
||||
acc +18
|
||||
nop +182
|
||||
jmp +189
|
||||
acc +37
|
||||
acc +46
|
||||
jmp +258
|
||||
acc +22
|
||||
acc +15
|
||||
jmp +249
|
||||
acc +17
|
||||
jmp -162
|
||||
jmp +25
|
||||
acc -6
|
||||
nop +314
|
||||
jmp -30
|
||||
jmp +312
|
||||
acc +34
|
||||
nop -230
|
||||
acc -2
|
||||
jmp +158
|
||||
acc -4
|
||||
acc +37
|
||||
jmp +318
|
||||
acc +18
|
||||
acc +23
|
||||
acc -8
|
||||
jmp -248
|
||||
jmp +181
|
||||
acc +17
|
||||
acc +4
|
||||
jmp -189
|
||||
acc +27
|
||||
acc -13
|
||||
acc -4
|
||||
acc +8
|
||||
jmp +222
|
||||
jmp +310
|
||||
acc -5
|
||||
acc +35
|
||||
jmp +241
|
||||
jmp -130
|
||||
jmp +124
|
||||
acc -19
|
||||
jmp +331
|
||||
acc -8
|
||||
acc +45
|
||||
jmp +106
|
||||
acc +23
|
||||
acc +48
|
||||
jmp -107
|
||||
acc +7
|
||||
acc -19
|
||||
acc +3
|
||||
jmp +130
|
||||
jmp -104
|
||||
nop +5
|
||||
acc +29
|
||||
acc +8
|
||||
acc -6
|
||||
jmp +7
|
||||
acc +12
|
||||
jmp +102
|
||||
acc -4
|
||||
acc +46
|
||||
acc -17
|
||||
jmp -209
|
||||
acc +20
|
||||
jmp -271
|
||||
acc +48
|
||||
jmp +30
|
||||
nop +204
|
||||
acc -19
|
||||
acc +4
|
||||
acc +38
|
||||
jmp +17
|
||||
jmp +116
|
||||
acc -17
|
||||
acc +23
|
||||
jmp -75
|
||||
jmp -129
|
||||
jmp +152
|
||||
acc +36
|
||||
nop -193
|
||||
acc +26
|
||||
acc +38
|
||||
jmp +242
|
||||
jmp -197
|
||||
acc +32
|
||||
acc -5
|
||||
acc -19
|
||||
jmp -201
|
||||
jmp -304
|
||||
acc +9
|
||||
jmp +175
|
||||
acc +1
|
||||
jmp -15
|
||||
jmp +1
|
||||
nop -74
|
||||
jmp -38
|
||||
nop -165
|
||||
acc -19
|
||||
jmp -317
|
||||
acc -19
|
||||
acc -1
|
||||
jmp +17
|
||||
acc +0
|
||||
nop +151
|
||||
jmp +93
|
||||
acc +32
|
||||
acc +29
|
||||
acc +0
|
||||
jmp -340
|
||||
acc +39
|
||||
jmp -115
|
||||
acc +0
|
||||
acc +47
|
||||
nop -320
|
||||
jmp +244
|
||||
acc +29
|
||||
jmp +81
|
||||
jmp -84
|
||||
acc +2
|
||||
acc +16
|
||||
nop -345
|
||||
acc +23
|
||||
jmp +9
|
||||
acc +26
|
||||
jmp -67
|
||||
acc -11
|
||||
acc +38
|
||||
jmp +150
|
||||
acc +19
|
||||
acc -2
|
||||
jmp -244
|
||||
jmp +88
|
||||
acc -4
|
||||
jmp -157
|
||||
acc +22
|
||||
acc +33
|
||||
acc +41
|
||||
jmp -117
|
||||
acc +31
|
||||
acc +50
|
||||
acc +24
|
||||
jmp -265
|
||||
jmp +1
|
||||
jmp -352
|
||||
jmp -312
|
||||
acc +35
|
||||
acc +30
|
||||
jmp -90
|
||||
jmp +8
|
||||
acc +14
|
||||
acc +39
|
||||
jmp -112
|
||||
acc -11
|
||||
acc -3
|
||||
acc +22
|
||||
jmp -116
|
||||
acc +48
|
||||
jmp -194
|
||||
acc -5
|
||||
jmp -252
|
||||
jmp +66
|
||||
jmp -295
|
||||
jmp +196
|
||||
acc +25
|
||||
acc -11
|
||||
nop +112
|
||||
acc +33
|
||||
jmp +123
|
||||
acc -10
|
||||
acc +28
|
||||
nop -119
|
||||
acc +12
|
||||
jmp -166
|
||||
jmp -356
|
||||
acc +8
|
||||
acc +16
|
||||
jmp +161
|
||||
acc +25
|
||||
acc +3
|
||||
jmp -5
|
||||
acc +32
|
||||
acc +40
|
||||
jmp +181
|
||||
acc -11
|
||||
acc -5
|
||||
jmp +1
|
||||
acc +0
|
||||
jmp -265
|
||||
acc +5
|
||||
acc +24
|
||||
acc +15
|
||||
acc -17
|
||||
jmp -326
|
||||
nop +103
|
||||
acc -9
|
||||
acc +13
|
||||
jmp -379
|
||||
acc +38
|
||||
acc +16
|
||||
jmp -65
|
||||
jmp +1
|
||||
jmp +1
|
||||
jmp +1
|
||||
acc -1
|
||||
jmp -191
|
||||
acc +35
|
||||
acc -19
|
||||
acc -6
|
||||
jmp -52
|
||||
acc +15
|
||||
jmp -357
|
||||
nop -134
|
||||
acc -3
|
||||
nop +103
|
||||
jmp -123
|
||||
acc +43
|
||||
acc +0
|
||||
acc +47
|
||||
jmp -373
|
||||
acc +0
|
||||
acc +50
|
||||
acc +44
|
||||
acc +21
|
||||
jmp -114
|
||||
acc -19
|
||||
jmp -339
|
||||
acc +25
|
||||
jmp -410
|
||||
jmp -126
|
||||
acc -2
|
||||
acc -6
|
||||
acc +14
|
||||
jmp -207
|
||||
acc +35
|
||||
acc -7
|
||||
jmp +75
|
||||
acc +9
|
||||
acc +22
|
||||
jmp +114
|
||||
acc +18
|
||||
acc +36
|
||||
acc +0
|
||||
acc +40
|
||||
jmp -192
|
||||
acc +35
|
||||
acc +0
|
||||
acc +28
|
||||
acc +3
|
||||
jmp -346
|
||||
nop -131
|
||||
acc +46
|
||||
nop -467
|
||||
nop -179
|
||||
jmp -151
|
||||
jmp -120
|
||||
acc +30
|
||||
acc +22
|
||||
acc -7
|
||||
acc +18
|
||||
jmp -157
|
||||
acc +5
|
||||
jmp +76
|
||||
nop -315
|
||||
acc +25
|
||||
jmp -357
|
||||
acc +44
|
||||
jmp -12
|
||||
acc +0
|
||||
acc +19
|
||||
nop -485
|
||||
jmp -495
|
||||
nop -115
|
||||
acc +12
|
||||
jmp -8
|
||||
acc +31
|
||||
acc -7
|
||||
jmp -158
|
||||
acc +44
|
||||
acc +32
|
||||
jmp +87
|
||||
acc +1
|
||||
acc +37
|
||||
acc +44
|
||||
jmp -86
|
||||
acc +0
|
||||
acc +17
|
||||
acc -13
|
||||
jmp -434
|
||||
acc +37
|
||||
jmp -342
|
||||
acc +3
|
||||
jmp +1
|
||||
acc +29
|
||||
jmp -242
|
||||
acc +48
|
||||
jmp -442
|
||||
jmp -283
|
||||
acc -19
|
||||
acc +6
|
||||
acc +20
|
||||
acc +44
|
||||
jmp -533
|
||||
acc -15
|
||||
nop -356
|
||||
acc +18
|
||||
jmp -408
|
||||
acc -9
|
||||
acc +17
|
||||
acc +16
|
||||
jmp -385
|
||||
nop -130
|
||||
jmp +1
|
||||
acc +38
|
||||
acc +39
|
||||
jmp -324
|
||||
jmp -141
|
||||
acc +4
|
||||
acc +3
|
||||
acc -4
|
||||
jmp -114
|
||||
acc +2
|
||||
jmp +1
|
||||
acc +44
|
||||
jmp -360
|
||||
acc +43
|
||||
acc +36
|
||||
nop -177
|
||||
nop -288
|
||||
jmp -496
|
||||
acc +45
|
||||
acc +0
|
||||
jmp -322
|
||||
acc +13
|
||||
jmp -511
|
||||
acc -2
|
||||
acc +36
|
||||
jmp -460
|
||||
acc +28
|
||||
acc +28
|
||||
jmp -455
|
||||
acc -4
|
||||
acc +38
|
||||
jmp -145
|
||||
jmp -163
|
||||
jmp -331
|
||||
nop -227
|
||||
jmp -470
|
||||
acc +35
|
||||
nop -419
|
||||
acc +39
|
||||
acc +0
|
||||
jmp -435
|
||||
jmp +1
|
||||
jmp -69
|
||||
acc +20
|
||||
acc +46
|
||||
nop +2
|
||||
jmp -239
|
||||
acc -3
|
||||
acc +12
|
||||
acc +38
|
||||
jmp -259
|
||||
jmp -60
|
||||
jmp -67
|
||||
nop -542
|
||||
jmp -397
|
||||
acc +32
|
||||
jmp -57
|
||||
acc +30
|
||||
nop -393
|
||||
jmp -380
|
||||
acc +16
|
||||
acc -7
|
||||
acc +0
|
||||
acc +2
|
||||
jmp +1
|
187
day-8/src/emulator.rs
Normal file
187
day-8/src/emulator.rs
Normal file
|
@ -0,0 +1,187 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use snafu::Snafu;
|
||||
|
||||
pub type Program = Vec<(Instruction, i64)>;
|
||||
|
||||
#[derive(Debug, PartialEq, Snafu)]
|
||||
pub enum EmulatorError {
|
||||
#[snafu(display("Segmentation fault"))]
|
||||
SegmentationFault,
|
||||
#[snafu(display("Infinite loop: {}", accumulator))]
|
||||
InfiniteLoop { accumulator: i64 },
|
||||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
pub enum ProgramParseError {
|
||||
#[snafu(display("Invalid instruction given: {}", instruction))]
|
||||
InvalidInstruction { instruction: String },
|
||||
#[snafu(display("Invalid argument given: {}", argument))]
|
||||
InvalidArgument { argument: String },
|
||||
#[snafu(display("Unparseable line: {}", line))]
|
||||
InvalidLine { line: String },
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Instruction {
|
||||
Accumulate,
|
||||
Jump,
|
||||
NoOperation,
|
||||
}
|
||||
|
||||
pub struct Emulator {
|
||||
accumulator: i64,
|
||||
program_counter: usize,
|
||||
}
|
||||
|
||||
impl Emulator {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
accumulator: 0,
|
||||
program_counter: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
self.accumulator = 0;
|
||||
self.program_counter = 0;
|
||||
}
|
||||
|
||||
pub fn execute_instruction(
|
||||
&mut self,
|
||||
instruction: Instruction,
|
||||
argument: i64,
|
||||
) -> Result<(), EmulatorError> {
|
||||
match instruction {
|
||||
Instruction::Accumulate => self.accumulator += argument,
|
||||
Instruction::Jump => {
|
||||
self.program_counter = self.program_counter.wrapping_add(argument as usize - 1)
|
||||
}
|
||||
Instruction::NoOperation => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_program_finitely(&mut self, program: &Program) -> Result<i64, EmulatorError> {
|
||||
let mut executed = HashSet::new();
|
||||
|
||||
loop {
|
||||
let (instruction, argument) = program
|
||||
.get(self.program_counter)
|
||||
.ok_or(EmulatorError::SegmentationFault)?;
|
||||
executed.insert(self.program_counter);
|
||||
|
||||
self.execute_instruction(*instruction, *argument)?;
|
||||
|
||||
self.program_counter += 1;
|
||||
|
||||
if executed.contains(&self.program_counter) {
|
||||
break Err(EmulatorError::InfiniteLoop {
|
||||
accumulator: self.accumulator,
|
||||
});
|
||||
} else if self.program_counter >= program.len() {
|
||||
break Ok(self.accumulator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_code(input: &str) -> Result<Program, ProgramParseError> {
|
||||
input
|
||||
.lines()
|
||||
.map(|instruction| {
|
||||
let (name, argument): (&str, &str) = {
|
||||
let temp: Vec<&str> = instruction.split(' ').collect();
|
||||
if temp.len() != 2 {
|
||||
Err(ProgramParseError::InvalidLine {
|
||||
line: instruction.to_string(),
|
||||
})
|
||||
} else {
|
||||
Ok((temp[0], temp[1]))
|
||||
}
|
||||
}?;
|
||||
|
||||
Ok((
|
||||
match name {
|
||||
"acc" => Instruction::Accumulate,
|
||||
"jmp" => Instruction::Jump,
|
||||
"nop" => Instruction::NoOperation,
|
||||
_ => Err(ProgramParseError::InvalidInstruction {
|
||||
instruction: name.to_string(),
|
||||
})?,
|
||||
},
|
||||
argument
|
||||
.parse()
|
||||
.or(Err(ProgramParseError::InvalidArgument {
|
||||
argument: argument.to_string(),
|
||||
}))?,
|
||||
))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use indoc::indoc;
|
||||
|
||||
#[test]
|
||||
fn test_parsing() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let input = indoc!(
|
||||
"nop +0
|
||||
acc +1
|
||||
jmp +4
|
||||
acc +3
|
||||
jmp -3
|
||||
acc -99
|
||||
acc +1
|
||||
jmp -4
|
||||
acc +6
|
||||
"
|
||||
);
|
||||
|
||||
let code = parse_code(&input)?;
|
||||
assert_eq!(
|
||||
code,
|
||||
vec![
|
||||
(Instruction::NoOperation, 0),
|
||||
(Instruction::Accumulate, 1),
|
||||
(Instruction::Jump, 4),
|
||||
(Instruction::Accumulate, 3),
|
||||
(Instruction::Jump, -3),
|
||||
(Instruction::Accumulate, -99),
|
||||
(Instruction::Accumulate, 1),
|
||||
(Instruction::Jump, -4),
|
||||
(Instruction::Accumulate, 6),
|
||||
]
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_running() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let input = indoc!(
|
||||
"nop +0
|
||||
acc +1
|
||||
jmp +4
|
||||
acc +3
|
||||
jmp -3
|
||||
acc -99
|
||||
acc +1
|
||||
jmp -4
|
||||
acc +6
|
||||
"
|
||||
);
|
||||
|
||||
let code = parse_code(&input)?;
|
||||
let mut emulator = Emulator::new();
|
||||
assert_eq!(
|
||||
emulator.run_program_finitely(&code),
|
||||
Err(EmulatorError::InfiniteLoop { accumulator: 5 })
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
49
day-8/src/main.rs
Normal file
49
day-8/src/main.rs
Normal file
|
@ -0,0 +1,49 @@
|
|||
use std::fs;
|
||||
|
||||
mod emulator;
|
||||
|
||||
use emulator::{parse_code, Emulator, EmulatorError, Instruction};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let input = fs::read_to_string("input")?;
|
||||
let program = parse_code(&input)?;
|
||||
|
||||
// Part 1
|
||||
let mut emulator = Emulator::new();
|
||||
if let Err(EmulatorError::InfiniteLoop { accumulator }) =
|
||||
emulator.run_program_finitely(&program)
|
||||
{
|
||||
println!("{}", accumulator);
|
||||
} else {
|
||||
panic!("We should get an infinite loop.");
|
||||
}
|
||||
|
||||
// Part 2
|
||||
let result = program
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, instruction)| match instruction {
|
||||
(Instruction::Jump, arg) => {
|
||||
let mut program = program.clone();
|
||||
program[i] = (Instruction::NoOperation, *arg);
|
||||
emulator.reset();
|
||||
emulator.run_program_finitely(&program).ok()
|
||||
}
|
||||
(Instruction::NoOperation, arg) => {
|
||||
let mut program = program.clone();
|
||||
program[i] = (Instruction::Jump, *arg);
|
||||
emulator.reset();
|
||||
emulator.run_program_finitely(&program).ok()
|
||||
}
|
||||
(_, _) => None,
|
||||
})
|
||||
.next();
|
||||
|
||||
if let Some(result) = result {
|
||||
println!("{}", result);
|
||||
} else {
|
||||
panic!("We should have at least one non-infinte loop.");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in a new issue