#![feature(non_ascii_idents)]

fn main() {
    std::env::args().nth(1)
    .ok_or(format!("Usage: {} FILE", std::env::args().next().unwrap())) // File name
    .and_then(|filename| {
        std::fs::File::open(&filename)
            .map_err(|e| (&e as &std::error::Error).description().to_string())
    }).map(|f| (f, String::new()))
    .map(|(mut f, mut s)| ((&mut f as &mut std::io::Read).read_to_string(&mut s), s))
    .and_then(|(_, s)| s.lines().map(|line| {
        line.parse::<u32>()
            .map(|u| u as f32)
            .map_err(|e| (&e as &std::error::Error).description().to_string())
    }).collect::<Result<Vec<f32>, String>>())
    .map(|vec| (vec.len() as f32, vec))
    .map(|(n, vec) : (f32, Vec<f32>)| {
        (n, vec.into_iter().zip(1..).map(|(f, i)| (f32::ln(i as f32), f32::ln(f)))
         .fold((0.0, 0.0, 0.0, 0.0, 0.0), 
               |(sum_x, sum_sqrx, sum_y, sum_sqry, sum_xy), (x, y)| {
             (sum_x + x, sum_sqrx + x * x, sum_y + y, sum_sqry + y * y, sum_xy + x * y)
         }))
    }).map(|(n, (sum_x, sum_sqrx, sum_y, sum_sqry, sum_xy))| {
        (sum_x / n, sum_sqrx / n, sum_y / n, sum_sqry / n, sum_xy / n)
    }).map(|(x̅, s̅q̅r̅x̅, y̅, s̅q̅r̅y̅, x̅y̅)| {
        ((x̅y̅ - x̅ * y̅) / (s̅q̅r̅x̅ - x̅ * x̅), 
         (x̅y̅ - x̅ * y̅) * (x̅y̅ - x̅ * y̅) / ((s̅q̅r̅x̅ - x̅ * x̅) * (s̅q̅r̅y̅ - y̅ * y̅)))
    }).map(|(m, sqrr)| println!("m: {}\nR²: {}", m, sqrr))
    .unwrap()
}