This commit is contained in:
Joseph Montanaro 2021-12-09 12:56:44 -08:00
parent d77c4ed0c9
commit 19e219bcc3
2 changed files with 64 additions and 3 deletions

61
2021/src/day7.rs Normal file
View File

@ -0,0 +1,61 @@
use color_eyre::eyre;
#[derive(Default)]
struct Map {
counts: Vec<usize>, // index is position, value is how many at that position
index: Vec<usize>, // 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<usize> = (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::<usize>())
.collect::<Result<Vec<_>, _>>()?;
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))
}

View File

@ -4,14 +4,14 @@ use color_eyre::eyre;
mod lib; mod lib;
use lib::load; use lib::load;
mod day6; mod day7;
fn main() -> eyre::Result<()> { fn main() -> eyre::Result<()> {
let data = load("data/06.txt")?; let data = load("data/07.txt")?;
let start = Instant::now(); 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 (dur, unit) = format_ns(start.elapsed().as_nanos());
let precision = 2.0 - dur.log10().floor(); let precision = 2.0 - dur.log10().floor();