07 Rust
Part I Assignment
Rust is a compiled language,
you first need to compile it with rustc
and then run it.
rustc 07.rs && ./07
The code.
use std::fs::File;
use std::io::{BufReader, BufRead, Error};
const THRESHOLD: i32 = 100000;
fn main() -> Result<(), Error> {
// open file and propagate error
let file = File::open("07.input")?;
// buffered reader
let reader = BufReader::new(file);
// vector of integers to store stack
let mut stack: Vec<i32> = Vec::new();
// cummulative sum of directory sizes
let mut cum = 0;
// iterate over lines in the file
for line in reader.lines() {
// if the reading fails we panic
let l = line.unwrap();
// process commands; slicing the line
if &l[..1] == "$" {
// ls
if &l[2..4] == "ls" {
// we don't need to process this command
continue;
// cd /
} else if &l[5..6] == "/" {
// initialize stack with 0 size for /
stack.push(0);
}
// cd ..
else if &l[5..7] == ".." {
// going up in the directory tree
// at the top of stack we have size for the current dir
let dc = stack.pop().unwrap();
// if it is below threshold, we should count
if dc < THRESHOLD {
cum += dc;
}
// updating the parent with the size
let old = stack.pop().unwrap();
stack.push(old + dc);
}
// cd <dir>
else {
// initialize size for the current directory
stack.push(0);
}
}
// process dir listing
else {
// <num> file
if &l[..3] != "dir" {
// split the line and convert string into integer
let size: i32 = l
.split_whitespace()
.next()
.unwrap_or("")
.parse()
.unwrap();
// update the size of the current dir
let old = stack.pop().unwrap();
stack.push(old + size);
}
// we ignore directory listings, we will process them later anyway
}
}
// process the rest of the stack
while stack.len() > 0 {
let pop = stack.pop().unwrap();
// counting as before
if pop < THRESHOLD {
cum += pop
}
}
// print the result
println!("{}", cum);
// return unit
Ok(())
}
Part II
The process is very similar, we just need to store all directory sizes (after all the files in them are counted) and at the end, decide how many bytes to remove and find the smallest directory with its size larger than the “missing” bytes.
use std::fs::File;
use std::io::{BufReader, BufRead, Error};
const REQUIRED: i32 = 40_000_000;
fn main() -> Result<(), Error> {
let file = File::open("07.input")?;
let reader = BufReader::new(file);
let mut stack: Vec<i32> = Vec::new();
// all sizes to select the ideal directory (size) later
let mut all: Vec<i32> = Vec::new();
for line in reader.lines() {
let l = line.unwrap();
if &l[..1] == "$" {
if &l[2..4] == "ls" {
continue;
} else if &l[5..6] == "/" {
stack.push(0);
}
else if &l[5..7] == ".." {
let dc = stack.pop().unwrap();
let old = stack.pop().unwrap();
stack.push(old + dc);
// remember the size of the directory
all.push(dc);
}
else {
stack.push(0);
}
}
else {
if &l[..3] != "dir" {
let size: i32 = l
.split_whitespace()
.next()
.unwrap_or("")
.parse()
.unwrap();
let old = stack.pop().unwrap();
stack.push(old + size);
// we are updating, no need to remember nothing here
}
}
}
while stack.len() > 1 {
let dc = stack.pop().unwrap();
let old = stack.pop().unwrap();
stack.push(old + dc);
// remember the final sizes of directories
all.push(dc);
}
// total size of data
let total: i32 = stack.pop().unwrap();
// sort so the search is simple forward pass
all.sort();
// if data is small we don't need anything
if REQUIRED - total >= 0 {
println!("Nothing to delete...");
}
else {
// we need to remove at least <todelete> bytes
let todelete: i32 = total - REQUIRED;
// iter over the remembered directory sizes
for elem in all.iter() {
// gotcha!
if *elem > todelete {
println!("Delete the directory with size {}", elem);
break;
}
}
}
Ok(())
}
What I learned
cargo
is Rust packaging system- It’s hard to write a code in languages like Rust if you are used to the brevity and simplicity of Python.
- Even reading lines from a file is PITA.
- Rust has no garbage collection and uses “ownership”.
- Trailing
;
is PITA. - Rust is relatively young and the community is much smaller than that of Python. It means that googling and stackoverflowing for answers is much harder than in the case of Python.
published: 2022-12-07
last modified: 2023-01-21
https://vit.baisa.cz/notes/code/advent-of-code-2022/07/
last modified: 2023-01-21
https://vit.baisa.cz/notes/code/advent-of-code-2022/07/