Some progress on day 9

This commit is contained in:
Timothy Warren 2022-12-13 14:11:55 -05:00
parent 27483d052f
commit 9f337f8a6d
2 changed files with 90 additions and 95 deletions

View File

@ -1,92 +0,0 @@
/// A virtual 2d grid in an ordinary vector. Taken from day 8's puzzle solving implementation
#[derive(Debug)]
pub struct Grid<T> {
width: usize,
pub vec: Vec<T>,
}
impl<T> Grid<T> {
pub fn new(width: usize) -> Self {
Grid {
width,
vec: Vec::new(),
}
}
// Convert x,y coordinate into linear array index
pub fn xy_idx(&self, x: usize, y: usize) -> usize {
(y * self.width) + x
}
/// Convert linear array index to x,y coordinate
pub fn idx_xy(&self, idx: usize) -> (usize, usize) {
(idx % self.width, idx / self.width)
}
pub fn get(&self, idx: usize) -> Option<&T> {
self.vec.get(idx)
}
pub fn get_mut(&mut self, idx: usize) -> Option<&mut T> {
self.vec.get_mut(idx)
}
pub fn row_first_idx(&self, row: usize) -> usize {
let idx = row * self.width;
if idx < self.vec.len() {
idx
} else {
self.vec.len()
}
}
pub fn row_last_idx(&self, row: usize) -> usize {
if (row + 1) > self.num_rows() {
return self.vec.len();
}
self.row_first_idx(row + 1) - 1
}
pub fn num_rows(&self) -> usize {
self.vec.len() / self.width
}
pub fn num_cols(&self) -> usize {
self.width
}
pub fn get_row(&mut self, row_num: usize) -> &mut [T] {
let start = self.row_first_idx(row_num);
let end = self.row_last_idx(row_num);
&mut self.vec[start..=end]
}
pub fn get_row_indexes(&self, row_num: usize) -> Vec<usize> {
let start = self.row_first_idx(row_num);
let end = self.row_last_idx(row_num);
(start..=end).collect()
}
pub fn get_column_indexes(&self, col_num: usize) -> Vec<usize> {
let mut indexes = Vec::new();
if col_num >= self.num_cols() {
panic!(
"Asked for column {}, there are {} columns",
col_num,
self.num_cols()
);
}
for r in 0..self.num_rows() {
let idx = self.width * r + col_num;
indexes.push(idx);
}
indexes
}
}

View File

@ -1,11 +1,98 @@
mod grid;
use std::collections::HashSet;
use grid::Grid;
#[derive(Debug)]
enum Direction {
Up,
Down,
Left,
Right,
}
use Direction::*;
struct Move {
dir: Direction,
amount: usize,
}
impl Move {
fn from_line(line: &str) -> Self {
let parts: Vec<&str> = line.split_ascii_whitespace().collect();
let dir = match parts[0] {
"U" => Up,
"D" => Down,
"L" => Left,
"R" => Right,
_ => panic!("Invalid direction!"),
};
let amount = parts[1].parse::<usize>().unwrap();
Move { dir, amount }
}
}
#[derive(Debug, Default, Copy, Clone, Eq, Hash, PartialEq)]
struct Location {
x: usize,
y: usize,
}
impl Location {
fn new(x: usize, y: usize) -> Self {
Location { x, y }
}
}
// ----------------------------------------------------------------------------
#[derive(Debug, Default)]
struct Rope {
head: Location,
tail: Location,
head_visited: HashSet<Location>,
tail_visited: HashSet<Location>,
}
impl Rope {
pub fn new() -> Self {
Rope { ..Rope::default() }
}
pub fn move_head(&mut self, moves: Move) {
let from = self.head;
for _ in 0..moves.amount {
let mut x = from.x;
let mut y = from.y;
match moves.dir {
Up => y += 1,
Down => y -= 1,
Left => x -= 1,
Right => x += 1,
}
let to = Location::new(x, y);
self.move_tail(to);
self.head = to;
self.head_visited.insert(to);
}
}
fn move_tail(&mut self, head: Location) {}
}
// ----------------------------------------------------------------------------
fn main() {
let file_str = include_str!("input.txt");
let mut rope = Rope::new();
file_str
.lines()
.map(Move::from_line)
.for_each(|m| rope.move_head(m));
}
#[cfg(test)]