Add 2022 day 9

This commit is contained in:
Kienan Stewart 2022-12-09 12:17:30 -05:00
parent 5c99510c25
commit e79611a922
6 changed files with 2253 additions and 0 deletions

14
2022/9/Cargo.lock generated Normal file
View File

@ -0,0 +1,14 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "common"
version = "0.1.0"
[[package]]
name = "day9"
version = "0.1.0"
dependencies = [
"common",
]

9
2022/9/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "day9"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
common = { path = "../common" }

2000
2022/9/input Normal file

File diff suppressed because it is too large Load Diff

214
2022/9/src/main.rs Normal file
View File

@ -0,0 +1,214 @@
use std::str::FromStr;
fn main() {
let input_file = common::parse_args_input_file(&mut std::env::args());
let contents = std::fs::read_to_string(input_file).expect("Failed to read input file");
let mut set = std::collections::HashSet::<Point>::new();
set.insert(Point { x: 0, y: 0 });
let mut head = Point {
x: 0,
y: 0,
};
let mut tail = Point {
x: 0,
y: 0,
};
let mut knots = std::vec::Vec::<Point>::new();
let mut p2_set = std::collections::HashSet::<Point>::new();
p2_set.insert(Point{ x: 0, y: 0 });
for i in 0..10 {
knots.push(Point { x: 0, y: 0 });
}
for line in contents.lines() {
if line.eq("") {
continue;
}
let words: std::vec::Vec::<&str> = line.split(' ').collect();
assert_eq!(words.len(), 2);
let steps = i32::from_str(words[1]).unwrap();
let direction = words[0].chars().nth(0).unwrap();
head.add(&Point::displacement(direction, steps));
let mut adjustment = tail.towards(&head);
while adjustment != (Point {x: 0, y: 0}) {
tail.add(&adjustment);
set.insert(tail.clone());
adjustment = tail.towards(&head);
}
// Simulate part 2
knots[0].add(&Point::displacement(direction, steps));
let mut moved = true;
while moved {
moved = false;
for i in 1..10 {
let h = knots[i-1].clone();
let adjustment = knots[i].towards(&h);
if adjustment != (Point {x: 0, y: 0}) {
moved = true;
knots[i].add(&adjustment);
if i == 9 {
println!("{:?}", knots[i]);
p2_set.insert(knots[i].clone());
}
}
}
}
// for i in 1..10 {
// let h = knots[i - 1].clone();
// let mut adjustment = knots[i].towards(&h);
// while adjustment != (Point {x: 0, y: 0}) {
// // println!("Knot {}: {:?} towards {:?} : {:?}", i, knots[i], h, adjustment);
// knots[i].add(&adjustment);
// if i == 9 {
// println!("{:?}", knots[i]);
// p2_set.insert(knots[i].clone());
// }
// adjustment = knots[i].towards(&h);
// // println!("\tNew adjustment: {:?}", adjustment);
// }
// }
// println!("{}{}: {:?}", direction, steps, knots);
// print_set(&p2_set);
}
println!("[PART 1] Tail visited {} points", set.len());
println!("[PART 2] Tail visited {} points", p2_set.len());
}
fn print_set(set: &std::collections::HashSet<Point>) {
let mut min_x = 0;
let mut max_x = 0;
let mut min_y = 0;
let mut max_y = 0;
for point in set.iter() {
min_x = std::cmp::min(point.x, min_x);
min_y = std::cmp::min(point.y, min_y);
max_x = std::cmp::max(point.x, max_x);
max_y = std::cmp::max(point.y, max_y);
}
println!("{},{} to {},{}", min_x, max_y, max_x, min_y);
for y in 0..=(max_y-min_y) {
for x in min_x..=max_x {
let p = Point { x: x, y: max_y - y };
if x == 0 && (max_y - y) == 0 {
print!("s");
continue;
}
if set.contains(&p) {
print!("#");
}
else {
print!(".");
}
}
println!("");
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
struct Point {
x: i32,
y: i32,
}
impl Point {
fn displacement(direction: char, magnitude: i32) -> Point {
let delta = match direction {
'U' => Point { x: 0, y: magnitude },
'D' => Point { x: 0, y: -magnitude},
'L' => Point { x: -magnitude, y: 0 },
'R' => Point { x: magnitude, y: 0 },
_ => unreachable!(),
};
return delta;
}
fn add(&mut self, delta: &Point) {
self.x += delta.x;
self.y += delta.y;
}
fn touching(&self, other: &Point) -> bool {
let d = self.delta(other);
return d.x.abs() < 2 && d.y.abs() < 2;
}
fn delta(&self, other: &Point) -> Point {
return Point {
x: (self.x - other.x),
y: (self.y - other.y),
};
}
fn towards(&self, other: &Point) -> Point {
if self.touching(other) {
return Point {x: 0, y: 0};
}
let mut delta = self.delta(other);
delta.unit();
let dir_x = if self.x > other.x { -1 } else { 1 };
delta.x *= dir_x;
let dir_y = if self.y > other.y { -1 } else { 1 };
delta.y *= dir_y;
return delta;
}
fn unit(&mut self) {
let larger = std::cmp::max(self.x.abs(), self.y.abs()) as f32;
assert!(larger != 0.0);
self.x = (self.x.abs() as f32 / larger).ceil() as i32;
self.y = (self.y.abs() as f32 / larger).ceil() as i32;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn towards() {
let no_movement = Point { x: 0, y: 0 };
let down = Point { x: 0, y: -1 };
let up = Point { x: 0, y: 1 };
let left = Point { x: -1, y: 0 };
let right = Point { x: 1, y: 0 };
let diag_dr = Point { x: 1, y: -1 };
let diag_dl = Point { x: -1, y: -1 };
let diag_ur = Point { x: 1, y: 1 };
let diag_ul = Point { x: -1, y: 1 };
let h = Point { x: 0, y: 0 };
for x in -1..2 as i32 {
for y in -1..2 as i32 {
let p = Point { x: x, y: y };
println!("{},{}", x, y);
assert_eq!(p.towards(&h), no_movement);
}
}
let tests = vec![
vec![Point { x: -2, y: 2 }, diag_dr.clone()],
vec![Point { x: -1, y: 2 }, diag_dr.clone()],
vec![Point { x: 0, y: 2 }, down.clone()],
vec![Point { x: 1, y: 2 }, diag_dl.clone()],
vec![Point { x: 2, y: 2 }, diag_dl.clone()],
vec![Point { x: -2, y: -2 }, diag_ur.clone()],
vec![Point { x: -1, y: -2 }, diag_ur.clone()],
vec![Point { x: 0, y: -2 }, up.clone()],
vec![Point { x: 1, y: -2 }, diag_ul.clone()],
vec![Point { x: 2, y: -2 }, diag_ul.clone()],
vec![Point { x: -2, y: 1 }, diag_dr.clone()],
vec![Point { x: -2, y: 0 }, right.clone()],
vec![Point { x: -2, y: -1 }, diag_ur.clone()],
vec![Point { x: 2, y: 1 }, diag_dl.clone()],
vec![Point { x: 2, y: 0 }, left.clone()],
vec![Point { x: 2, y: -1 }, diag_ul.clone()],
];
for t in tests.iter() {
println!("{:?}", t[0]);
assert_eq!(t[0].towards(&h), t[1]);
}
}
}

8
2022/9/test_input Normal file
View File

@ -0,0 +1,8 @@
R 4
U 4
L 3
D 1
R 4
D 1
L 5
R 2

8
2022/9/test_input2 Normal file
View File

@ -0,0 +1,8 @@
R 5
U 8
L 8
D 3
R 17
D 10
L 25
U 20