|
@@ -0,0 +1,92 @@
|
|
|
|
|
+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<i64>) -> 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<i64>) -> Vec<i64> {
|
|
|
|
|
+ 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<i64>> {
|
|
|
|
|
+ many1(terminated(i64, space0))(input)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+fn parse_line(input: &str) -> Result<Vec<i64>, 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<String> = 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<i64>> = 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}");
|
|
|
|
|
+}
|