2022 rust day 7 refactor
This commit is contained in:
parent
1cd2721b61
commit
276b515e6d
|
@ -4,7 +4,7 @@ use crate::utils;
|
||||||
|
|
||||||
|
|
||||||
pub fn run() -> () {
|
pub fn run() -> () {
|
||||||
let data = parse_data(utils::read_lines(utils::Source::Day(7)));
|
let data = parse_data(&utils::read_lines(utils::Source::Day(7)));
|
||||||
|
|
||||||
println!("Day 7");
|
println!("Day 7");
|
||||||
println!("Part 1: {}", solve1(&data));
|
println!("Part 1: {}", solve1(&data));
|
||||||
|
@ -23,6 +23,7 @@ struct FileNode {
|
||||||
size: i32,
|
size: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
struct Node<'data> {
|
struct Node<'data> {
|
||||||
name: &'data str,
|
name: &'data str,
|
||||||
// Backref pointer
|
// Backref pointer
|
||||||
|
@ -31,14 +32,8 @@ struct Node<'data> {
|
||||||
subdirs: Vec<Box<Node<'data>>>,
|
subdirs: Vec<Box<Node<'data>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'data> Node<'data> {
|
|
||||||
fn new(name: &'data str, parent: Option<*mut Node<'data>>) -> Node<'data> {
|
|
||||||
Node { name, parent, files: vec![], subdirs: vec![] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cli_to_tree(data: &[CliEntry]) -> Box<Node> {
|
fn cli_to_tree(data: &[CliEntry]) -> Box<Node> {
|
||||||
let mut root = Box::new(Node::new("/", None));
|
let mut root = Box::new(Node { name: "/", ..Default::default() });
|
||||||
|
|
||||||
let mut current: &mut Node = root.as_mut();
|
let mut current: &mut Node = root.as_mut();
|
||||||
for command in data {
|
for command in data {
|
||||||
|
@ -59,7 +54,7 @@ fn cli_to_tree(data: &[CliEntry]) -> Box<Node> {
|
||||||
CliEntry::Ls => {},
|
CliEntry::Ls => {},
|
||||||
CliEntry::Dir(name) => {
|
CliEntry::Dir(name) => {
|
||||||
let current_ptr = current as *mut Node;
|
let current_ptr = current as *mut Node;
|
||||||
current.subdirs.push(Box::new(Node::new(name, Some(current_ptr))));
|
current.subdirs.push(Box::new(Node { name, parent: Some(current_ptr), ..Default::default() }));
|
||||||
},
|
},
|
||||||
CliEntry::File(_, size) => {
|
CliEntry::File(_, size) => {
|
||||||
current.files.push(FileNode { size: *size })
|
current.files.push(FileNode { size: *size })
|
||||||
|
@ -69,23 +64,24 @@ fn cli_to_tree(data: &[CliEntry]) -> Box<Node> {
|
||||||
root
|
root
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_sizes(root: &Box<Node>) -> (i32, BinaryHeap<i32>) {
|
fn find_sizes(node: &Box<Node>, heap: &mut BinaryHeap<i32>) -> i32 {
|
||||||
let mut acc: i32 = root.files.iter().map(|f| f.size).sum();
|
let mut acc: i32 = 0;
|
||||||
let mut sizes: BinaryHeap<i32> = BinaryHeap::new();
|
for file in &node.files {
|
||||||
root.subdirs.iter().for_each(|subdir| {
|
acc += file.size;
|
||||||
let (sub_size, sub_sizes) = find_sizes(subdir);
|
}
|
||||||
sizes.extend(sub_sizes.iter());
|
for subdir in &node.subdirs {
|
||||||
acc += sub_size;
|
acc += find_sizes(subdir, heap);
|
||||||
});
|
}
|
||||||
sizes.push(acc);
|
heap.push(acc);
|
||||||
(acc, sizes)
|
acc
|
||||||
}
|
}
|
||||||
|
|
||||||
fn solve1(data: &[CliEntry]) -> i32 {
|
fn solve1(data: &[CliEntry]) -> i32 {
|
||||||
let tree = cli_to_tree(&data[1..]);
|
let tree = cli_to_tree(&data[1..]);
|
||||||
let (_, sizes) = find_sizes(&tree);
|
let mut heap: BinaryHeap<i32> = BinaryHeap::new();
|
||||||
|
find_sizes(&tree, &mut heap);
|
||||||
|
|
||||||
sizes.into_iter()
|
heap.into_iter()
|
||||||
.filter_map(|size| size
|
.filter_map(|size| size
|
||||||
.le(&100000)
|
.le(&100000)
|
||||||
.then_some(size)
|
.then_some(size)
|
||||||
|
@ -97,10 +93,11 @@ fn solve2(data: &[CliEntry]) -> i32 {
|
||||||
static DISK_SPACE: i32 = 70000000;
|
static DISK_SPACE: i32 = 70000000;
|
||||||
static REQUIRED: i32 = 30000000;
|
static REQUIRED: i32 = 30000000;
|
||||||
let tree = cli_to_tree(&data[1..]);
|
let tree = cli_to_tree(&data[1..]);
|
||||||
let (size, sizes) = find_sizes(&tree);
|
let mut heap: BinaryHeap<i32> = BinaryHeap::new();
|
||||||
|
let size = find_sizes(&tree, &mut heap);
|
||||||
|
|
||||||
let threshold = REQUIRED - (DISK_SPACE - size);
|
let threshold = REQUIRED - (DISK_SPACE - size);
|
||||||
sizes.into_sorted_vec()
|
heap.into_sorted_vec()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|&x| x > threshold)
|
.filter(|&x| x > threshold)
|
||||||
.next()
|
.next()
|
||||||
|
@ -108,9 +105,10 @@ fn solve2(data: &[CliEntry]) -> i32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn parse_data(data: Vec<String>) -> Vec<CliEntry> {
|
fn parse_data<T: AsRef<str>>(data: &[T]) -> Vec<CliEntry> {
|
||||||
data.into_iter()
|
data.into_iter()
|
||||||
.map(|s| {
|
.map(|str_ref| {
|
||||||
|
let s = str_ref.as_ref();
|
||||||
let mut parts = s.split_whitespace().into_iter();
|
let mut parts = s.split_whitespace().into_iter();
|
||||||
if s.starts_with('$') {
|
if s.starts_with('$') {
|
||||||
match parts.nth(1).unwrap() {
|
match parts.nth(1).unwrap() {
|
||||||
|
@ -134,8 +132,7 @@ fn parse_data(data: Vec<String>) -> Vec<CliEntry> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn data() -> Vec<String> {
|
static DATA: &[&str; 23] = &[
|
||||||
vec![
|
|
||||||
"$ cd /",
|
"$ cd /",
|
||||||
"$ ls", "dir a", "14848514 b.txt", "8504156 c.dat", "dir d",
|
"$ ls", "dir a", "14848514 b.txt", "8504156 c.dat", "dir d",
|
||||||
"$ cd a",
|
"$ cd a",
|
||||||
|
@ -146,19 +143,17 @@ mod tests {
|
||||||
"$ cd ..",
|
"$ cd ..",
|
||||||
"$ cd d",
|
"$ cd d",
|
||||||
"$ ls", "4060174 j", "8033020 d.log", "5626152 d.ext", "7214296 k",
|
"$ ls", "4060174 j", "8033020 d.log", "5626152 d.ext", "7214296 k",
|
||||||
]
|
];
|
||||||
.into_iter().map(String::from).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn part1() {
|
fn part1() {
|
||||||
let data = parse_data(data());
|
let data = parse_data(DATA);
|
||||||
assert_eq!(95437, solve1(&data));
|
assert_eq!(95437, solve1(&data));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn part2() {
|
fn part2() {
|
||||||
let data = parse_data(data());
|
let data = parse_data(DATA);
|
||||||
assert_eq!(24933642, solve2(&data));
|
assert_eq!(24933642, solve2(&data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue