add day 7, part 1
This commit is contained in:
parent
04380e53a3
commit
8127688167
|
@ -0,0 +1,112 @@
|
||||||
|
// Copyright 2022 Christian Ulrich
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::io;
|
||||||
|
use std::iter;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Node {
|
||||||
|
Directory { name: String, children: Vec<Node> },
|
||||||
|
File { name: String, size: usize },
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FileSystem {
|
||||||
|
root: Node,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Node {
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Node::File { name, size: _ } => name,
|
||||||
|
Node::Directory { name, children: _ } => name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn size(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
Node::File { name: _, size } => *size,
|
||||||
|
Node::Directory { name: _, children } => {
|
||||||
|
children.iter().fold(0, |acc, c| acc + c.size())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn walk(&self) -> Box<dyn Iterator<Item = &Node> + '_> {
|
||||||
|
match self {
|
||||||
|
Node::File { name: _, size: _ } => Box::new(iter::empty()),
|
||||||
|
Node::Directory { name: _, children } => Box::new(
|
||||||
|
children.iter().chain(
|
||||||
|
children
|
||||||
|
.iter()
|
||||||
|
.skip(1)
|
||||||
|
.fold(children[0].walk(), |acc, c| Box::new(acc.chain(c.walk()))),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FileSystem {
|
||||||
|
pub fn from_stdin() -> Result<FileSystem, &'static str> {
|
||||||
|
let mut line = String::new();
|
||||||
|
if let Ok(_) = io::stdin().read_line(&mut line) {
|
||||||
|
return Ok(FileSystem {
|
||||||
|
root: FileSystem::parse_dir(&line)?,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Err("input file is empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn root(&self) -> &Node {
|
||||||
|
&self.root
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_file(line: &str) -> Result<Node, &'static str> {
|
||||||
|
if let Some((size, name)) = line.trim().split_once(' ') {
|
||||||
|
return Ok(Node::File {
|
||||||
|
name: name.into(),
|
||||||
|
size: size.parse().map_err(|_| "failed to parse file")?,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Err("failed to parse file")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_dir(line: &str) -> Result<Node, &'static str> {
|
||||||
|
if !line.starts_with("$ cd ") {
|
||||||
|
return Err("cannot parse directory");
|
||||||
|
}
|
||||||
|
let name = line[5..].trim();
|
||||||
|
let mut children = vec![];
|
||||||
|
let mut line = String::new();
|
||||||
|
match io::stdin().read_line(&mut line) {
|
||||||
|
Ok(_) if { line == "$ ls\n" } => (),
|
||||||
|
_ => return Err("cannot parse directory"),
|
||||||
|
}
|
||||||
|
loop {
|
||||||
|
line.clear();
|
||||||
|
match io::stdin().read_line(&mut line) {
|
||||||
|
Ok(_) if { line.starts_with("dir ") } => (),
|
||||||
|
Ok(_) if { line.trim().is_empty() || line == "$ cd ..\n" } => break,
|
||||||
|
Ok(_) if { line.starts_with("$ cd ") } => children.push(Self::parse_dir(&line)?),
|
||||||
|
Ok(_) => children.push(Self::parse_file(&line)?),
|
||||||
|
_ => assert!(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Node::Directory {
|
||||||
|
name: name.into(),
|
||||||
|
children: children,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright 2022 Christian Ulrich
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// usage: ./part1 < input
|
||||||
|
|
||||||
|
pub mod common;
|
||||||
|
|
||||||
|
use common::{FileSystem, Node};
|
||||||
|
|
||||||
|
fn main() -> Result<(), &'static str> {
|
||||||
|
let fs = FileSystem::from_stdin()?;
|
||||||
|
let mut result = 0;
|
||||||
|
for node in fs.root().walk() {
|
||||||
|
if let Node::Directory {
|
||||||
|
name: _,
|
||||||
|
children: _,
|
||||||
|
} = node
|
||||||
|
{
|
||||||
|
let size = node.size();
|
||||||
|
if size <= 100000 {
|
||||||
|
result += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("{result}");
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
$ cd /
|
||||||
|
$ ls
|
||||||
|
dir a
|
||||||
|
14848514 b.txt
|
||||||
|
8504156 c.dat
|
||||||
|
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
|
Loading…
Reference in New Issue