Parser finished.
This commit is contained in:
parent
0408d3e148
commit
6245e1a17c
127
src/prob5.rs
127
src/prob5.rs
@ -1,19 +1,116 @@
|
||||
fn parser(content: &str) {
|
||||
let output = content
|
||||
.lines()
|
||||
.filter(|item| !item.starts_with("move"))
|
||||
.flat_map(|line| {
|
||||
let splitted = line
|
||||
.trim()
|
||||
.split(' ')
|
||||
.enumerate()
|
||||
.filter(|item| !item.1.contains(' '))
|
||||
.filter(|item| !item.1.is_empty())
|
||||
.collect::<Vec<(usize, &str)>>();
|
||||
println!("{splitted:?}");
|
||||
splitted
|
||||
use nom::{
|
||||
branch::alt,
|
||||
bytes::complete::{tag, take, take_while1},
|
||||
combinator::{all_consuming, map, map_res, opt},
|
||||
sequence::{delimited, preceded, tuple},
|
||||
Finish, IResult,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Instruction {
|
||||
quantity: usize,
|
||||
src: usize,
|
||||
dst: usize,
|
||||
}
|
||||
|
||||
/// Used to parse a crate
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `i`:
|
||||
///
|
||||
/// returns: Result<(&str, char), Err<Error<I>>>
|
||||
///
|
||||
fn parse_crate(i: &str) -> IResult<&str, char> {
|
||||
let first_char = |s: &str| s.chars().next().unwrap();
|
||||
let f = delimited(tag("["), take(1_usize), tag("]"));
|
||||
map(f, first_char)(i)
|
||||
}
|
||||
|
||||
fn parse_hole(i: &str) -> IResult<&str, ()> {
|
||||
// `drop` takes a value and returns nothing, which is
|
||||
// perfect for our case
|
||||
map(tag(" "), drop)(i)
|
||||
}
|
||||
|
||||
fn parse_crate_or_hole(i: &str) -> IResult<&str, Option<char>> {
|
||||
alt((map(parse_crate, Some), map(parse_hole, |_| None)))(i)
|
||||
}
|
||||
|
||||
fn parse_crate_line(i: &str) -> IResult<&str, Vec<Option<char>>> {
|
||||
let (mut i, c) = parse_crate_or_hole(i)?;
|
||||
let mut v = vec![c];
|
||||
|
||||
loop {
|
||||
let (next_i, maybe_c) = opt(preceded(tag(" "), parse_crate_or_hole))(i)?;
|
||||
match maybe_c {
|
||||
Some(c) => v.push(c),
|
||||
None => break,
|
||||
}
|
||||
i = next_i;
|
||||
}
|
||||
|
||||
Ok((i, v))
|
||||
}
|
||||
|
||||
fn transpose_rev<T>(v: Vec<Vec<Option<T>>>) -> Vec<Vec<T>> {
|
||||
assert!(!v.is_empty());
|
||||
let len = v[0].len();
|
||||
let mut iters: Vec<_> = v.into_iter().map(|n| n.into_iter()).collect();
|
||||
(0..len)
|
||||
.map(|_| {
|
||||
iters
|
||||
.iter_mut()
|
||||
.filter_map(|n| n.next().unwrap())
|
||||
.collect::<Vec<T>>()
|
||||
})
|
||||
.collect::<Vec<(usize, &str)>>();
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn parse_number(i: &str) -> IResult<&str, usize> {
|
||||
map_res(take_while1(|c: char| c.is_ascii_digit()), |s: &str| {
|
||||
s.parse::<usize>()
|
||||
})(i)
|
||||
}
|
||||
|
||||
fn parse_pile_number(i: &str) -> IResult<&str, usize> {
|
||||
map(parse_number, |i| i - 1)(i)
|
||||
}
|
||||
|
||||
fn parse_instruction(i: &str) -> IResult<&str, Instruction> {
|
||||
map(
|
||||
tuple((
|
||||
preceded(tag("move "), parse_number),
|
||||
preceded(tag(" from "), parse_pile_number),
|
||||
preceded(tag(" to "), parse_pile_number),
|
||||
)),
|
||||
|(quantity, src, dst)| Instruction { quantity, src, dst },
|
||||
)(i)
|
||||
}
|
||||
|
||||
fn parser(content: &str) {
|
||||
let mut lines = content.lines();
|
||||
let crate_lines = (&mut lines)
|
||||
.map_while(|line| {
|
||||
all_consuming(parse_crate_line)(line)
|
||||
.finish()
|
||||
.ok()
|
||||
.map(|(_, line)| line)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let crate_columns = transpose_rev(crate_lines);
|
||||
|
||||
crate_columns.iter().for_each(|item| println!("{item:?}"));
|
||||
|
||||
assert!(lines.next().unwrap().is_empty());
|
||||
|
||||
let instructions: Vec<_> = lines
|
||||
.map(|line| all_consuming(parse_instruction)(line).finish().unwrap().1)
|
||||
.collect();
|
||||
for ins in &instructions {
|
||||
println!("{ins:?}");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn solve(file_path: &str) -> i32 {
|
||||
|
Loading…
Reference in New Issue
Block a user