day 9 cleanup
This commit is contained in:
67
src/day09.rs
67
src/day09.rs
@@ -1,7 +1,5 @@
|
|||||||
use std::{collections::BTreeMap, fs::read_to_string};
|
use std::{collections::BTreeMap, fs::read_to_string};
|
||||||
|
|
||||||
use itertools::Itertools;
|
|
||||||
|
|
||||||
pub fn day_main() {
|
pub fn day_main() {
|
||||||
let input = read_to_string("input/day09.txt").unwrap();
|
let input = read_to_string("input/day09.txt").unwrap();
|
||||||
let input = input.trim();
|
let input = input.trim();
|
||||||
@@ -55,8 +53,8 @@ fn part1(input: &str) -> RiddleResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn part2(input: &str) -> RiddleResult {
|
fn part2(input: &str) -> RiddleResult {
|
||||||
// (start_index, len, file_id)
|
|
||||||
let mut free: BTreeMap<usize, usize> = BTreeMap::new();
|
let mut free: BTreeMap<usize, usize> = BTreeMap::new();
|
||||||
|
// (start_index, len, file_id)
|
||||||
let mut files: Vec<(usize, usize, usize)> = Vec::with_capacity(input.len() / 2 + 1);
|
let mut files: Vec<(usize, usize, usize)> = Vec::with_capacity(input.len() / 2 + 1);
|
||||||
let mut head = 0;
|
let mut head = 0;
|
||||||
for (i, l) in input.chars().enumerate() {
|
for (i, l) in input.chars().enumerate() {
|
||||||
@@ -70,13 +68,15 @@ fn part2(input: &str) -> RiddleResult {
|
|||||||
}
|
}
|
||||||
for file in files.iter_mut().rev() {
|
for file in files.iter_mut().rev() {
|
||||||
let (start_index, length, _file_id) = *file;
|
let (start_index, length, _file_id) = *file;
|
||||||
let found = free.iter().find(|f| *f.1 >= length && *f.0 < start_index);
|
let found = free
|
||||||
|
.iter()
|
||||||
|
.take_while(|f| *f.0 < start_index)
|
||||||
|
.find(|f| *f.1 >= length);
|
||||||
|
|
||||||
if let Some((&free_start, &free_length)) = found.clone() {
|
if let Some((&free_start, &free_length)) = found.clone() {
|
||||||
free.remove(&free_start);
|
free.remove(&free_start);
|
||||||
free.insert(start_index, length);
|
free.insert(start_index, length);
|
||||||
file.0 = free_start;
|
file.0 = free_start;
|
||||||
merge(&mut free, start_index);
|
|
||||||
if length < free_length {
|
if length < free_length {
|
||||||
free.insert(free_start + length, free_length - length);
|
free.insert(free_start + length, free_length - length);
|
||||||
}
|
}
|
||||||
@@ -91,34 +91,8 @@ fn part2(input: &str) -> RiddleResult {
|
|||||||
.sum()
|
.sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merge(free: &mut BTreeMap<usize, usize>, start_index: usize) {
|
|
||||||
let mut current = start_index;
|
|
||||||
if let Some((&left, &left_length)) = free.range(0..start_index).last() {
|
|
||||||
if left + left_length == start_index {
|
|
||||||
*free.get_mut(&left).unwrap() += free.remove(&start_index).unwrap();
|
|
||||||
current = left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if current == *free.last_entry().unwrap().key() {
|
|
||||||
return; // make sure we don't try to access a range starting > max, panics
|
|
||||||
}
|
|
||||||
if let Some((&right, &_right_length)) = free.range(current + 1..).next() {
|
|
||||||
if current + free[¤t] == right {
|
|
||||||
*free.get_mut(¤t).unwrap() += free.remove(&right).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn n(m: usize) -> usize {
|
|
||||||
(m * m - m) / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::collections::BTreeMap;
|
|
||||||
|
|
||||||
use crate::day09::merge;
|
|
||||||
|
|
||||||
use super::{part1, part2};
|
use super::{part1, part2};
|
||||||
|
|
||||||
const TEST_INPUT: &str = r"2333133121414131402";
|
const TEST_INPUT: &str = r"2333133121414131402";
|
||||||
@@ -132,35 +106,4 @@ mod test {
|
|||||||
fn test2() {
|
fn test2() {
|
||||||
assert_eq!(part2(TEST_INPUT), 2858);
|
assert_eq!(part2(TEST_INPUT), 2858);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn merge_left() {
|
|
||||||
let mut tree = BTreeMap::new();
|
|
||||||
tree.insert(0, 3);
|
|
||||||
tree.insert(3, 5);
|
|
||||||
merge(&mut tree, 3);
|
|
||||||
assert_eq!(tree.len(), 1);
|
|
||||||
assert_eq!(tree[&0], 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn merge_right() {
|
|
||||||
let mut tree = BTreeMap::new();
|
|
||||||
tree.insert(0, 3);
|
|
||||||
tree.insert(3, 5);
|
|
||||||
merge(&mut tree, 0);
|
|
||||||
assert_eq!(tree.len(), 1);
|
|
||||||
assert_eq!(tree[&0], 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn merge_both() {
|
|
||||||
let mut tree = BTreeMap::new();
|
|
||||||
tree.insert(0, 3);
|
|
||||||
tree.insert(3, 5);
|
|
||||||
tree.insert(8, 11);
|
|
||||||
merge(&mut tree, 3);
|
|
||||||
assert_eq!(tree.len(), 1);
|
|
||||||
assert_eq!(tree[&0], 19);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user