/*
* Copyright (c) 2019, 2020 Erik Nordstrøm <erik@nordstroem.no>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
solution_printer!;
pub const INPUT: &str = include_str!;
/// ### Day 1: The Tyranny of the Rocket Equation
///
/// [https://adventofcode.com/2019/day/1](https://adventofcode.com/2019/day/1)
///
/// Santa has become stranded at the edge of the Solar System while
/// delivering presents to other planets! To accurately calculate his
/// position in space, safely align his warp drive, and return to Earth in
/// time to save Christmas, he needs you to bring him measurements from *fifty
/// stars*.
///
/// Collect stars by solving puzzles. Two puzzles will be made available on
/// each day in the Advent calendar; the second puzzle is unlocked when you
/// complete the first. Each puzzle grants *one star*. Good luck!
///
/// The Elves quickly load you into a spacecraft and prepare to launch.
///
/// At the first Go / No Go poll, every Elf is Go until the Fuel Counter-
/// Upper. They haven't determined the amount of fuel required yet.
///
/// Fuel required to launch a given *module* is based on its *mass*.
/// Specifically, to find the fuel required for a module, take its mass,
/// divide by three, round down, and subtract 2.
///
/// For example:
///
/// - For a mass of `12`, divide by 3 and round down to get `4`, then subtract
/// 2 to get `2`.
/// - For a mass of `14`, dividing by 3 and rounding down still yields `4`, so
/// the fuel required is also `2`.
/// - For a mass of `1969`, the fuel required is `654`.
/// - For a mass of `100756`, the fuel required is `33583`.
///
/// The Fuel Counter-Upper needs to know the total fuel requirement. To find
/// it, individually calculate the fuel needed for the mass of each module
/// (your puzzle input), then add together all the fuel values.
///
/// *What is the sum of the fuel requirements* for all of the modules on your
/// spacecraft?
///
/// ### Examples
///
/// ```
/// use codetrotter_aoc_2019_solutions::day_01::{input_generator, solve_part_1};
/// assert_eq!(solve_part_1(&mut input_generator("12")), 2);
/// ```
///
/// ```
/// # use codetrotter_aoc_2019_solutions::day_01::{input_generator, solve_part_1};
/// assert_eq!(solve_part_1(&mut input_generator("14")), 2);
/// ```
///
/// ```
/// # use codetrotter_aoc_2019_solutions::day_01::{input_generator, solve_part_1};
/// assert_eq!(solve_part_1(&mut input_generator("1969")), 654);
/// ```
///
/// ```
/// # use codetrotter_aoc_2019_solutions::day_01::{input_generator, solve_part_1};
/// assert_eq!(solve_part_1(&mut input_generator("100756")), 33583);
/// ```
///
/// ### Solution
///
/// ⚠️ SPOILER ALERT ⚠️
///
/// ```
/// use codetrotter_aoc_2019_solutions::day_01::{INPUT, input_generator, solve_part_1};
/// assert_eq!(solve_part_1(&mut input_generator(INPUT)), 3403509);
/// ```
pub type Mass = i64;
pub type FuelRequired = i64;
/// ### Day 1, Part Two
///
/// [https://adventofcode.com/2019/day/1#part2](https://adventofcode.com/2019/day/1#part2)
///
/// During the second Go / No Go poll, the Elf in charge of the Rocket
/// Equation Double-Checker stops the launch sequence. Apparently, you forgot
/// to include additional fuel for the fuel you just added.
///
/// Fuel itself requires fuel just like a module - take its mass, divide by
/// three, round down, and subtract 2. However, that fuel *also* requires fuel,
/// and *that* fuel requires fuel, and so on. Any mass that would require
/// *negative fuel* should instead be treated as if it requires *zero fuel*; the
/// remaining mass, if any, is instead handled by *wishing really hard*, which
/// has no mass and is outside the scope of this calculation.
///
/// So, for each module mass, calculate its fuel and add it to the total.
/// Then, treat the fuel amount you just calculated as the input mass and
/// repeat the process, continuing until a fuel requirement is zero or
/// negative. For example:
///
/// - A module of mass `14` requires `2` fuel. This fuel requires no further
/// fuel (2 divided by 3 and rounded down is `0`, which would call for a
/// negative fuel), so the total fuel required is still just `2`.
/// - At first, a module of mass `1969` requires `654` fuel. Then, this fuel
/// requires `216` more fuel (`654 / 3 - 2`). `216` then requires `70` more fuel,
/// which requires `21` fuel, which requires `5` fuel, which requires no
/// further fuel. So, the total fuel required for a module of mass `1969`
/// is `654 + 216 + 70 + 21 + 5 = 966`.
/// - The fuel required by a module of mass `100756` and its fuel is:
/// `33583 + 11192 + 3728 + 1240 + 411 + 135 + 43 + 12 + 2 = 50346`.
///
/// *What is the sum of the fuel requirements* for all of the modules on your
/// spacecraft when also taking into account the mass of the added fuel?
/// (Calculate the fuel requirements for each module separately, then add
/// them all up at the end.)
///
/// ### Examples
///
/// ```
/// use codetrotter_aoc_2019_solutions::day_01::{input_generator, solve_part_2};
/// assert_eq!(solve_part_2(&mut input_generator("14")), 2);
/// ```
///
/// ```
/// # use codetrotter_aoc_2019_solutions::day_01::{input_generator, solve_part_2};
/// assert_eq!(solve_part_2(&mut input_generator("1969")), 966);
/// ```
///
/// ```
/// # use codetrotter_aoc_2019_solutions::day_01::{input_generator, solve_part_2};
/// assert_eq!(solve_part_2(&mut input_generator("100756")), 50346);
/// ```
///
/// ### Solution
///
/// ⚠️ SPOILER ALERT ⚠️
///
/// ```
/// use codetrotter_aoc_2019_solutions::day_01::{INPUT, input_generator, solve_part_2};
/// assert_eq!(solve_part_2(&mut input_generator(INPUT)), 5102369);
/// ```