println!("Pythagorean triples are sets of 3 integers a, b and c that correspond to the dimensions of a right-angled triangle.");
println!("As if it isn't neat enough that such triangles exist, they form a tree structure and you can derive them all from the classic (3, 4, 5) triangle.");
println!();
println!("Enter a Pythagorean triple, e.g. 3 4 5 or (3,4,5). NB don't change the order of the 3 integers.");
loop {
println!("Enter the triple as 3 numbers, or q to quit, then press Ctrl-D on a new line. Ctrl-C will also quit.");
let mut buffer = String::new();
io::stdin().lock().read_to_string(&mut buffer)?;
let s = buffer.trim();
if s == "q" { break };
let vec = s
.trim_start_matches('(')
.trim_end_matches(')')
.replace(',', " ")
.split_whitespace()
.map(|x| x.parse::<usize>().expect("Parse error"))
.collect::<Vec<usize>>();
let (a, b, c): (usize, usize, usize) = (vec[0], vec[1], vec[2]);
let m: usize = (((a + c) as f64) / 2.0).sqrt() as usize; let n: usize = b / (2 * m);
let (m1, n1): (usize, usize) = (2 * m - n, m);
let (m2, n2): (usize, usize) = (2 * m + n, m);
let (m3, n3): (usize, usize) = (m + 2 * n, n);
let (p1, p2, p3) = ((m1, n1), (m2, n2), (m3, n3));
println!();
let (a1, b1, c1): (usize, usize, usize) = (m1.pow(2) - n1.pow(2), 2 * m1 * n1, m1.pow(2) + n1.pow(2));
let (a2, b2, c2): (usize, usize, usize) = (m2.pow(2) - n2.pow(2), 2 * m2 * n2, m2.pow(2) + n2.pow(2));
let (a3, b3, c3): (usize, usize, usize) = (m3.pow(2) - n3.pow(2), 2 * m3 * n3, m3.pow(2) + n3.pow(2));
let (t, t1, t2, t3) = ((a, b, c), (a1, b1, c1), (a2, b2, c2), (a3, b3, c3));
println!("Triple {t:?} has child triples {t1:?}, {t2:?} and {t3:?}");
println!();
println!("Would you like to try another triple? You can enter any valid triple that won't break the limits of Rust's usize.");
}