use std::{
fs::File,
io::{BufRead, BufReader},
path::Path,
};
#[derive(Debug)]
struct M {
a: P,
b: P,
p: P,
}
impl M {
fn from_lines(lines: &[String]) -> Self {
let a_line = &lines[0];
let b_line = &lines[1];
let p_line = &lines[2];
Self {
a: P {
x: a_line[&a_line.find("X").unwrap() + 2..a_line.find(",").unwrap()]
.parse()
.unwrap(),
y: a_line[&a_line.find("Y").unwrap() + 2..a_line.len()]
.parse()
.unwrap(),
},
b: P {
x: b_line[&b_line.find("X").unwrap() + 2..b_line.find(",").unwrap()]
.parse()
.unwrap(),
y: b_line[&b_line.find("Y").unwrap() + 2..b_line.len()]
.parse()
.unwrap(),
},
p: P {
x: p_line[&p_line.find("X").unwrap() + 2..p_line.find(",").unwrap()]
.parse::<usize>()
.unwrap()
+ 10000000000000,
y: p_line[&p_line.find("Y").unwrap() + 2..p_line.len()]
.parse::<usize>()
.unwrap()
+ 10000000000000,
},
}
}
}
#[derive(Debug)]
struct P {
x: usize,
y: usize,
}
pub fn part_two(input: &Path) -> anyhow::Result<usize> {
let reader = BufReader::new(File::open(input)?);
let machines: Vec<M> = reader
.lines()
.filter_map(|l| {
let l = l.unwrap();
if !l.is_empty() {
Some(l)
} else {
None
}
})
.collect::<Vec<String>>()
.chunks(3)
.map(|l| -> M { M::from_lines(l) })
.collect();
let mut answer = 0;
for m in machines {
println!();
println!("{}x + {}y = {}", m.a.x, m.b.x, m.p.x);
println!("{}x + {}y = {}", m.a.y, m.b.y, m.p.y);
println!();
let b: i64 = (m.p.y as i64 * m.a.x as i64 - m.p.x as i64 * m.a.y as i64)
/ (m.b.y as i64 * m.a.x as i64 - m.b.x as i64 * m.a.y as i64);
let a: i64 = (m.p.x as i64 - b * m.b.x as i64) / m.a.x as i64;
if m.a.x as i64 * a + m.b.x as i64 * b == m.p.x as i64
&& m.a.y as i64 * a + m.b.y as i64 * b == m.p.y as i64
{
answer += a * 3 + b;
println!("yes");
}
}
Ok(answer as usize)
}