1
0

Prob7 using parser from the same site for solution.

This commit is contained in:
Pcornat 2023-09-20 19:25:11 +02:00
parent 17740888b5
commit 62bba80378
Signed by: Pcornat
GPG Key ID: 2F3932FF46D9ECA0
2 changed files with 96 additions and 11 deletions

View File

@ -13,3 +13,4 @@ rpath = true
[dependencies]
nom = "7.1.1"
itertools = "0.10.5"
camino = "1.1.6"

View File

@ -1,17 +1,101 @@
use nom::{branch::alt, bytes::complete::tag, combinator::map, IResult};
use std::collections::HashMap;
use crate::prob7::Instructions::{Cd, Dir, Ls};
use camino::Utf8PathBuf;
use nom::combinator::all_consuming;
use nom::{
branch::alt,
bytes::complete::{tag, take_while1},
combinator::map,
sequence::{preceded, separated_pair},
Finish, IResult,
};
enum Instructions {
#[derive(Debug)]
struct Ls;
#[derive(Debug)]
struct Cd(Utf8PathBuf);
#[derive(Debug)]
enum Entry {
Dir(Utf8PathBuf),
File(u64, Utf8PathBuf),
}
#[derive(Debug)]
enum Command {
Ls,
Cd,
Dir,
Cd(Utf8PathBuf),
}
fn parse_instruction(i: &str) -> IResult<&str, Instructions> {
alt((
map(tag("ls"), |_| Ls),
map(tag("cd"), |_| Cd),
map(tag("dir"), |_| Dir),
))(i)
#[derive(Debug)]
enum Line {
Command(Command),
Entry(Entry),
}
impl From<Ls> for Command {
fn from(_ls: Ls) -> Self {
Command::Ls
}
}
impl From<Cd> for Command {
fn from(cd: Cd) -> Self {
Command::Cd(cd.0)
}
}
struct Node {
children: HashMap<String, Node>,
size: u32,
}
fn parse_entry(input: &str) -> IResult<&str, Entry> {
let parse_file = map(
separated_pair(nom::character::complete::u64, tag(" "), parse_path),
|(size, path)| Entry::File(size, path),
);
let parse_dir = map(preceded(tag("dir "), parse_path), Entry::Dir);
alt((parse_file, parse_dir))(input)
}
fn parse_path(input: &str) -> IResult<&str, Utf8PathBuf> {
map(
take_while1(|c: char| "abcdefghijklmnopqrstuvwxyz./".contains(c)),
Into::into,
)(input)
}
fn parse_ls(input: &str) -> IResult<&str, Ls> {
map(tag("ls"), |_| Ls)(input)
}
fn parse_cd(input: &str) -> IResult<&str, Cd> {
map(preceded(tag("cd "), parse_path), Cd)(input)
}
fn parse_command(line: &str) -> IResult<&str, Command> {
let (input, _) = tag("$ ")(line)?;
alt((map(parse_ls, Into::into), map(parse_cd, Into::into)))(input)
}
fn parse_line(input: &str) -> IResult<&str, Line> {
alt((
map(parse_command, Line::Command),
map(parse_entry, Line::Entry),
))(input)
}
pub fn solve_part1(content: &str) {
let lines = content.lines().map(|line| {
all_consuming(parse_line)(line)
.finish()
.unwrap_or_else(|err| panic!("{err}"))
.1
});
for line in lines {
println!("{line:?}");
}
}