From 62bba8037860a54be2274ff14fdd17f03d494550 Mon Sep 17 00:00:00 2001 From: Pcornat Date: Wed, 20 Sep 2023 19:25:11 +0200 Subject: [PATCH] Prob7 using parser from the same site for solution. --- Cargo.toml | 1 + src/prob7.rs | 106 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 96 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bf7e11d..888dc55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,4 @@ rpath = true [dependencies] nom = "7.1.1" itertools = "0.10.5" +camino = "1.1.6" diff --git a/src/prob7.rs b/src/prob7.rs index 24c01dc..c55f7e0 100644 --- a/src/prob7.rs +++ b/src/prob7.rs @@ -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 for Command { + fn from(_ls: Ls) -> Self { + Command::Ls + } +} + +impl From for Command { + fn from(cd: Cd) -> Self { + Command::Cd(cd.0) + } +} + +struct Node { + children: HashMap, + 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:?}"); + } }