This commit is contained in:
Gabe Venberg 2023-12-12 14:14:56 -06:00
parent fb83813662
commit bd5d5ae901
11 changed files with 642 additions and 16 deletions

9
Cargo.lock generated
View file

@ -88,6 +88,15 @@ dependencies = [
"aoc_libs", "aoc_libs",
] ]
[[package]]
name = "day11"
version = "0.1.0"
dependencies = [
"aoc_libs",
"collection_literals",
"itertools",
]
[[package]] [[package]]
name = "either" name = "either"
version = "1.9.0" version = "1.9.0"

View file

@ -0,0 +1,3 @@
pub trait Distances{
fn taxicab_distance(&self, other: &Self)->usize;
}

View file

@ -1,3 +1,4 @@
pub mod points; pub mod points;
pub mod range; pub mod range;
pub mod misc; pub mod misc;
pub mod distances;

View file

@ -1,3 +1,5 @@
use crate::distances::Distances;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash)]
pub struct Point { pub struct Point {
pub x: isize, pub x: isize,
@ -16,6 +18,12 @@ impl Point {
} }
} }
impl Distances for Point {
fn taxicab_distance(&self, other: &Self) -> usize {
self.x.abs_diff(other.x) + self.y.abs_diff(other.y)
}
}
impl std::ops::Add for Point { impl std::ops::Add for Point {
type Output = Point; type Output = Point;
@ -62,7 +70,7 @@ impl std::ops::Neg for Point {
} }
/// an unsigned point in 2d space /// an unsigned point in 2d space
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct UPoint { pub struct UPoint {
pub x: usize, pub x: usize,
pub y: usize, pub y: usize,
@ -80,6 +88,12 @@ impl UPoint {
} }
} }
impl Distances for UPoint {
fn taxicab_distance(&self, other: &Self) -> usize {
self.x.abs_diff(other.x) + self.y.abs_diff(other.y)
}
}
impl std::ops::Add for UPoint { impl std::ops::Add for UPoint {
type Output = UPoint; type Output = UPoint;
@ -184,7 +198,9 @@ where
} }
} }
impl<T, const X: usize, const Y: usize> std::ops::IndexMut<Point> for FourQuadrantMatrix<{ X }, { Y }, T> { impl<T, const X: usize, const Y: usize> std::ops::IndexMut<Point>
for FourQuadrantMatrix<{ X }, { Y }, T>
{
fn index_mut(&mut self, index: Point) -> &mut Self::Output { fn index_mut(&mut self, index: Point) -> &mut Self::Output {
let upoint = index let upoint = index
.to_upoint(&self.zero_coord) .to_upoint(&self.zero_coord)
@ -193,7 +209,9 @@ impl<T, const X: usize, const Y: usize> std::ops::IndexMut<Point> for FourQuadra
} }
} }
impl<T, const X: usize, const Y: usize> std::ops::Index<Point> for FourQuadrantMatrix<{ X }, { Y }, T> { impl<T, const X: usize, const Y: usize> std::ops::Index<Point>
for FourQuadrantMatrix<{ X }, { Y }, T>
{
type Output = T; type Output = T;
fn index(&self, index: Point) -> &Self::Output { fn index(&self, index: Point) -> &Self::Output {

View file

@ -115,19 +115,6 @@ mod tests {
assert_eq!(input.num_ways_to_win(), 71503); assert_eq!(input.num_ways_to_win(), 71503);
} }
#[test]
fn test_distance_given_charge_time() {
let input = Race { time: 7, record: 9 };
assert_eq!(input.distance_given_charge_time(0), 0);
assert_eq!(input.distance_given_charge_time(1), 6);
assert_eq!(input.distance_given_charge_time(2), 10);
assert_eq!(input.distance_given_charge_time(3), 12);
assert_eq!(input.distance_given_charge_time(4), 12);
assert_eq!(input.distance_given_charge_time(5), 10);
assert_eq!(input.distance_given_charge_time(6), 6);
assert_eq!(input.distance_given_charge_time(7), 0);
}
#[test] #[test]
fn test_parse_part2() { fn test_parse_part2() {
let input = concat!("Time: 7 15 30\n", "Distance: 9 40 200\n",); let input = concat!("Time: 7 15 30\n", "Distance: 9 40 200\n",);

11
days/day11/Cargo.toml Normal file
View file

@ -0,0 +1,11 @@
[package]
name = "day11"
authors.workspace = true
description.workspace = true
version.workspace = true
edition.workspace = true
[dependencies]
aoc_libs.workspace = true
collection_literals.workspace = true
itertools.workspace = true

140
days/day11/src/input.txt Normal file
View file

@ -0,0 +1,140 @@
.#..........#.....................#........................................................#....................................#...........
...................#........................................#......................#........................................................
...........................................#......#..................#...................................................#..................
....#......................#...............................................#.........................#.....#......#................#........
.................................................................#.......................#..................................................
..............................................................................................................................#.............
.......#........#.............#...................................................#...................................#.....................
.........................#...................................#............................................................................#.
....................#.............#.........#..........................................#...............#....................................
.....................................................#...............#.............................................................#........
...........................................................................................................................#................
..........................................................#.........................................#...............#.......................
..............................................................................................#.............................................
.#........#........................#......#..............................................#..............................#...............#...
...............#......#...............................#.......#.........#......#.............................#.................#............
...............................#..............#.............................................................................................
............................................................................................................................................
.........................#.......................................#..........................................................................
..................#........................#......................................#........................................#................
..................................................#.......#..............................................#........................#.......#.
...#........#........................#....................................#...............#.................................................
............................................................................................................................................
.......#........................#....................................................................................#......................
...............#...........#........................................................................#.......................................
.............................................#................#.........#.............................................................#.....
...........#...........................#................#...........................#.......................................................
..................................................#.......................................#.............#...................................
.....#..................#..........#..............................#.............................#........................................#..
..............................#...............................................................................................#.............
...................................................................................................................#........................
..............#..........................................#.............#...........................#..............................#.........
...#...................................#.........................................#..........................................................
..................#...................................................................#................................................#....
..........................#...................................#.........................................#...................................
............................................................................................................................................
.........#...........#..........#..........................................#....................#..............#........#.....#...........#.
....................................................#.......................................................................................
.............................................#..............................................................................................
......................................#..................#..............................#...........#.......#...............................
............................#..................................#..............#.............................................................
...............#............................................................................................................................
...........................................#............................#.......................#...........................................
.....#..............#.................................................................................#...........................#.........
............................................................................................................................................
........................................#..........#.................#..........................................#...........................
.............................................#.................................#...........#................................................
...............................#.......................#...........................................#.......#....................#...........
#........#.............#...............................................................................................#...................#
.....................................#........................#..........#.........#........................................................
.................#............................................................................#.............................................
..........................#.......................................#.................................................#.......................
.....................................................#...................................#....................................#.............
..#.........................................................................................................................................
.............#.....#.......................#.............#....................................................#........................#....
......#........................................................................................#............................................
.................................#.................................#........................................................................
.................................................................................#.......................#................................#.
#.....................................................#...................................................................#.....#...........
.........#..................................................#......................................#........................................
..............................#.............#.................................................................#.......#.....................
........................#............................................................#......#................................#..............
.............#..............................................................................................................................
.....#........................................................#............#..........................#...........................#.........
...........................#......#.................................................................................#...................#...
.........#.....................................#...............................#............................................................
..................#.......................................#.......#................................#........................................
...............................#.....................#...................................#................................#.................
..............#..........................#.............................#............#.....................#.....................#.........#.
.................................................................................................................#..........................
......#.....................................................................................................................................
...........#.............#.........#........................................................................................................
...................................................................#..............#..................#......................................
..................#...........................................................................................#.............................
........#.................................#..............#.................................................................#..........#.....
...#.....................................................................#..............#.......#...........................................
............................................................................................................................................
............................................................................................................................................
.................................#................#..........................................................#...............#.............#
..............#............................................................#................................................................
......#.....................#..........................#........#.....#............#..............#.........................................
....................#..................................................................................#..................#.................
....................................#.........#........................................................................................#....
..........................................................#..............#..................................................................
................#...............................................................................................#.............#.............
............................................................................................................................................
............................#...................#......#.............#..............................................#.......................
.............#...................................................................................#........................................#.
......................#..........................................................#.......#..................................................
#...........................................................#...............................................................................
.........#.........................#.................#....................................................#.................#...............
............................................................................................................................................
...................#.............................................#.....#....................................................................
........................#.........................#.....................................................................................#...
.....#........................................................................................................................#.............
.......................................#...............................................................#.........#..........................
............................#...........................#...........#......................#..............................#.......#.........
..#................................#...........#............................................................................................
.................#..................................#...................#...................................................................
..........#.................................................#................................................#..............................
.....................#...............................................................................#......................................
..............#..................#..............................#.............#....................................#.........#........#.....
...#.............................................................................................#..........................................
............................................#..........................................#....................................................
.........#...............................................#..............................................................#...................
................#.........#.................................................................................................................
.....#..................................#............................#..............................#........#..................#..........#
...............................#............................................................................................................
....................................................#........#..............................................................................
........#..........................#.........#...............................................................................#..............
....................................................................................................................#.......................
....................#........#......................................#.........#.....#.....#.................................................
................................................................................................................................#.....#.....
...............#..........................................#...............#...............................#.................................
...#..............................#.........................................................................................................
........................................................................................#............#....................................#.
............................................................................................................................#...............
...................................................................................#............................#...........................
#........#........#........#..........#.........#...........................................................................................
.............................................................#..............................#............................#..................
................................#.......................#...................................................................................
.......................#................................................#...............#.........#..................#................#.....
............#..................................................................#........................#...................................
............................................................................................................................................
......#.....................#.......#......#..............#......#..........................................................................
.....................#......................................................................................................................
................................#................................................#.............#...........................#.............#..
..............................................................................................................#.............................
............#............#..........................................................................#.............................#.........
.....#...........#.....................#.............................#.....#........................................#.......................
................................................#...........#..........................#....................................................
............................................................................................................................................
#..........................#.....#................................................................#......................................#..
..........................................#.................................................................#.............#.................
................#.........................................................#.................................................................
.......#..............................#..............................................#..........................................#...........
........................#...................................#...............................................................................
............................................................................................................................#...............
..............................#.....................#.............................#...........#.................#...........................
...............................................#................#.....#................................................#....................
...................#...................#.................#.................#.........................#......................................

14
days/day11/src/main.rs Normal file
View file

@ -0,0 +1,14 @@
mod part1;
mod part2;
mod parse;
fn main() {
let input = include_str!("./input.txt");
let structured_input = parse::parse(input);
println!("Part One");
println!("Result: {}", part1::part1(&structured_input));
println!("Part Two");
println!("Result: {}", part2::part2(&structured_input));
}

388
days/day11/src/parse.rs Normal file
View file

@ -0,0 +1,388 @@
use std::collections::HashSet;
use aoc_libs::distances::Distances;
use aoc_libs::points::UPoint;
use itertools::Itertools;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Space {
Galaxy,
Space,
}
#[derive(Debug, PartialEq, Eq)]
pub struct SparseSpace {
galaxies: HashSet<UPoint>,
empty_rows: HashSet<usize>,
empty_columns: HashSet<usize>,
}
impl SparseSpace {
pub fn get_distance_between_galaxies(
&self,
galaxy1: &UPoint,
galaxy2: &UPoint,
expantion: &usize,
) -> usize {
// println!("distance between {:?} and {:?}", galaxy1, galaxy2);
//get unexpanded distance.
let mut distance = galaxy1.taxicab_distance(galaxy2);
// println!("unexpanded distance is {}", distance);
//expand rows
for y in galaxy1.y.min(galaxy2.y)+1..galaxy1.y.max(galaxy2.y) {
if self.empty_rows.contains(&y) {
// println!("expanding row {}", y);
distance += expantion
}
}
//expand columns.
for x in galaxy1.x.min(galaxy2.x)+1..galaxy1.x.max(galaxy2.x) {
if self.empty_columns.contains(&x) {
// println!("expanding col {}", x);
distance += expantion
}
}
distance
}
pub fn get_sum_of_distances(&self, expantion: usize) -> usize {
self.galaxies
.iter()
.combinations(2)
// .inspect(|pair| println!("{:?}", pair))
.map(|pair| self.get_distance_between_galaxies(pair[0], pair[1], &expantion))
// .inspect(|distance| println!("{:?}", distance))
.sum()
}
}
impl From<Vec<Vec<Space>>> for SparseSpace {
fn from(value: Vec<Vec<Space>>) -> Self {
let mut galaxies: HashSet<UPoint> = HashSet::new();
let mut empty_rows: HashSet<usize> = HashSet::new();
let mut empty_columns: HashSet<usize> = HashSet::new();
//find all galaxies and empty rows.
for (y, row) in value.iter().enumerate() {
let mut has_galaxy = false;
for (x, space) in row.iter().enumerate() {
if *space == Space::Galaxy {
has_galaxy = true;
galaxies.insert(UPoint { x, y });
};
}
if !has_galaxy {
empty_rows.insert(y);
};
}
//find all empty columns
for x in 0..value[0].len() {
let mut has_galaxy = false;
for y in 0..value.len() {
if value[y][x] == Space::Galaxy {
has_galaxy = true;
}
}
if !has_galaxy {
empty_columns.insert(x);
};
}
SparseSpace {
galaxies,
empty_rows,
empty_columns,
}
}
}
pub fn parse(input: &str) -> SparseSpace {
parse_to_space(input).into()
}
pub fn parse_to_space(input: &str) -> Vec<Vec<Space>> {
input
.lines()
.map(|l| {
l.chars()
.map(|c| match c {
'#' => Space::Galaxy,
'.' => Space::Space,
_ => panic!("unexpected char {}", c),
})
.collect()
})
.collect()
}
#[cfg(test)]
mod tests {
use collection_literals::collection;
use super::*;
#[test]
fn test_get_sum_of_distances() {
let tested = SparseSpace {
galaxies: collection! {
UPoint { x: 0, y: 2 },
UPoint { x: 0, y: 9 },
UPoint { x: 1, y: 5 },
UPoint { x: 3, y: 0 },
UPoint { x: 4, y: 9 },
UPoint { x: 6, y: 4 },
UPoint { x: 7, y: 1 },
UPoint { x: 7, y: 8 },
UPoint { x: 9, y: 6 }
},
empty_rows: collection! {3, 7},
empty_columns: collection! {2, 5, 8},
};
assert_eq!(tested.get_sum_of_distances(1), 374)
}
#[test]
fn test_get_distance_between_galaxies() {
let tested = SparseSpace {
galaxies: collection! {
UPoint { x: 0, y: 2 },
UPoint { x: 0, y: 9 },
UPoint { x: 1, y: 5 },
UPoint { x: 3, y: 0 },
UPoint { x: 4, y: 9 },
UPoint { x: 6, y: 4 },
UPoint { x: 7, y: 1 },
UPoint { x: 7, y: 8 },
UPoint { x: 9, y: 6 }
},
empty_rows: collection! {3, 7},
empty_columns: collection! {2, 5, 8},
};
assert_eq!(
tested.get_distance_between_galaxies(
&UPoint { x: 4, y: 9 },
&UPoint { x: 1, y: 5 },
&1
),
9
);
assert_eq!(
tested.get_distance_between_galaxies(
&UPoint { x: 7, y: 8 },
&UPoint { x: 0, y: 3 },
&1
),
15
);
assert_eq!(
tested.get_distance_between_galaxies(
&UPoint { x: 0, y: 2 },
&UPoint { x: 9, y: 6 },
&1
),
17
);
assert_eq!(
tested.get_distance_between_galaxies(
&UPoint { x: 0, y: 9 },
&UPoint { x: 4, y: 9 },
&1
),
5
);
assert_eq!(
tested.get_distance_between_galaxies(
&UPoint { x: 3, y: 0 },
&UPoint { x: 6, y: 4 },
&1
),
9
);
assert_eq!(
tested.get_distance_between_galaxies(
&UPoint { x: 7, y: 8 },
&UPoint { x: 7, y: 8 },
&1
),
0
);
}
#[test]
fn test_parse() {
let input = concat!(
"...#......\n",
".......#..\n",
"#.........\n",
"..........\n",
"......#...\n",
".#........\n",
".........#\n",
"..........\n",
".......#..\n",
"#...#.....\n",
);
assert_eq!(
parse(input),
SparseSpace {
galaxies: collection! {
UPoint { x: 0, y: 2 },
UPoint { x: 0, y: 9 },
UPoint { x: 1, y: 5 },
UPoint { x: 3, y: 0 },
UPoint { x: 4, y: 9 },
UPoint { x: 6, y: 4 },
UPoint { x: 7, y: 1 },
UPoint { x: 7, y: 8 },
UPoint { x: 9, y: 6 }
},
empty_rows: collection! {3, 7},
empty_columns: collection! {2, 5, 8}
}
)
}
#[test]
fn test_parse_to_space() {
let input = concat!(
"...#......\n",
".......#..\n",
"#.........\n",
"..........\n",
"......#...\n",
".#........\n",
".........#\n",
"..........\n",
".......#..\n",
"#...#.....\n",
);
assert_eq!(
parse_to_space(input),
vec![
vec![
Space::Space,
Space::Space,
Space::Space,
Space::Galaxy,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space
],
vec![
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Galaxy,
Space::Space,
Space::Space
],
vec![
Space::Galaxy,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space
],
vec![
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space
],
vec![
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Galaxy,
Space::Space,
Space::Space,
Space::Space
],
vec![
Space::Space,
Space::Galaxy,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space
],
vec![
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Galaxy
],
vec![
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space
],
vec![
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Galaxy,
Space::Space,
Space::Space
],
vec![
Space::Galaxy,
Space::Space,
Space::Space,
Space::Space,
Space::Galaxy,
Space::Space,
Space::Space,
Space::Space,
Space::Space,
Space::Space
]
]
);
}
}

27
days/day11/src/part1.rs Normal file
View file

@ -0,0 +1,27 @@
use crate::parse::*;
pub fn part1(input: &SparseSpace) -> usize {
input.get_sum_of_distances(1)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() {
let input = concat!(
"...#......\n",
".......#..\n",
"#.........\n",
"..........\n",
"......#...\n",
".#........\n",
".........#\n",
"..........\n",
".......#..\n",
"#...#.....\n",
);
assert_eq!(part1(&parse(input)), 374)
}
}

28
days/day11/src/part2.rs Normal file
View file

@ -0,0 +1,28 @@
use crate::parse::*;
pub fn part2(input: &SparseSpace) -> usize {
input.get_sum_of_distances(999_999)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part2() {
let input = concat!(
"...#......\n",
".......#..\n",
"#.........\n",
"..........\n",
"......#...\n",
".#........\n",
".........#\n",
"..........\n",
".......#..\n",
"#...#.....\n",
);
assert_eq!(parse(input).get_sum_of_distances(9), 1030);
assert_eq!(parse(input).get_sum_of_distances(99), 8410);
}
}