diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 2f7896d..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target/ diff --git a/day-12/Cargo.lock b/day-12/Cargo.lock deleted file mode 100644 index b7e1235..0000000 --- a/day-12/Cargo.lock +++ /dev/null @@ -1,78 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "day-12" -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-12/Cargo.toml b/day-12/Cargo.toml deleted file mode 100644 index 35cad43..0000000 --- a/day-12/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "day-12" -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-12/input b/day-12/input deleted file mode 100644 index bedc29a..0000000 --- a/day-12/input +++ /dev/null @@ -1,771 +0,0 @@ -F8 -N2 -F32 -F17 -E4 -N4 -R90 -S2 -R90 -E3 -L90 -N5 -E2 -N2 -W5 -F78 -L180 -F19 -R90 -S1 -E2 -L180 -E1 -S5 -E4 -F62 -R180 -F16 -S2 -F8 -R180 -S1 -L90 -E4 -R90 -S3 -E5 -R180 -F87 -N2 -E2 -R90 -N2 -F2 -R90 -N5 -W4 -L90 -F42 -N1 -F93 -F87 -E2 -S4 -F73 -L270 -S2 -W3 -F48 -W5 -L180 -N1 -F53 -R90 -S2 -R90 -N2 -E2 -S5 -W3 -R90 -E2 -R90 -W1 -L180 -F29 -W1 -F56 -R90 -F34 -F74 -S1 -R90 -L90 -W4 -L90 -W5 -L90 -W1 -L90 -N5 -E2 -S2 -F58 -N5 -L90 -S4 -L90 -R270 -W4 -S4 -E3 -R180 -S4 -W3 -R90 -F36 -R90 -W1 -F73 -S4 -E1 -L90 -S4 -W5 -L90 -F20 -W3 -L180 -E3 -S1 -R90 -S5 -W3 -L90 -E5 -W2 -F21 -N4 -F83 -W4 -F48 -W3 -F4 -L90 -N5 -R270 -E1 -S5 -L180 -F44 -W5 -R180 -S3 -F30 -N5 -F87 -L90 -F69 -S5 -E1 -R90 -E2 -S3 -F40 -W4 -F97 -W5 -F20 -L180 -N5 -L90 -E5 -N3 -L90 -F13 -N2 -F38 -S5 -F27 -E5 -L180 -F59 -N3 -F2 -R90 -N2 -R90 -F56 -L90 -N4 -R90 -F12 -F34 -N3 -F93 -L270 -W3 -F74 -W4 -R90 -E2 -L180 -W3 -F12 -N5 -W1 -F98 -E4 -R180 -S1 -W5 -R90 -F96 -N2 -L90 -F36 -S1 -F3 -W3 -F100 -N5 -R90 -F33 -W3 -N5 -E3 -R90 -F33 -N5 -E2 -N1 -L90 -F84 -L270 -E1 -F28 -R180 -W3 -L90 -S2 -F88 -L90 -W2 -N1 -F3 -R90 -F56 -N1 -N4 -L90 -R90 -F97 -E5 -N4 -F38 -N1 -R90 -W1 -F60 -W3 -N1 -F59 -E1 -N3 -E3 -L180 -N1 -F53 -S1 -E2 -R90 -E2 -F6 -R180 -F36 -R180 -W2 -F81 -R90 -E4 -R90 -F97 -L90 -W1 -S1 -E5 -L180 -F34 -R180 -F64 -E2 -R180 -W3 -S5 -L90 -E4 -F12 -F58 -W3 -N3 -F77 -N4 -F32 -R90 -N2 -E4 -L90 -S5 -E1 -N5 -F44 -R90 -F5 -E4 -R90 -N5 -E4 -R180 -W3 -L90 -N1 -F1 -S3 -E5 -R180 -S3 -F86 -S5 -F61 -W3 -R270 -W5 -R90 -F26 -R180 -F92 -S5 -L90 -E5 -N5 -F82 -R90 -F22 -R90 -F23 -S1 -F42 -N4 -F76 -E1 -S1 -W3 -S2 -L90 -F19 -E4 -F41 -E2 -N2 -L90 -F34 -S4 -F20 -W3 -F18 -S1 -R90 -N3 -F38 -W3 -R90 -W4 -R90 -E2 -R90 -F10 -L90 -N4 -F94 -S1 -W3 -R180 -W5 -F74 -R90 -S4 -L180 -S3 -F74 -N5 -S4 -L90 -F34 -S2 -E5 -N5 -F28 -L90 -E1 -F31 -N1 -L90 -L90 -W2 -N5 -R90 -F1 -N5 -F48 -W2 -F50 -N2 -F62 -S4 -L90 -W5 -N1 -F12 -W3 -R90 -R90 -F75 -N5 -F69 -E3 -F19 -N2 -F77 -E1 -N4 -R180 -E3 -N2 -L90 -N1 -W1 -S4 -F85 -W1 -R90 -F74 -E5 -F73 -E4 -S3 -W4 -S5 -L90 -F49 -S5 -E5 -F5 -W2 -F58 -R90 -W5 -F53 -S4 -F86 -N2 -F88 -E5 -F59 -E1 -F56 -W2 -N4 -W4 -R180 -F16 -F25 -R180 -N3 -F4 -W4 -S4 -F98 -E5 -L90 -W4 -S1 -E2 -R90 -F96 -L270 -E1 -N1 -F55 -S1 -F10 -R90 -W2 -L90 -N5 -R90 -N4 -E4 -L90 -F52 -S3 -F43 -E2 -R90 -S3 -R90 -N4 -E1 -N4 -F15 -E3 -R270 -L180 -N2 -F43 -L90 -W2 -F19 -L90 -S5 -F58 -E4 -S4 -L90 -W1 -F9 -N4 -F38 -S5 -L90 -W1 -F39 -W5 -F83 -L180 -F99 -L90 -E3 -S2 -R90 -N3 -F35 -N1 -N3 -L90 -N4 -W5 -F26 -R270 -N2 -F7 -N1 -F16 -S4 -L90 -S5 -L180 -F5 -W1 -F32 -S2 -N3 -F82 -N4 -R90 -F27 -R180 -F20 -S1 -E3 -L90 -W3 -F23 -L180 -N3 -F34 -W1 -N3 -S2 -F80 -E5 -F65 -L90 -E5 -N1 -F80 -R90 -W3 -L90 -N1 -L180 -S1 -F65 -E3 -S1 -W3 -F89 -S1 -F24 -E5 -F85 -W1 -F87 -S1 -R90 -S4 -F3 -S3 -F23 -N4 -L90 -N5 -R90 -N2 -R90 -S2 -W4 -S2 -F95 -L90 -F52 -W1 -N5 -L90 -N4 -S3 -E3 -R90 -N2 -E1 -R180 -W4 -F82 -L180 -E5 -L90 -E4 -F65 -W5 -R90 -W5 -N5 -L180 -N4 -F22 -W3 -S4 -F60 -R90 -E5 -N3 -F32 -S2 -F80 -R90 -F18 -S3 -L90 -F90 -E3 -L90 -N3 -E5 -F79 -N5 -W4 -S5 -F100 -N1 -E3 -S3 -F49 -R180 -S3 -E2 -F1 -W1 -F5 -R180 -S5 -W3 -S3 -F67 -R270 -N3 -W3 -N1 -W3 -F37 -L90 -N3 -L90 -F68 -N3 -W4 -W2 -F26 -N3 -L90 -W3 -S2 -F7 -W3 -E3 -L270 -F64 -R90 -E4 -R90 -W3 -N1 -W1 -F98 -R270 -W5 -F45 -R90 -F49 -E4 -S2 -F58 -F56 -W3 -F57 -E3 -S5 -R180 -E3 -F82 -F57 -S3 -W2 -R90 -E2 -R90 -F95 -W4 -F85 -E3 -N3 -R90 -E5 -F31 -R90 -F20 -R90 -N5 -E3 -S4 -R180 -W1 -N5 -F72 -L90 -E3 -F46 -R180 -F18 -E3 -F48 -S2 -F84 -W3 -F88 -F44 -S2 -E4 -F77 -L90 -N4 -L90 -E2 -F22 -E5 -L90 -F79 -W1 -R90 -F41 -R180 -F54 diff --git a/day-12/src/main.rs b/day-12/src/main.rs deleted file mode 100644 index 6212c23..0000000 --- a/day-12/src/main.rs +++ /dev/null @@ -1,225 +0,0 @@ -use std::fs; - -fn main() -> Result<(), Box<dyn std::error::Error>> { - let input = fs::read_to_string("input")?; - let actions = parse_actions(&input)?; - - // Part 1 - let location = simulate_ship_movement(&actions); - println!("{}", location.0.abs() + location.1.abs()); - - // Part 2 - let location = simulate_waypoint_movement(&actions); - println!("{}", location.0.abs() + location.1.abs()); - - Ok(()) -} - -#[derive(Copy, Clone, Debug)] -enum Action { - North(u32), - South(u32), - East(u32), - West(u32), - Left(u32), - Right(u32), - Forward(u32), -} - -impl Action { - fn new(input: &str) -> Result<Self, String> { - if input.len() < 2 { - Err(format!("Invalud input line: {}", input))?; - } - - let (action, value) = input.split_at(1); - let value = value - .parse() - .map_err(|e| format!("Could not parse value: {}", e))?; - - Ok(match action { - "N" => Self::North(value), - "S" => Self::South(value), - "E" => Self::East(value), - "W" => Self::West(value), - "L" => Self::Left(value), - "R" => Self::Right(value), - "F" => Self::Forward(value), - _ => Err(format!("Could not parse action: {}", action))?, - }) - } - - fn opposite_direction(self) -> Self { - match self { - Action::North(x) => Action::South(x), - Action::South(x) => Action::North(x), - Action::East(x) => Action::West(x), - Action::West(x) => Action::East(x), - _ => panic!("Invalid direction"), - } - } - - fn right_direction(self) -> Self { - match self { - Action::North(x) => Action::East(x), - Action::South(x) => Action::West(x), - Action::East(x) => Action::South(x), - Action::West(x) => Action::North(x), - _ => panic!("Invalid direction"), - } - } - - fn left_direction(self) -> Self { - match self { - Action::North(x) => Action::West(x), - Action::South(x) => Action::East(x), - Action::East(x) => Action::North(x), - Action::West(x) => Action::South(x), - _ => panic!("Invalid direction"), - } - } -} - -fn parse_actions(input: &str) -> Result<Vec<Action>, String> { - input.lines().map(Action::new).collect() -} - -fn simulate_ship_movement(actions: &Vec<Action>) -> (i64, i64) { - let mut coords: (i64, i64) = (0, 0); - let mut direction = Action::East(0); - - for action in actions { - // If the action is Action::Forward, we instead want to move - // in a direction determined by our current angle. - // - // So we convert Action::Forward to a concrete direction. - - let converted_action = if let &Action::Forward(amount) = action { - match direction { - Action::North(_) => Action::North(amount), - Action::South(_) => Action::South(amount), - Action::East(_) => Action::East(amount), - Action::West(_) => Action::West(amount), - _ => unreachable!("Direction can only be NSEW."), - } - } else { - *action - }; - - match converted_action { - Action::North(amount) => { - coords.1 += amount as i64; - } - Action::South(amount) => { - coords.1 -= amount as i64; - } - Action::East(amount) => { - coords.0 += amount as i64; - } - Action::West(amount) => { - coords.0 -= amount as i64; - } - Action::Left(amount) => match amount % 360 { - 0 => direction = direction, - 90 => direction = direction.left_direction(), - 180 => direction = direction.opposite_direction(), - 270 => direction = direction.right_direction(), - _ => panic!("Only 90 degree turns allowed"), - }, - Action::Right(amount) => match amount % 360 { - 0 => direction = direction, - 90 => direction = direction.right_direction(), - 180 => direction = direction.opposite_direction(), - 270 => direction = direction.left_direction(), - _ => panic!("Only 90 degree turns allowed"), - }, - Action::Forward(_) => unreachable!("Converted previously"), - } - } - - coords -} - -fn simulate_waypoint_movement(actions: &Vec<Action>) -> (i64, i64) { - let mut waypoint = (1, 10); - let mut ship = (0, 0); - - for action in actions { - match *action { - Action::North(amount) => { - waypoint.0 += amount as i64; - } - Action::South(amount) => { - waypoint.0 -= amount as i64; - } - Action::East(amount) => { - waypoint.1 += amount as i64; - } - Action::West(amount) => { - waypoint.1 -= amount as i64; - } - Action::Left(amount) => match amount % 360 { - 0 => {} - 90 => waypoint = (waypoint.1, -waypoint.0), - 180 => waypoint = (-waypoint.0, -waypoint.1), - 270 => waypoint = (-waypoint.1, waypoint.0), - _ => panic!("Only 90 degree turns allowed"), - }, - Action::Right(amount) => match amount % 360 { - 0 => {} - 90 => waypoint = (-waypoint.1, waypoint.0), - 180 => waypoint = (-waypoint.0, -waypoint.1), - 270 => waypoint = (waypoint.1, -waypoint.0), - _ => panic!("Only 90 degree turns allowed"), - }, - Action::Forward(amount) => { - ship.0 += waypoint.0 * amount as i64; - ship.1 += waypoint.1 * amount as i64; - } - } - } - - ship -} - -#[cfg(test)] -mod tests { - use super::*; - use indoc::indoc; - - #[test] - fn test_simple() -> Result<(), Box<dyn std::error::Error>> { - let input = indoc!( - "F10 - N3 - F7 - R90 - F11 - " - ); - - let actions = parse_actions(&input)?; - let location = simulate_ship_movement(&actions); - assert_eq!(location.0.abs() + location.1.abs(), 25); - - Ok(()) - } - - #[test] - fn test_simple2() -> Result<(), Box<dyn std::error::Error>> { - let input = indoc!( - "F10 - N3 - F7 - R90 - F11 - " - ); - - let actions = parse_actions(&input)?; - let location = simulate_waypoint_movement(&actions); - assert_eq!(location.0.abs() + location.1.abs(), 286); - - Ok(()) - } -}