From 19e219bcc33108ceca17b5048a66a419f8f65621 Mon Sep 17 00:00:00 2001 From: Joseph Montanaro Date: Thu, 9 Dec 2021 12:56:44 -0800 Subject: [PATCH] day 7 --- 2021/src/day7.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 2021/src/main.rs | 6 ++--- 2 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 2021/src/day7.rs diff --git a/2021/src/day7.rs b/2021/src/day7.rs new file mode 100644 index 0000000..1f9fdb1 --- /dev/null +++ b/2021/src/day7.rs @@ -0,0 +1,61 @@ +use color_eyre::eyre; + + +#[derive(Default)] +struct Map { + counts: Vec, // index is position, value is how many at that position + index: Vec, // values are indices of `counts`, sorted from most to least +} + +impl Map { + fn from(nums: &[usize]) -> Map { + let hi = nums.iter().max().unwrap_or(&0); + let mut counts = vec![0; hi + 1]; + for n in nums { + counts[*n] += 1; + } + let mut index: Vec = (0..counts.len()).collect(); + index.sort_by(|&a, &b| counts[b].cmp(&counts[a])); // flip the comparison function to sort in reverse + + Map {counts, index} + } + + fn cost_simple(&self, pos: usize) -> usize { + let mut total = 0; + for (i, count) in self.counts.iter().enumerate() { + let distance = if pos > i {pos - i} else {i - pos}; + total += distance * count; + } + total + } + + fn cost_complex(&self, pos: usize) -> usize { + let mut total = 0; + for (i, count) in self.counts.iter().enumerate() { + let distance = if pos > i {pos -i} else {i - pos}; + let cost_single = distance * (distance + 1) / 2; // Gauss' method for summing numbers 0 to n + total += cost_single * count; + } + total + } +} + + +pub fn run(data: &str) -> eyre::Result<(usize, usize)> { + let nums = data.trim().split(',') + .map(|s| s.parse::()) + .collect::, _>>()?; + let map = Map::from(&nums); + + let mut min_simple = usize::MAX; + let mut min_complex = usize::MAX; + for i in 0..map.counts.len() { + let simple = map.cost_simple(i); + if simple < min_simple {min_simple = simple;} + + let complex = map.cost_complex(i); + if complex < min_complex {min_complex = complex;} + } + + Ok((min_simple, min_complex)) +} diff --git a/2021/src/main.rs b/2021/src/main.rs index 979da0d..ecb01fe 100644 --- a/2021/src/main.rs +++ b/2021/src/main.rs @@ -4,14 +4,14 @@ use color_eyre::eyre; mod lib; use lib::load; -mod day6; +mod day7; fn main() -> eyre::Result<()> { - let data = load("data/06.txt")?; + let data = load("data/07.txt")?; let start = Instant::now(); - let (one, two) = day6::run(&data)?; + let (one, two) = day7::run(&data)?; let (dur, unit) = format_ns(start.elapsed().as_nanos()); let precision = 2.0 - dur.log10().floor();