diff --git a/day-13/Cargo.lock b/day-13/Cargo.lock
new file mode 100644
index 0000000..d0515ae
--- /dev/null
+++ b/day-13/Cargo.lock
@@ -0,0 +1,78 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "day-13"
+version = "0.1.0"
+dependencies = [
+ "indoc",
+]
+
+[[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 = "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-13/Cargo.toml b/day-13/Cargo.toml
new file mode 100644
index 0000000..a4e1f5b
--- /dev/null
+++ b/day-13/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "day-13"
+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"
diff --git a/day-13/input b/day-13/input
new file mode 100644
index 0000000..e614056
--- /dev/null
+++ b/day-13/input
@@ -0,0 +1,2 @@
+1000391
+19,x,x,x,x,x,x,x,x,x,x,x,x,37,x,x,x,x,x,383,x,x,x,x,x,x,x,23,x,x,x,x,13,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,29,x,457,x,x,x,x,x,x,x,x,x,41,x,x,x,x,x,x,17
diff --git a/day-13/src/main.rs b/day-13/src/main.rs
new file mode 100644
index 0000000..be4bd15
--- /dev/null
+++ b/day-13/src/main.rs
@@ -0,0 +1,172 @@
+use std::fs;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+    let input = fs::read_to_string("input")?;
+    let (time, ids) = parse_notes(&input)?;
+
+    // Part 1
+    let (earliest, arrival) = find_closest_bus(time, &ids);
+    println!("{}", (arrival - time) * earliest);
+
+    // Part 2
+    let timestamp = find_gauss(&ids);
+    println!("{}", timestamp);
+
+    Ok(())
+}
+
+fn parse_notes(input: &str) -> Result<(u32, Vec<u32>), &str> {
+    let mut lines = input.lines();
+
+    let estimate = lines
+        .next()
+        .ok_or("Input too short")?
+        .parse()
+        .map_err(|_| "Estimate is not a number")?;
+
+    let ids = lines
+        .next()
+        .ok_or("Input too short")?
+        .split(',')
+        .map(|id| id.parse().unwrap_or(1))
+        .collect();
+
+    Ok((estimate, ids))
+}
+
+fn find_closest_bus(time: u32, ids: &Vec<u32>) -> (u32, u32) {
+    ids.iter()
+        .filter(|id| **id != 1)
+        .map(|id| {
+            let mut arrival = *id;
+
+            while arrival < time {
+                arrival += id
+            }
+
+            (*id, arrival)
+        })
+        .min_by_key(|id| id.1)
+        .expect("Must have at least one bus ID")
+}
+
+fn find_gauss(ids: &Vec<u32>) -> u128 {
+    let ids: Vec<u128> = ids.iter().map(|id| *id as u128).collect();
+    let product: u128 = ids.iter().product();
+
+    let gauss = |mut n: u128, mut d: u128, m: u128| -> u128 {
+        while d != 1 {
+            if m == 1 {
+                return 0;
+            };
+
+            let multiplier = if m > d {
+                m / d + (m % d != 0) as u128
+            } else {
+                1
+            };
+
+            n = (n * multiplier) % m;
+            d = (d * multiplier) % m;
+        }
+
+        n / d
+    };
+
+    (0..ids.len())
+        .map(|a| {
+            let b = product / ids[a];
+            let bi = gauss(1, b, ids[a]);
+            let a = (ids[a] * a as u128 - a as u128) % ids[a] as u128;
+
+            a * b * bi
+        })
+        .sum::<u128>()
+        % product
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use indoc::indoc;
+
+    #[test]
+    fn test_simple() -> Result<(), Box<dyn std::error::Error>> {
+        let input = indoc!(
+            "939
+             7,13,x,x,59,x,31,19
+            "
+        );
+
+        let (time, ids) = parse_notes(input)?;
+        let (earliest, arrival) = find_closest_bus(time, &ids);
+
+        assert_eq!(arrival, 944);
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_simple2() -> Result<(), Box<dyn std::error::Error>> {
+        let input = indoc!(
+            "939
+             17,x,13,19
+            "
+        );
+
+        let (time, ids) = parse_notes(input)?;
+        let timestamp = find_gauss(&ids);
+
+        assert_eq!(timestamp, 3417);
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_simple3() -> Result<(), Box<dyn std::error::Error>> {
+        let input = indoc!(
+            "939
+             7,13,x,x,59,x,31,19
+            "
+        );
+
+        let (time, ids) = parse_notes(input)?;
+        let timestamp = find_gauss(&ids);
+
+        assert_eq!(timestamp, 1068781);
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_simple4() -> Result<(), Box<dyn std::error::Error>> {
+        let input = indoc!(
+            "939
+             67,7,59,61
+            "
+        );
+
+        let (time, ids) = parse_notes(input)?;
+        let timestamp = find_gauss(&ids);
+
+        assert_eq!(timestamp, 754018);
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_simple5() -> Result<(), Box<dyn std::error::Error>> {
+        let input = indoc!(
+            "939
+             67,x,7,59,61
+            "
+        );
+
+        let (time, ids) = parse_notes(input)?;
+        let timestamp = find_gauss(&ids);
+
+        assert_eq!(timestamp, 779210);
+
+        Ok(())
+    }
+}