# AoC 2019 Day 01: The Tyranny of the Rocket Equation

## Description

The objective is to write a function that calculates the amount of fuel needed to propel a given mass. The question is interesting because the fuel has mass and therefore requires fuel too, and so forth.

## My Solution

``````use std::fs::File;
use std::path::Path;

/// Returns the amount of fuel required to launch a module of mass `mass`.
fn fuel_needed_for_mass(mass: i64) -> i64 {
// You can return early from a function by using the `return` keyword and
// specifying a value, but most functions return the last expression
// implicitly. Note that expressions don't have semicolons.
//
// https://doc.rust-lang.org/book/ch03-03-how-functions-work.html

// To find the fuel required for a module, take its mass, divide by three,
// round down, and subtract 2.
//
// I like how Rust warned me against using an unsigned int:
// thread 'main' panicked at 'attempt to subtract with overflow'
let fuel_mass = (mass / 3) - 2;

// Can't do a one-line if-statement in Rust. Good to know.
if fuel_mass <= 0 { return 0; }

// The fuel also requires fuel...
return fuel_mass + fuel_needed_for_mass(fuel_mass);
}

fn main() {
assert_eq!(fuel_needed_for_mass(14), 2);
assert_eq!(fuel_needed_for_mass(1969), 966);
assert_eq!(fuel_needed_for_mass(100756), 50346);

let mut total_fuel_needed: i64 = 0;
// Functions return `Result` whenever errors are expected and recoverable.
// `Ok(T)` represents success and contains a value, while `Err(E)`
// represents an error and contains an error value.
// https://doc.rust-lang.org/std/result/
if let Ok(lines) = read_lines("./input01.txt") {
for line in lines {
// So much error handling. In Python, I couldn't even consider
// adding this check. What could go wrong at this point?
// Update: say the line is not valid UTF-8
if let Ok(mass_str) = line {
let mass = mass_str.parse::<i64>().unwrap();
total_fuel_needed += fuel_needed_for_mass(mass);
}
}
}
// Macros look like functions, except that their name ends with
// a bang !, but instead of generating a function call, macros
// are expanded into source code that gets compiled with the
// rest of the program.
// https://doc.rust-lang.org/rust-by-example/macros.html
//
// The string formatting is similar to that of Python
// https://doc.rust-lang.org/std/fmt/index.html
println!("Total fuel needed: {}", total_fuel_needed);
}

/// Returns an `Iterator` to the `Reader` of the lines of the file. The output
/// is wrapped in an `io::Result<T>` to make the failure of all I/O operations
/// explicit.
///