use std::fs::File; use std::io::Read; use std::str::FromStr; use nom::Parser; #[repr(C)] #[derive(Clone, Default)] pub struct Node { pub edge_start: u32, pub num_edges: u32, } pub fn parse_graph(file: String) -> (Vec<Node>, u32, Vec<u32>) { let mut file = File::open(file).expect("Error opening input file"); let mut contents = String::new(); file.read_to_string(&mut contents) .expect("Error reading input file"); let mut parser = nom::combinator::all_consuming(graph_parser); let (_, result) = parser.parse(&contents).expect("Parser error"); result } fn graph_parser<'a>(text: &'a str) -> nom::IResult<&'a str, (Vec<Node>, u32, Vec<u32>)> { // First, we find the number of nodes let text = nom::character::complete::multispace0(text)?.0; let (text, num_nodes) = nom::character::complete::digit1(text)?; let num_nodes = u32::from_str(num_nodes).unwrap(); // Then, for each node there are two numbers: the index of that node's first edge and the // number of edges that node has let mut nodes = vec![]; let mut text = text; for _ in 0..num_nodes { let ntext = nom::character::complete::multispace0(text)?.0; let (ntext, edge_start) = nom::character::complete::digit1(ntext)?; let ntext = nom::character::complete::multispace0(ntext)?.0; let (ntext, num_edges) = nom::character::complete::digit1(ntext)?; let edge_start = u32::from_str(edge_start).unwrap(); let num_edges = u32::from_str(num_edges).unwrap(); nodes.push(Node { edge_start, num_edges, }); text = ntext; } // Next, we find the source node let text = nom::character::complete::multispace0(text)?.0; let (text, source) = nom::character::complete::digit1(text)?; let source = u32::from_str(source).unwrap(); // Next, the number of edges let text = nom::character::complete::multispace0(text)?.0; let (text, num_edges) = nom::character::complete::digit1(text)?; let num_edges = u32::from_str(num_edges).unwrap(); // Finally, for each edge there are two numbers: the id (i.e. what the edge goes to) and the // weight which is ignored (weighted BFS can't be parallelized in the same way, it would // require synchronization) let mut edges = vec![]; let mut text = text; for _ in 0..num_edges { let ntext = nom::character::complete::multispace0(text)?.0; let (ntext, id) = nom::character::complete::digit1(ntext)?; let ntext = nom::character::complete::multispace0(ntext)?.0; let (ntext, _) = nom::character::complete::digit1(ntext)?; let id = u32::from_str(id).unwrap(); edges.push(id); text = ntext; } // Consume any remaining whitespace let text = nom::character::complete::multispace0(text)?.0; Ok((text, (nodes, source, edges))) }