diff --git a/day-8/.gitignore b/day-8/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/day-8/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/day-8/Cargo.lock b/day-8/Cargo.lock
new file mode 100644
index 0000000..81f3040
--- /dev/null
+++ b/day-8/Cargo.lock
@@ -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"
diff --git a/day-8/Cargo.toml b/day-8/Cargo.toml
new file mode 100644
index 0000000..9cc66ff
--- /dev/null
+++ b/day-8/Cargo.toml
@@ -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"
diff --git a/day-8/input b/day-8/input
new file mode 100644
index 0000000..764999d
--- /dev/null
+++ b/day-8/input
@@ -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
diff --git a/day-8/src/emulator.rs b/day-8/src/emulator.rs
new file mode 100644
index 0000000..c148197
--- /dev/null
+++ b/day-8/src/emulator.rs
@@ -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(())
+    }
+}
diff --git a/day-8/src/main.rs b/day-8/src/main.rs
new file mode 100644
index 0000000..e4afef8
--- /dev/null
+++ b/day-8/src/main.rs
@@ -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(())
+}