Skip to content

Instantly share code, notes, and snippets.

@weirddan455
Created December 17, 2024 19:44
Show Gist options
  • Save weirddan455/f871942a8ce50c21a7be832125a1c749 to your computer and use it in GitHub Desktop.
Save weirddan455/f871942a8ce50c21a7be832125a1c749 to your computer and use it in GitHub Desktop.
Advent of Code Day 15 Part 2 (not working)
use std::ops::{Add, AddAssign};
#[derive(Clone, Copy)]
enum Direction {
Up,
Down,
Left,
Right
}
#[derive(Clone, Copy, PartialEq, Eq)]
struct Vector2 {
x: i32,
y: i32
}
impl Add<Direction> for Vector2 {
type Output = Self;
fn add(self, rhs: Direction) -> Self::Output {
match rhs {
Direction::Up => Self{x: self.x, y: self.y - 1},
Direction::Down => Self{x: self.x, y: self.y + 1},
Direction::Left => Self{x: self.x - 1, y: self.y},
Direction::Right => Self{x: self.x + 1, y: self.y}
}
}
}
impl AddAssign<Direction> for Vector2 {
fn add_assign(&mut self, rhs: Direction) {
match rhs {
Direction::Up => self.y -= 1,
Direction::Down => self.y += 1,
Direction::Left => self.x -= 1,
Direction::Right => self.x += 1,
}
}
}
#[derive(Clone, Copy, PartialEq, Eq)]
struct Rect {
pos: Vector2,
width: i32,
height: i32
}
impl Add<Direction> for Rect {
type Output = Self;
fn add(self, rhs: Direction) -> Self::Output {
Self {
pos: self.pos + rhs,
width: self.width,
height: self.height
}
}
}
impl AddAssign<Direction> for Rect {
fn add_assign(&mut self, rhs: Direction) {
self.pos += rhs;
}
}
impl Rect {
fn collides(&self, other: &Rect) -> bool {
self.pos.x < other.pos.x + other.width &&
self.pos.x + self.width > other.pos.x &&
self.pos.y < other.pos.y + other.height &&
self.pos.y + self.height > other.pos.y
}
fn can_move(&self, dir: Direction, walls: &Vec<Rect>, boxes: &Vec<Rect>) -> Option<Vec<usize>> {
let new_rect = *self + dir;
for w in walls {
if new_rect.collides(w) {
return None;
}
}
let mut ret = Vec::new();
for (i, b) in boxes.iter().enumerate() {
if b == self {
continue;
}
if new_rect.collides(b) {
match b.can_move(dir, walls, boxes) {
Some(mut v) => {
ret.push(i);
ret.append(&mut v);
},
None => return None
}
}
}
Some(ret)
}
fn move_dir(&mut self, dir: Direction, walls: &Vec<Rect>, boxes: &mut Vec<Rect>) {
if let Some(v) = self.can_move(dir, walls, boxes) {
*self += dir;
for i in v {
boxes[i] += dir;
}
}
}
}
struct Input {
robot: Rect,
walls: Vec<Rect>,
boxes: Vec<Rect>,
directions: Vec<Direction>
}
fn parse_input() -> Input {
let data = std::fs::read("input").unwrap();
let mut iter = data.split(|&c| c == b'\n');
let mut width: i32 = 0;
let mut y: i32 = 0;
let mut robot = None;
let mut walls = Vec::new();
let mut boxes = Vec::new();
while let Some(line) = iter.next() {
if line.is_empty() {
break;
}
if width == 0 {
width = line.len().try_into().unwrap();
} else {
let w: i32 = line.len().try_into().unwrap();
assert_eq!(w, width, "Unequal grid widths");
}
let mut x: i32 = 0;
for c in line {
match *c {
b'#' => walls.push(Rect{
pos: Vector2{x, y},
width: 2,
height: 1
}),
b'O' => boxes.push(Rect{
pos: Vector2{x, y},
width: 2,
height: 1
}),
b'.' => {},
b'@' => {
assert!(robot.is_none(), "Found more than one robot");
robot = Some(Rect{
pos: Vector2{x, y},
width: 1,
height: 1
});
}
_ => panic!("Invalid char in grid: {}", *c as char)
}
x += 2;
}
y += 1;
}
let mut directions = Vec::new();
while let Some(line) = iter.next() {
for c in line {
match *c {
b'^' => directions.push(Direction::Up),
b'<' => directions.push(Direction::Left),
b'>' => directions.push(Direction::Right),
b'v' => directions.push(Direction::Down),
_ => panic!("Invalid char in input: {}", *c as char)
}
}
}
assert!(!directions.is_empty(), "Failed to parse directions");
assert!(!walls.is_empty(), "Failed to parse walls");
assert!(!boxes.is_empty(), "Failed to parse boxes");
Input {
robot: robot.expect("Failed to find robot"),
walls,
boxes,
directions
}
}
fn main() {
let mut input = parse_input();
for dir in input.directions {
input.robot.move_dir(dir, &input.walls, &mut input.boxes);
}
let mut answer = 0;
for b in input.boxes {
answer += b.pos.y * 100 + b.pos.x;
}
println!("Answer: {answer}");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment