diff --git a/Cargo.lock b/Cargo.lock index 31a8806..275595c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -88,3 +88,11 @@ dependencies = [ [[package]] name = "d10t2" version = "0.1.0" + +[[package]] +name = "d11t1" +version = "0.1.0" + +[[package]] +name = "d11t2" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 0606f18..683a293 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,4 +23,6 @@ members = [ "d09t2", "d10t1", "d10t2", + "d11t1", + "d11t2", ] diff --git a/d11t1/Cargo.toml b/d11t1/Cargo.toml new file mode 100644 index 0000000..311bfae --- /dev/null +++ b/d11t1/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "d11t1" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/d11t1/demo_input.txt b/d11t1/demo_input.txt new file mode 100644 index 0000000..a0bda53 --- /dev/null +++ b/d11t1/demo_input.txt @@ -0,0 +1,10 @@ +...#...... +.......#.. +#......... +.......... +......#... +.#........ +.........# +.......... +.......#.. +#...#..... \ No newline at end of file diff --git a/d11t1/src/main.rs b/d11t1/src/main.rs new file mode 100644 index 0000000..10d674d --- /dev/null +++ b/d11t1/src/main.rs @@ -0,0 +1,70 @@ +use std::fs::read_to_string; + +fn main() { + let input = read_to_string("input.txt").unwrap(); + println!("d11t1: {}", d11t1(&input)); +} + +#[derive(Clone, Copy, Debug)] +struct Galaxy { + col: usize, + row: usize, +} + +#[must_use] +pub fn d11t1(input: &str) -> usize { + let lines = input.lines(); + let width = lines.clone().next().unwrap().len(); + let mut expanded_lines = Vec::::new(); + for line in lines { + if line.chars().all(|c| c == '.') { + expanded_lines.push(".".repeat(width)); + } + expanded_lines.push(line.to_string()); + } + let mut fields = vec![String::new(); expanded_lines.len()]; + let expanded_lines = expanded_lines + .into_iter() + .map(|l| l.chars().collect::>()) + .collect::>(); + for col in 0..width { + if expanded_lines.iter().all(|row| row[col] == '.') { + for (row_idx, row) in expanded_lines.iter().enumerate() { + fields[row_idx].extend(['.', row[col]]); + } + } else { + for (row_idx, row) in expanded_lines.iter().enumerate() { + fields[row_idx].extend([row[col]]); + } + } + } + let galaxies = fields + .iter() + .enumerate() + .flat_map(|(row, line)| { + line.chars() + .enumerate() + .filter(|&(_col, c)| c == '#') + .map(move |(col, _)| Galaxy { col, row }) + }) + .collect::>(); + let mut res = 0; + for (idx, galaxy) in galaxies.clone().into_iter().enumerate() { + res += galaxies + .iter() + .skip(idx + 1) + .map(|g| g.col.abs_diff(galaxy.col) + g.row.abs_diff(galaxy.row)) + .sum::(); + } + res +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_d11t1() { + let input = include_str!("../demo_input.txt"); + assert_eq!(d11t1(input), 374); + } +} diff --git a/d11t2/Cargo.toml b/d11t2/Cargo.toml new file mode 100644 index 0000000..54bbb07 --- /dev/null +++ b/d11t2/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "d11t2" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/d11t2/demo_input.txt b/d11t2/demo_input.txt new file mode 100644 index 0000000..a0bda53 --- /dev/null +++ b/d11t2/demo_input.txt @@ -0,0 +1,10 @@ +...#...... +.......#.. +#......... +.......... +......#... +.#........ +.........# +.......... +.......#.. +#...#..... \ No newline at end of file diff --git a/d11t2/src/main.rs b/d11t2/src/main.rs new file mode 100644 index 0000000..09005fd --- /dev/null +++ b/d11t2/src/main.rs @@ -0,0 +1,75 @@ +use std::fs::read_to_string; + +fn main() { + let input = read_to_string("input.txt").unwrap(); + println!("d11t2: {}", d11t2(&input, 1_000_000)); +} + +#[derive(Clone, Copy, Debug)] +struct Galaxy { + col: usize, + row: usize, +} + +#[must_use] +pub fn d11t2(input: &str, factor: usize) -> usize { + let lines = input.lines(); + let width = lines.clone().next().unwrap().len(); + + let fields = lines + .into_iter() + .map(|l| l.chars().collect::>()) + .collect::>(); + let empty_rows = fields + .iter() + .enumerate() + .filter(|(_, row)| row.iter().all(|c| *c == '.')) + .map(|(idx, _)| idx) + .collect::>(); + let empty_cols = (0..width) + .filter(|&col| fields.iter().all(|row| row[col] == '.')) + .collect::>(); + let galaxies = fields + .iter() + .enumerate() + .flat_map(|(row, line)| { + line.iter() + .enumerate() + .filter(|&(_col, c)| *c == '#') + .map(move |(col, _)| Galaxy { col, row }) + }) + .collect::>(); + let get_distances = |(a, b): (Galaxy, Galaxy)| -> usize { + a.col.abs_diff(b.col) + + a.row.abs_diff(b.row) + + (((a.col.min(b.col))..=(a.col.max(b.col))) + .filter(|col| empty_cols.contains(col)) + .count() + + ((a.row.min(b.row))..=(a.row.max(b.row))) + .filter(|row| empty_rows.contains(row)) + .count()) + * (factor - 1) + }; + galaxies + .clone() + .into_iter() + .enumerate() + .flat_map(|(idx, galaxy)| galaxies.iter().skip(idx + 1).map(move |g| (galaxy, *g))) + .map(get_distances) + .sum::() +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_d11t2_10() { + let input = include_str!("../demo_input.txt"); + assert_eq!(d11t2(input, 10), 1030); + } + #[test] + fn test_d11t2_100() { + let input = include_str!("../demo_input.txt"); + assert_eq!(d11t2(input, 100), 8410); + } +}