main.rs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. use std::fs;
  2. use std::env;
  3. use nom::IResult;
  4. use nom::multi::many1;
  5. use nom::character::complete::i64;
  6. use nom::sequence::terminated;
  7. use nom::character::complete::space0;
  8. #[derive(Clone, Debug, PartialEq, Eq)]
  9. struct Node {
  10. name: String,
  11. left_child_name: String,
  12. right_child_name: String,
  13. left_child_offset: usize,
  14. right_child_offset: usize,
  15. }
  16. fn are_all_same(numbers: &Vec<i64>) -> bool {
  17. if numbers.is_empty() {
  18. return true;
  19. }
  20. let first = numbers[0];
  21. for number in numbers {
  22. if *number != first {
  23. return false;
  24. }
  25. }
  26. true
  27. }
  28. fn calc_derivative(numbers: &Vec<i64>) -> Vec<i64> {
  29. if numbers.len() < 2 {
  30. return Vec::new();
  31. }
  32. let mut derivative = Vec::new();
  33. for i in 1..numbers.len() {
  34. derivative.push(numbers[i] - numbers[i-1]);
  35. }
  36. derivative
  37. }
  38. fn parse_numbers(input: &str) -> IResult<&str, Vec<i64>> {
  39. many1(terminated(i64, space0))(input)
  40. }
  41. fn parse_line(input: &str) -> Result<Vec<i64>, String> {
  42. match parse_numbers(input) {
  43. Ok((rest, data)) => if rest == "" {
  44. Ok(data)
  45. } else {
  46. Err(format!("Incomplete parse, remaining: {}", rest))
  47. },
  48. Err(error) => Err(error.to_string()),
  49. }
  50. }
  51. fn main() {
  52. let args: Vec<String> = env::args().collect();
  53. let file_path = &args[1];
  54. let input_data = fs::read_to_string(file_path).unwrap_or_else(
  55. |_|{panic!("Can't read file {}", file_path)});
  56. let mut result:i64 = 0;
  57. for line in input_data.lines() {
  58. let numbers = parse_line(line).unwrap_or_else(
  59. |e|panic!("Failed to parse line: {}", e));
  60. let mut derivatives:Vec<Vec<i64>> = Vec::new();
  61. derivatives.push(numbers);
  62. loop {
  63. if are_all_same(derivatives.last().unwrap()) {
  64. break;
  65. }
  66. derivatives.push(calc_derivative(derivatives.last().unwrap()));
  67. }
  68. let mut r = *derivatives.last().unwrap().first().unwrap();
  69. for i in (0..derivatives.len()-1).rev() {
  70. r = *derivatives[i].first().unwrap() - r;
  71. }
  72. result += r;
  73. }
  74. println!("{result}");
  75. }