<commit_before>use std::path::Path;
use std::io::{BufReader,BufRead};
use std::fs::File;

fn fuel_calc_v2(score: f32, debug: bool) -> f32 {
    let mut fuel_req = (score / 3.0).floor() - 2.0;
    if fuel_req < 0.0 {
        return 0.0;
    }
    fuel_req += fuel_calc_v2(fuel_req, false);
    if debug {
        println!("{} requires {} fuel", score, fuel_req);
    }
    fuel_req
}

fn fuel_calc_v1(score: f32, debug: bool) -> f32 {
    let fuel_req = (score / 3.0).floor() - 2.0;
    if debug {
        println!("{} requires {} fuel", score, fuel_req);
    }
    fuel_req as f32
}

fn solve(path: &Path, fuel_calc: fn(f32, bool) -> f32, debug: bool) -> u32{
    let display = path.display();
    let file = match File::open(&path) {
        Err(why) => panic!(
            "couldn't open {}: {}", display, why),
        Ok(file) => file,
    };

    let reader = BufReader::new(file);
    let scores = reader.lines().map(|line| {
        let score: f32 = line.unwrap().parse().unwrap();
        score
    });
    let fuel_reqs = scores.map(|score| {
        fuel_calc(score, debug) as u32
    });
    let total : u32 = fuel_reqs.sum();
    return total;
}

fn main() {
    for (idx, func) in [fuel_calc_v1, fuel_calc_v2].iter().enumerate() {
        println!("======Part {}=====", idx+1);
        println!("==Test Case==");
        let mut answer : u32 = solve(Path::new("./test"), *func, true);
        println!("Total Fuel Requirements: {}", answer);
        println!("==Real Thing==");
        answer = solve(Path::new("./input"), *func, false);
        println!("Total Fuel Requirements: {}", answer);
    }
}<commit_msg>Refactor 2019 Day 01<commit_after>use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;

fn fuel_calc_v2(score: i32) -> i32 {
    let fuel_req = fuel_calc_v1(score);
    if fuel_req < 0 {
        return 0;
    }
    fuel_req + fuel_calc_v2(fuel_req)
}

fn fuel_calc_v1(score: i32) -> i32 {
    (score as f32 / 3.0).floor() as i32 - 2
}

fn solve(path: &Path, fuel_calc: fn(i32) -> i32, verbose: bool) -> i32 {
    let display = path.display();
    let file = match File::open(&path) {
        Err(why) => panic!("couldn't open {}: {}", display, why),
        Ok(file) => file,
    };

    let reader = BufReader::new(file);
    let scores = reader.lines().map(|line| {
        line.unwrap().parse::<i32>().unwrap()
    });
    let fuel_reqs = scores.map(|score| {
        let fuel_req = fuel_calc(score);
        if verbose {
            println!("{} requires {} fuel", score, fuel_req);
        }
        fuel_req
    });
    fuel_reqs.sum()
}

fn main() {
    for (name, path, verbose) in [
        ("Test", Path::new("./test"), true),
        ("Real", Path::new("./input"), false),
    ]
    .iter()
    {
        println!("======={} Case=======", name);
        for (idx, func) in [fuel_calc_v1, fuel_calc_v2].iter().enumerate() {
            println!("==Part {}==", idx + 1);
            println!("Total Fuel Requirements: {}", solve(path, *func, *verbose));
        }
    }
}
{'fraction_non_alphanumeric': 0.19610432485968968, 'fraction_numerical': 0.02641135688345989, 'mean_word_length': 2.5605170387779084, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1033904', 'n_tokens_mistral': 1117, 'n_tokens_neox': 1067, 'n_words': 249}