Parser finished.
This commit is contained in:
		
					parent
					
						
							
								0408d3e148
							
						
					
				
			
			
				commit
				
					
						6245e1a17c
					
				
			
		
					 1 changed files with 112 additions and 15 deletions
				
			
		
							
								
								
									
										127
									
								
								src/prob5.rs
									
										
									
									
									
								
							
							
						
						
									
										127
									
								
								src/prob5.rs
									
										
									
									
									
								
							|  | @ -1,19 +1,116 @@ | ||||||
| fn parser(content: &str) { | use nom::{ | ||||||
|     let output = content |     branch::alt, | ||||||
|         .lines() |     bytes::complete::{tag, take, take_while1}, | ||||||
|         .filter(|item| !item.starts_with("move")) |     combinator::{all_consuming, map, map_res, opt}, | ||||||
|         .flat_map(|line| { |     sequence::{delimited, preceded, tuple}, | ||||||
|             let splitted = line |     Finish, IResult, | ||||||
|                 .trim() | }; | ||||||
|                 .split(' ') | 
 | ||||||
|                 .enumerate() | #[derive(Debug)] | ||||||
|                 .filter(|item| !item.1.contains(' ')) | struct Instruction { | ||||||
|                 .filter(|item| !item.1.is_empty()) |     quantity: usize, | ||||||
|                 .collect::<Vec<(usize, &str)>>(); |     src: usize, | ||||||
|             println!("{splitted:?}"); |     dst: usize, | ||||||
|             splitted | } | ||||||
|  | 
 | ||||||
|  | /// 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 { | pub fn solve(file_path: &str) -> i32 { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue