Day 9, parts 1 + 2!

This commit is contained in:
Eryn Wells 2022-12-14 16:55:27 -08:00
parent 5335b160cd
commit 2ce2edca0d
4 changed files with 2226 additions and 0 deletions

2000
2022/Data/day9-input.txt Normal file

File diff suppressed because it is too large Load diff

98
2022/aoc2022/src/day9.rs Normal file
View file

@ -0,0 +1,98 @@
use crate::grid::{Direction, Point};
use std::collections::HashSet;
const INPUT: &'static str = include_str!("../../Data/day9-input.txt");
type SignedPoint = Point;
struct Rope {
nodes: Vec<SignedPoint>,
}
impl Rope {
fn with_length(length: usize) -> Rope {
Rope {
nodes: vec![SignedPoint::zero(); length],
}
}
fn move_head(&mut self, direction: Direction) {
if let Some(head) = self.nodes.first_mut() {
head.move_by_one_in(direction);
println!("{}", &head);
for i in 1..self.nodes.len() {
let first = self.nodes[i - 1].clone();
let mut second = self.nodes.get_mut(i).unwrap();
let distance = second.distance_to(&first);
if distance.0 == 2 {
second.x += 1;
if distance.1 < 0 {
second.y -= 1;
} else if distance.1 > 0 {
second.y += 1;
}
} else if distance.0 == -2 {
second.x -= 1;
if distance.1 < 0 {
second.y -= 1;
} else if distance.1 > 0 {
second.y += 1;
}
} else if distance.1 == 2 {
second.y += 1;
if distance.0 < 0 {
second.x -= 1;
} else if distance.0 > 0 {
second.x += 1;
}
} else if distance.1 == -2 {
second.y -= 1;
if distance.0 < 0 {
second.x -= 1;
} else if distance.0 > 0 {
second.x += 1;
}
}
}
}
}
}
pub fn main(_filename: &str) -> std::io::Result<()> {
let mut visited_points: HashSet<SignedPoint> = HashSet::new();
let mut long_rope_visited_points: HashSet<SignedPoint> = HashSet::new();
let mut rope = Rope::with_length(2);
let mut long_rope = Rope::with_length(10);
for line in INPUT.lines() {
let mut split_line = line.split(" ");
let direction = Direction::from_relative_direction(split_line.next().unwrap()).unwrap();
let count = u8::from_str_radix(split_line.next().unwrap(), 10).unwrap();
for _ in 0..count {
rope.move_head(direction);
if let Some(last_node) = rope.nodes.last() {
visited_points.insert(last_node.clone());
}
long_rope.move_head(direction);
if let Some(last_node) = long_rope.nodes.last() {
long_rope_visited_points.insert(last_node.clone());
}
}
}
println!(
"Part 1: number of points tail node visited: {}",
&visited_points.len()
);
println!(
"Part 2: number of points tail node of long rope visited: {}",
&long_rope_visited_points.len()
);
Ok(())
}

125
2022/aoc2022/src/grid.rs Normal file
View file

@ -0,0 +1,125 @@
#[derive(Clone, Copy, Debug)]
pub enum Direction {
North,
East,
South,
West,
}
impl Direction {
pub fn all() -> &'static [Direction] {
&[
Direction::North,
Direction::East,
Direction::South,
Direction::West,
]
}
pub fn from_relative_direction(letter: &str) -> Option<Direction> {
match letter {
"U" | "u" => Some(Direction::North),
"R" | "r" => Some(Direction::East),
"D" | "d" => Some(Direction::South),
"L" | "l" => Some(Direction::West),
_ => None,
}
}
}
#[derive(Debug)]
struct Grid<T: Clone + Copy> {
grid: Vec<Vec<T>>,
}
impl<T> Grid<T>
where
T: Clone + Copy,
{
pub fn new(size: usize, item: T) -> Grid<T> {
let vectors = (0..size).map(|_| vec![item; size]).collect::<Vec<Vec<T>>>();
Grid { grid: vectors }
}
pub fn height(&self) -> usize {
self.grid.len()
}
pub fn width(&self) -> usize {
self.grid[0].len()
}
pub fn get_at(&self, pt: &Point) -> Option<&T> {
if let Some(row) = self.grid.get(pt.y as usize) {
row.get(pt.x as usize)
} else {
None
}
}
pub fn set_at(&mut self, pt: &Point, value: T) -> Result<(), &str> {
if let Some(row) = self.grid.get_mut(pt.y as usize) {
if pt.x < row.len() as i32 {
row[pt.x as usize] = value;
Ok(())
} else {
Err("Unable to set")
}
} else {
Err("Unable to set")
}
}
pub fn iter_points(&self) -> Box<dyn Iterator<Item = Point>> {
let width = self.width();
Box::new(
(0..self.height())
.map(move |y| (0..width).map(move |x| Point::new(x as i32, y as i32)))
.flatten(),
)
}
}
impl<T: Clone + Copy> From<Vec<Vec<T>>> for Grid<T> {
fn from(grid: Vec<Vec<T>>) -> Grid<T> {
Grid { grid }
}
}
/**
* A point in standard coordinates, where Y values grow in the positively in the North direction.
*/
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Point {
pub x: i32,
pub y: i32,
}
impl Point {
pub fn zero() -> Point {
Point::new(0, 0)
}
pub fn new(x: i32, y: i32) -> Point {
Point { x, y }
}
pub fn distance_to(&self, other: &Point) -> (i32, i32) {
(other.x - self.x, other.y - self.y)
}
pub fn move_by_one_in(&mut self, direction: Direction) {
match direction {
Direction::North => self.y += 1,
Direction::East => self.x += 1,
Direction::South => self.y -= 1,
Direction::West => self.x -= 1,
}
}
}
impl std::fmt::Display for Point {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}

View file

@ -9,7 +9,9 @@ mod day5;
mod day6;
mod day7;
mod day8;
mod day9;
mod file;
mod grid;
fn main() {
let days = [
@ -21,6 +23,7 @@ fn main() {
day6::main,
day7::main,
day8::main,
day9::main,
];
let args: Vec<String> = env::args().collect();