diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2f7896d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/day-11/Cargo.lock b/day-11/Cargo.lock new file mode 100644 index 0000000..5e329eb --- /dev/null +++ b/day-11/Cargo.lock @@ -0,0 +1,78 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "day-11" +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-11/Cargo.toml b/day-11/Cargo.toml new file mode 100644 index 0000000..5cf3b01 --- /dev/null +++ b/day-11/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "day-11" +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-11/input b/day-11/input new file mode 100644 index 0000000..7cf41d9 --- /dev/null +++ b/day-11/input @@ -0,0 +1,93 @@ +LLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLLLL.LL.LLLLLLLL.LLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLL.L.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +..L...L.L..L.LL.....L.L..L...L.L.....L.L...LLL..L....L.L.LL.LL...L.....LLL.....L...L..L..L....... +LLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLL.LLLL.LLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLL.LLLL.LLLLLLLLLLLLL +.....LLL....L..L.L..L.L..L...L.L.LL.....L...L..LL.LL..L.L.LL...LL....LL.....L.....L.L.LL.L..L.L.. +LLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLL.LLLL.L.LLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLL..LLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LL.LLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLLLLLLL.LLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL +..L.L.LL.L..LL..L..LL.L..L................L....L............L.L..L...L...L..LLLL....L.L..LL....L. +LLLLLL.LLL.LLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLL.L.LLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLL.LLLL.LLL.LLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLL.LLL.L.LLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LL.L.L.L.....L..L...L.L...L.......L...LLL...L.LL.L.....L.LLL.LL....LLLLL.L....LLL.L..LL..L....L.L +LLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLL +LLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLLLL.L.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLLLL.LLLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLL.LLL +.L.LL..LL...L....LL...L.LL.L....LL.LL......L..L........LL..LLL..L...LLL.....LL....L.L...L.....L.. +LLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLL.LLL.LLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLL.L.LLLLLLLLLLLLL +.LLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLL.L.LLLLLL.LLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLL.LLLL.LLLLL.LLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLL.LLL.LLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLL +..L....LL..LL.LLLL......L..L...LLL.L......L.L.....L....L....LLLL.....L..LL...L....L....LLL....LL. +LLLLLLLLLLLLLLL.LLLL.LLLLL.LLLLLLLL..LLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLL.LLLL.LLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLL..LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLL.LLLLL.LLLLLLL.LLL.LLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLL..LLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLL.LL +LLLLLLLLLLLLLLL.LLL..LLLLLLLL.LL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLL +...LL.LL.....LL..LLL.....LL....LL....L.LL.L.LL....L........LLLL..LLLLLL.L..L..LLL......L....L.... +LLL.LLLLLLLLLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LL.LLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLL.LLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLL +.....L.L..LL..LL..L.L.L.....LLLLL.....L..L...L.....L.L..L..L....LL....L...........L.L.......L.LLL +LLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLL.LLLLLL.LLLL.LLLL.LLLLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLL..LLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLL.LLLLLLL.L.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL +LLLL.L.LLL.LLLL.LLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLLLL.LLLLLLLL.LL.L.LLLLLLLL +L.LLL.................LLL....L...LL..........L.L.L.......L.....L.....LLLLLL......L.......L...L.LL +LLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLL.LL.LLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLL.LL +LLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLL.LLL.LLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLL.LLLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLL.LLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLL..LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLLLL.LLLL.LLLLLLLL +..L...LL.LLL.LLL.......LL..LL.L...LLL.....L....LLLL.L..........L.....L.L....L..............LL.L.. +LLLLLLLLLL.LLLL.LLL..LLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLLLLLLL.LLL.LLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLL.LLLLLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLL.LL.LLLLLLLL +LLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLL.LLLLL.LLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLLLLLLLLLLL.LL.LL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LL.L.L..LL..L.......L.L..LL....L.L.L...L.L..LL....LL.LL....L....LL..L....L............L.......L.. +LLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLL.L.LLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL +..L.L.....L......L..L.....L.......L..L....LL...L.L.L...LLL.L.L..L..L..L......LLL.....L..L..L..... +LLLLLLLLLLLLLLL.LLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLL.LLLLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLL.LLLLLLLLLLLL.LLLLLL.L.LLLLLL.LLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLL..LLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLL.LLLLLLLLL.LL.LLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL diff --git a/day-11/src/main.rs b/day-11/src/main.rs new file mode 100644 index 0000000..886261d --- /dev/null +++ b/day-11/src/main.rs @@ -0,0 +1,180 @@ +use std::fs; + +fn main() -> Result<(), Box<dyn std::error::Error>> { + let input = fs::read_to_string("input")?; + let layout = parse_layout(&input)?; + + // Part 1 + let result = count_eventually_occupied_seats(&layout); + println!("{}", result); + + Ok(()) +} + +#[derive(Copy, Clone, Debug, PartialEq)] +enum Seating { + Occupied, + Empty, + Floor, +} + +impl Seating { + fn new(symbol: char) -> Result<Self, String> { + match symbol { + '#' => Ok(Seating::Occupied), + 'L' => Ok(Seating::Empty), + '.' => Ok(Seating::Floor), + rubbish => Err(format!("Found some rubbish on the floor, area must be clean to conserve human behavior: {}", rubbish)) + } + } +} + +fn parse_layout(input: &str) -> Result<Vec<Vec<Seating>>, String> { + input + .lines() + .map(|line| line.chars().map(Seating::new).collect()) + .collect() +} + +fn print_layout(layout: &Vec<Vec<Seating>>) { + let output: String = layout + .iter() + .map(|row| { + let mut row: String = row + .iter() + .map(|c| match c { + Seating::Occupied => '#', + Seating::Empty => 'L', + Seating::Floor => '.', + }) + .collect(); + row.push('\n'); + row + }) + .collect(); + + println!("{}", output); +} + +fn get_adjacent(layout: &Vec<Vec<Seating>>, i: usize, j: usize) -> Vec<Option<&Seating>> { + let adjacent: [[usize; 2]; 8] = [ + [0, 0], + [0, 1], + [0, 2], + [1, 0], + [1, 2], + [2, 0], + [2, 1], + [2, 2], + ]; + + adjacent + .iter() + .map(|[nudge_row, nudge_col]| { + if let Some(row) = (i + nudge_row).checked_sub(1) { + if let Some(row) = layout.get(row) { + if let Some(col) = (j + nudge_col).checked_sub(1) { + row.get(col) + } else { + None + } + } else { + None + } + } else { + None + } + }) + .collect() +} + +fn simulate_people(layout: &Vec<Vec<Seating>>) -> (Vec<Vec<Seating>>, usize) { + let mut changes = 0; + + let layout = layout + .iter() + .enumerate() + .map(|(i, row)| { + row.iter() + .enumerate() + .map(|(j, seat)| match seat { + Seating::Occupied => { + if get_adjacent(layout, i, j) + .iter() + .filter(|seat| **seat == Some(&Seating::Occupied)) + .count() + >= 4 + { + changes += 1; + Seating::Empty + } else { + Seating::Occupied + } + } + Seating::Empty => { + if get_adjacent(layout, i, j) + .iter() + .any(|seat| *seat == Some(&Seating::Occupied)) + { + Seating::Empty + } else { + changes += 1; + Seating::Occupied + } + } + Seating::Floor => Seating::Floor, + }) + .collect() + }) + .collect(); + + (layout, changes) +} + +fn count_eventually_occupied_seats(layout: &Vec<Vec<Seating>>) -> usize { + let mut loop_layout = layout.clone(); + + loop { + let (res, changes) = simulate_people(&loop_layout); + loop_layout = res; + + if changes == 0 { + break; + } + } + + loop_layout + .iter() + .flatten() + .filter(|seat| **seat == Seating::Occupied) + .count() +} + +#[cfg(test)] +mod tests { + use super::*; + use indoc::indoc; + + #[test] + fn test_simple() -> Result<(), Box<dyn std::error::Error>> { + let input = indoc!( + "L.LL.LL.LL + LLLLLLL.LL + L.L.L..L.. + LLLL.LL.LL + L.LL.LL.LL + L.LLLLL.LL + ..L.L..... + LLLLLLLLLL + L.LLLLLL.L + L.LLLLL.LL + " + ); + + let layout = parse_layout(&input)?; + let result = count_eventually_occupied_seats(&layout); + + assert_eq!(result, 37); + Ok(()) + } +} diff --git a/day-12/Cargo.lock b/day-12/Cargo.lock new file mode 100644 index 0000000..b7e1235 --- /dev/null +++ b/day-12/Cargo.lock @@ -0,0 +1,78 @@ +# 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 new file mode 100644 index 0000000..35cad43 --- /dev/null +++ b/day-12/Cargo.toml @@ -0,0 +1,10 @@ +[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 new file mode 100644 index 0000000..bedc29a --- /dev/null +++ b/day-12/input @@ -0,0 +1,771 @@ +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 new file mode 100644 index 0000000..dc2ef28 --- /dev/null +++ b/day-12/src/main.rs @@ -0,0 +1,161 @@ +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()); + + 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 +} + +#[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(()) + } +}