Files
advent-of-code-2024/src/bin/d14p1.rs
T
2024-12-16 22:48:56 -08:00

136 lines
3.4 KiB
Rust

use std::{
collections::{HashMap, HashSet},
thread,
time::Duration,
};
use advent_of_code_2024::{make_main, next, Pair, SResult};
use regex::Regex;
make_main!();
fn solve(lines: Vec<String>) -> SResult<(usize, usize)> {
// NOTE: this needs to be adjusted for the size of the grid
let dims = (101, 103);
let pos_regex = Regex::new(r"p=(?<x>\d+),(?<y>\d+) v=(?<xvel>-?\d+),(?<yvel>-?\d+)").unwrap();
let mut robots = vec![];
for line in lines {
let caps = pos_regex.captures(&line.trim()).unwrap();
let x = caps["x"].parse::<usize>().unwrap();
let y = caps["y"].parse::<usize>().unwrap();
let xvel = caps["xvel"].parse::<i64>().unwrap();
let yvel = caps["yvel"].parse::<i64>().unwrap();
robots.push(Robot {
vel: (xvel, yvel),
pos: (x, y),
})
}
// Simulation GO
// 79, 388, 491, 697, 800, 903, 1006, 1109, 1212, 1315
let millis = Duration::from_millis(10);
let mut n = 0;
let mut tens = 11usize;
let mut ones = 24usize;
loop {
if (n / 100 == tens && n % 100 == ones) || (n >= 800 && (n - 800) % 103 == 0) {
print!("{}[2J", 27 as char);
println!("{}", n);
print_grid(&robots, dims);
if (n / 100 == tens && n % 100 == ones) {
tens += 1;
ones += 1;
}
thread::sleep(millis);
}
n += 1;
for robot in robots.iter_mut() {
robot.advance(dims);
}
}
//Ok((calc_safety(&robots, dims).iter().fold(1, |x, y| x * y), 0))
}
#[derive(Debug)]
struct Robot {
vel: Pair<i64>,
pos: Pair,
}
impl Robot {
fn advance(&mut self, dims: Pair) {
self.pos.0 = roll(self.pos.0, self.vel.0, dims.0);
self.pos.1 = roll(self.pos.1, self.vel.1, dims.1);
}
}
fn roll(pos: usize, vel: i64, dim: usize) -> usize {
let ipos = pos as i64;
if ipos + vel >= 0 {
((ipos + vel) as usize) % dim
} else {
((ipos + vel) + dim as i64) as usize
}
}
fn calc_safety(robots: &[Robot], dims: Pair) -> [usize; 4] {
let mut scores = [0usize; 4];
for robot in robots {
let xhalf = part(robot.pos.0, dims.0);
let yhalf = part(robot.pos.1, dims.1);
match (xhalf, yhalf) {
(0, 0) => scores[0] += 1,
(0, 1) => scores[1] += 1,
(1, 0) => scores[2] += 1,
(1, 1) => scores[3] += 1,
_ => {
// Do nothing; this is expected
}
}
}
scores
}
fn part(pos: usize, dim: usize) -> usize {
if pos < dim / 2 {
0
} else if pos > dim / 2 {
1
} else {
2
}
}
fn print_grid(robots: &[Robot], dims: Pair) {
println!("");
let mut pos = HashMap::new();
for rob in robots {
*pos.entry(rob.pos).or_insert(0) += 1;
}
for j in 0..dims.1 {
for i in 0..dims.0 {
if let Some(count) = pos.get(&(i, j)) {
print!("{}", count);
} else {
print!(" ");
}
}
println!("");
}
println!("");
}
#[cfg(test)]
mod tests {
use advent_of_code_2024::input;
use super::*;
#[test]
fn d14p1() {
return;
let strings: Vec<String> = input!("d14p1.txt");
let got = solve(strings).unwrap();
assert_eq!(got, (12, 0));
}
}