use std::fs; use std::env; use nom::IResult; use nom::multi::many1; use nom::character::complete::i64; use nom::sequence::terminated; use nom::character::complete::space0; #[derive(Clone, Debug, PartialEq, Eq)] struct Node { name: String, left_child_name: String, right_child_name: String, left_child_offset: usize, right_child_offset: usize, } fn are_all_same(numbers: &Vec) -> bool { if numbers.is_empty() { return true; } let first = numbers[0]; for number in numbers { if *number != first { return false; } } true } fn calc_derivative(numbers: &Vec) -> Vec { if numbers.len() < 2 { return Vec::new(); } let mut derivative = Vec::new(); for i in 1..numbers.len() { derivative.push(numbers[i] - numbers[i-1]); } derivative } fn parse_numbers(input: &str) -> IResult<&str, Vec> { many1(terminated(i64, space0))(input) } fn parse_line(input: &str) -> Result, String> { match parse_numbers(input) { Ok((rest, data)) => if rest == "" { Ok(data) } else { Err(format!("Incomplete parse, remaining: {}", rest)) }, Err(error) => Err(error.to_string()), } } fn main() { let args: Vec = env::args().collect(); let file_path = &args[1]; let input_data = fs::read_to_string(file_path).unwrap_or_else( |_|{panic!("Can't read file {}", file_path)}); let mut result:i64 = 0; for line in input_data.lines() { let numbers = parse_line(line).unwrap_or_else( |e|panic!("Failed to parse line: {}", e)); let mut derivatives:Vec> = Vec::new(); derivatives.push(numbers); loop { if are_all_same(derivatives.last().unwrap()) { break; } derivatives.push(calc_derivative(derivatives.last().unwrap())); } let mut r = *derivatives.last().unwrap().first().unwrap(); for i in (0..derivatives.len()-1).rev() { r = *derivatives[i].first().unwrap() - r; } result += r; } println!("{result}"); }