Some progress on day 9
This commit is contained in:
parent
27483d052f
commit
9f337f8a6d
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
@ -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() {
|
fn main() {
|
||||||
let file_str = include_str!("input.txt");
|
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)]
|
#[cfg(test)]
|
||||||
@ -15,4 +102,4 @@ mod tests {
|
|||||||
fn get_data() -> &'static str {
|
fn get_data() -> &'static str {
|
||||||
include_str!("test-input.txt")
|
include_str!("test-input.txt")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user