Added day 8 part 1
This commit is contained in:
parent
5c97578f75
commit
289eb2180b
1186
inputs/input.txt
1186
inputs/input.txt
File diff suppressed because it is too large
Load Diff
|
@ -1,23 +1,5 @@
|
||||||
$ cd /
|
30373
|
||||||
$ ls
|
25512
|
||||||
dir a
|
65332
|
||||||
14848514 b.txt
|
33549
|
||||||
8504156 c.dat
|
35390
|
||||||
dir d
|
|
||||||
$ cd a
|
|
||||||
$ ls
|
|
||||||
dir e
|
|
||||||
29116 f
|
|
||||||
2557 g
|
|
||||||
62596 h.lst
|
|
||||||
$ cd e
|
|
||||||
$ ls
|
|
||||||
584 i
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd d
|
|
||||||
$ ls
|
|
||||||
4060174 j
|
|
||||||
8033020 d.log
|
|
||||||
5626152 d.ext
|
|
||||||
7214296 k
|
|
||||||
|
|
176
src/main.rs
176
src/main.rs
|
@ -1,30 +1,18 @@
|
||||||
|
#![feature(byte_slice_trim_ascii)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
const INPUTS: [&str; 2] = [
|
const INPUTS: [&[u8]; 2] = [
|
||||||
include_str!("../inputs/sample.txt"),
|
include_bytes!("../inputs/sample.txt"),
|
||||||
include_str!("../inputs/input.txt"),
|
include_bytes!("../inputs/input.txt"),
|
||||||
];
|
];
|
||||||
|
|
||||||
fn parse(input: &'static str) -> impl Iterator<Item = &'static str> {
|
fn parse(input: &[u8]) -> Vec<Vec<u8>> {
|
||||||
let input = input.trim().lines();
|
|
||||||
|
|
||||||
input
|
input
|
||||||
}
|
.trim_ascii()
|
||||||
|
.split(|&c| c == b'\n')
|
||||||
#[derive(Debug)]
|
.map(|line| line.iter().map(|b| b - b'0').collect())
|
||||||
enum Node {
|
.collect()
|
||||||
File(u32),
|
|
||||||
Directory(Directory),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Directory {
|
|
||||||
children: HashMap<String, Node>,
|
|
||||||
parent: *mut Node,
|
|
||||||
size: u32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -36,115 +24,63 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn solution(input: impl Iterator<Item = &'static str>) -> u32 {
|
fn solution(input: Vec<Vec<u8>>) -> usize {
|
||||||
let mut tree = Node::Directory(Directory {
|
let m = input.len();
|
||||||
children: HashMap::new(),
|
let n = input[0].len();
|
||||||
parent: std::ptr::null_mut(),
|
|
||||||
size: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut current = &mut tree;
|
let mut answer = 0;
|
||||||
|
|
||||||
for line in input {
|
for i in 0..m {
|
||||||
match &line[..4] {
|
for j in 0..n {
|
||||||
"$ ls" => continue,
|
match (i, j) {
|
||||||
|
(0, _) => answer += 1,
|
||||||
"dir " => {
|
(_, 0) => answer += 1,
|
||||||
let dir = &line[4..];
|
(_, j) if j == n - 1 => answer += 1,
|
||||||
let cptr = current as *mut Node;
|
(i, _) if i == m - 1 => answer += 1,
|
||||||
|
|
||||||
let Node::Directory(Directory { children, ..}) = current else { unreachable!()};
|
|
||||||
|
|
||||||
children.insert(
|
|
||||||
dir.to_string(),
|
|
||||||
Node::Directory(Directory {
|
|
||||||
children: HashMap::new(),
|
|
||||||
parent: cptr,
|
|
||||||
size: 0,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
"$ cd" => match &line[5..6] {
|
|
||||||
// we are supposed to match on .. but this is fine
|
|
||||||
"." => {
|
|
||||||
let Node::Directory(Directory { parent , .. }) = *current else {
|
|
||||||
unreachable!("current is not a directory");
|
|
||||||
};
|
|
||||||
|
|
||||||
current = unsafe { &mut *parent };
|
|
||||||
}
|
|
||||||
|
|
||||||
"/" => current = &mut tree,
|
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
let dir = &line[5..];
|
let th = input[i][j];
|
||||||
let Node::Directory(Directory { children, ..}) = current else {
|
// l to r check
|
||||||
unreachable!("current is not a directory");
|
if input[i][0..j].iter().all(|&h| h < th) {
|
||||||
};
|
answer += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
current = children.get_mut(dir).unwrap();
|
// r to l check
|
||||||
|
if input[i][j + 1..n].iter().all(|&h| h < th) {
|
||||||
|
answer += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut visible = true;
|
||||||
|
for row in &input[0..i] {
|
||||||
|
if row[j] >= th {
|
||||||
|
visible = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if visible {
|
||||||
|
answer += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
visible = true;
|
||||||
|
for row in &input[i + 1..m] {
|
||||||
|
if row[j] >= th {
|
||||||
|
visible = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if visible {
|
||||||
|
answer += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
let (size, name) = line.split_once(' ').unwrap();
|
|
||||||
let fsize = size
|
|
||||||
.bytes()
|
|
||||||
.take_while(|&c| c != b' ')
|
|
||||||
.fold(0u32, |a, x| a * 10 + (x - b'0') as u32);
|
|
||||||
|
|
||||||
let Node::Directory(v) = current else {unreachable!("not a directory") };
|
|
||||||
|
|
||||||
v.children
|
|
||||||
.entry(name.to_string())
|
|
||||||
.or_insert(Node::File(fsize));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compute_dir_size(&mut tree);
|
answer
|
||||||
|
|
||||||
let total = 70000000;
|
|
||||||
let required = 30000000;
|
|
||||||
|
|
||||||
let Node::Directory(ref root) = tree else { unreachable!("not a directory") };
|
|
||||||
|
|
||||||
let to_freeup = root.size + required - total;
|
|
||||||
|
|
||||||
part2(&tree, to_freeup)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn part2(node: &Node, to_freeup: u32) -> u32 {
|
|
||||||
match node {
|
|
||||||
Node::Directory(dir) if dir.size >= to_freeup => {
|
|
||||||
let mut answer = dir.size;
|
|
||||||
|
|
||||||
for v in dir.children.values() {
|
|
||||||
answer = std::cmp::min(answer, part2(v, to_freeup));
|
|
||||||
}
|
|
||||||
|
|
||||||
answer
|
|
||||||
}
|
|
||||||
_ => std::u32::MAX,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compute_dir_size(node: &mut Node) -> u32 {
|
|
||||||
match node {
|
|
||||||
&mut Node::File(v) => v,
|
|
||||||
|
|
||||||
Node::Directory(dir) => {
|
|
||||||
let mut sum = 0;
|
|
||||||
|
|
||||||
for v in dir.children.values_mut() {
|
|
||||||
sum += compute_dir_size(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
dir.size = sum;
|
|
||||||
sum
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user