Skip to content

Commit

Permalink
[2024] Cleanup day 14
Browse files Browse the repository at this point in the history
  • Loading branch information
connorslade committed Dec 14, 2024
1 parent eff9739 commit 3b5690a
Showing 1 changed file with 42 additions and 68 deletions.
110 changes: 42 additions & 68 deletions aoc_2024/src/day_14.rs
Original file line number Diff line number Diff line change
@@ -1,87 +1,78 @@
use std::io::stdin;

use common::{solution, Answer};
use itertools::Itertools;
use nd_vec::{vector, Vec2};

solution!("Restroom Redoubt", 14);

// Part A was easy enough, just implement the logic and run it for 100 ticks. To
// be more efferent, instead of adding the velocity to the position of each
// robot on each tick, you can just add vel * ticks then basically modulo to put
// it back in bounds.
fn part_a(input: &str) -> Answer {
let mut problem = Problem::parse(input);

// println!();
for _ in 0..100 {
problem.tick();
}
// problem.debug();
problem.tick(100);
problem.score().into()
}

// When I read todays part B, I was just so confused for a while. To find boards
// that were likely showing some pattern, I just sum the distances from each
// robot to the board center, when this drops below a set threshold, I assume
// that is the tree. You can uncomment the .debug() call to actually see the
// tree.
fn part_b(input: &str) -> Answer {
let mut problem = Problem::parse(input);

// println!();
for i in 0..10_000 {
problem.tick();
// println!("{} v", i + 1);
// problem.debug();
// println!();
// println!("{}", problem.total_distance());

if problem.total_distance() < 6_000_000 {
println!("{}", problem.total_distance());
println!("{} v", i + 1);
problem.debug();
stdin().read_line(&mut String::new());
for i in 0.. {
problem.tick(1);
if problem.total_distance() < 20_000 {
// problem.debug();
return (i + 1).into();
}
}
// problem.debug();
problem.score().into()

unreachable!()
}

// rename
#[derive(Debug)]
struct Problem {
bounds: Vec2<i32>,
robots: Vec<Robot>,
}

#[derive(Debug)]
struct Robot {
pos: Vec2<i32>,
vel: Vec2<i32>,
}

impl Problem {
fn parse(input: &str) -> Self {
let robots = input.lines().map(|x| Robot::parse(x)).collect::<Vec<_>>();
let robots = input.lines().map(Robot::parse).collect::<Vec<_>>();

let mut bounds = vector!(0, 0);
for robot in robots.iter() {
bounds = vector!(robot.pos.x().max(bounds.x()), robot.pos.y().max(bounds.y()));
}
bounds += vector!(1, 1);
robots.iter().for_each(|robot| {
bounds = vector!(robot.pos.x().max(bounds.x()), robot.pos.y().max(bounds.y()))
});

Self { robots, bounds }
Self {
robots,
bounds: bounds + vector!(1, 1),
}
}

fn tick(&mut self) {
self.robots.iter_mut().for_each(|x| x.tick(self.bounds));
fn tick(&mut self, n: i32) {
self.robots.iter_mut().for_each(|x| x.tick(self.bounds, n));
}

fn total_distance(&self) -> i32 {
let mut sum = 0;
for (a, b) in self.robots.iter().tuple_combinations() {
sum += a.pos.manhattan_distance(&b.pos);
}
sum
let middle = self.bounds / 2;
self.robots
.iter()
.map(|x| x.pos.manhattan_distance(&middle))
.sum()
}

#[allow(unused)]
fn debug(&self) {
let half_bounds = self.bounds / 2;

for y in (0..self.bounds.y()) {
for x in (0..self.bounds.x()) {
for y in 0..self.bounds.y() {
for x in 0..self.bounds.x() {
let robots = self
.robots
.iter()
Expand All @@ -101,19 +92,14 @@ impl Problem {
fn score(&self) -> u32 {
let half_bounds = self.bounds / 2;

// 0 1 2 3 4

let mut quadrants = [0; 4];
for robot in self.robots.iter() {
let pos = robot.pos;

for pos in self.robots.iter().map(|x| x.pos) {
if pos.x() == half_bounds.x() || pos.y() == half_bounds.y() {
continue;
}

let width = (0..=half_bounds.x()).contains(&pos.x());
let height = (0..=half_bounds.y()).contains(&pos.y());

quadrants[((width as usize) << 1) | height as usize] += 1;
}

Expand All @@ -135,24 +121,12 @@ impl Robot {
}
}

fn tick(&mut self, bounds: Vec2<i32>) {
self.pos += self.vel;

while self.pos.x() < 0 {
self.pos += vector!(bounds.x(), 0);
}

while self.pos.x() >= bounds.x() {
self.pos -= vector!(bounds.x(), 0);
}

while self.pos.y() < 0 {
self.pos += vector!(0, bounds.y());
}

while self.pos.y() >= bounds.y() {
self.pos -= vector!(0, bounds.y());
}
fn tick(&mut self, bounds: Vec2<i32>, n: i32) {
self.pos += self.vel * n;
self.pos = vector!(
(self.pos.x() % bounds.x() + bounds.x()) % bounds.x(),
(self.pos.y() % bounds.y() + bounds.y()) % bounds.y()
);
}
}

Expand Down

0 comments on commit 3b5690a

Please sign in to comment.