use std::{
fs::File,
io::{BufRead, BufReader},
path::Path,
};
pub fn solve(input: &Path) -> anyhow::Result<()> {
println!("part one: {}", part_one(input)?);
//println!("part two: {}", part_two(input)?);
Ok(())
}
#[derive(Debug)]
struct R {
p: P<usize>,
v: P<i32>,
}
impl R {
fn from_str(line: &str) -> Self {
let mut split = line.split_whitespace();
let mut p_split = split.next().unwrap()[2..].split(",");
let mut v_split = split.next().unwrap()[2..].split(",");
Self {
p: P {
x: p_split.next().unwrap().parse().unwrap(),
y: p_split.next().unwrap().parse().unwrap(),
},
v: P {
x: v_split.next().unwrap().parse().unwrap(),
y: v_split.next().unwrap().parse().unwrap(),
},
}
}
}
#[derive(Debug)]
struct P<T> {
x: T,
y: T,
}
fn _print_robots_on_map(robots: &[R], w: usize, h: usize, q: bool) {
for y in 0..h {
if q && y == h / 2 {
println!();
continue;
}
for x in 0..w {
if q && x == w / 2 {
print!(" ");
continue;
}
let robots_on_tile = robots.iter().filter(|r| r.p.x == x && r.p.y == y).count();
if robots_on_tile > 0 {
print!("{}", robots_on_tile);
} else {
//print!(".");
print!(" ");
}
}
println!();
}
}
fn part_one(input: &Path) -> anyhow::Result<usize> {
let reader = BufReader::new(File::open(input)?);
let mut robots: Vec<R> = vec![];
for line in reader.lines() {
robots.push(R::from_str(&line?));
}
//let (w, h) = (11, 7);
let (w, h) = (101, 103);
//print_robots_on_map(&robots, w, h, false);
for _ in 0..100 {
//for i in 0..10403 {
for robot in &mut robots {
let mut nx: i32 = robot.p.x as i32 + robot.v.x;
if nx >= w as i32 {
nx = (nx - w as i32).abs();
} else if nx < 0 {
nx = (nx + w as i32).abs();
}
let mut ny: i32 = robot.p.y as i32 + robot.v.y;
if ny >= h as i32 {
ny = (ny - h as i32).abs();
} else if ny < 0 {
ny = (ny + h as i32).abs();
}
robot.p.x = nx as usize;
robot.p.y = ny as usize;
}
//println!();
//print_robots_on_map(&robots, w, h, true);
}
//println!();
//print_robots_on_map(&robots, w, h, true);
let q1 = robots
.iter()
.filter(|r| r.p.x < w / 2 && r.p.y < h / 2)
.count();
let q2 = robots
.iter()
.filter(|r| r.p.x > w / 2 && r.p.y < h / 2)
.count();
let q3 = robots
.iter()
.filter(|r| r.p.x > w / 2 && r.p.y > h / 2)
.count();
let q4 = robots
.iter()
.filter(|r| r.p.x < w / 2 && r.p.y > h / 2)
.count();
Ok(q1 * q2 * q3 * q4)
}