1
0

Added day 8 part 1

This commit is contained in:
Ishan Jain 2022-12-08 11:08:18 +05:30
parent 5c97578f75
commit 289eb2180b
Signed by: ishan
GPG Key ID: 0506DB2A1CC75C27
3 changed files with 160 additions and 1230 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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,116 +24,64 @@ 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
let (size, name) = line.split_once(' ').unwrap(); if input[i][j + 1..n].iter().all(|&h| h < th) {
let fsize = size answer += 1;
.bytes() continue;
.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") }; let mut visible = true;
for row in &input[0..i] {
if row[j] >= th {
visible = false;
break;
}
}
v.children if visible {
.entry(name.to_string()) answer += 1;
.or_insert(Node::File(fsize)); continue;
}
visible = true;
for row in &input[i + 1..m] {
if row[j] >= th {
visible = false;
break;
}
}
if visible {
answer += 1;
} }
} }
} }
compute_dir_size(&mut tree);
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 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]
fn solution_bench(b: &mut test::Bencher) { fn solution_bench(b: &mut test::Bencher) {