Complete day 9 part 1
This commit is contained in:
parent
9f337f8a6d
commit
5717adcf1c
110
day9/src/main.rs
110
day9/src/main.rs
@ -11,7 +11,7 @@ use Direction::*;
|
|||||||
|
|
||||||
struct Move {
|
struct Move {
|
||||||
dir: Direction,
|
dir: Direction,
|
||||||
amount: usize,
|
amount: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Move {
|
impl Move {
|
||||||
@ -25,7 +25,7 @@ impl Move {
|
|||||||
"R" => Right,
|
"R" => Right,
|
||||||
_ => panic!("Invalid direction!"),
|
_ => panic!("Invalid direction!"),
|
||||||
};
|
};
|
||||||
let amount = parts[1].parse::<usize>().unwrap();
|
let amount = parts[1].parse::<isize>().unwrap();
|
||||||
|
|
||||||
Move { dir, amount }
|
Move { dir, amount }
|
||||||
}
|
}
|
||||||
@ -33,17 +33,23 @@ impl Move {
|
|||||||
|
|
||||||
#[derive(Debug, Default, Copy, Clone, Eq, Hash, PartialEq)]
|
#[derive(Debug, Default, Copy, Clone, Eq, Hash, PartialEq)]
|
||||||
struct Location {
|
struct Location {
|
||||||
x: usize,
|
x: isize,
|
||||||
y: usize,
|
y: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Location {
|
impl Location {
|
||||||
fn new(x: usize, y: usize) -> Self {
|
fn new(x: isize, y: isize) -> Self {
|
||||||
Location { x, y }
|
Location { x, y }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_distance(self, other: Self) -> f64 {
|
||||||
|
let squares = (other.x - self.x).pow(2) + (other.y - self.y).pow(2);
|
||||||
|
|
||||||
|
(squares as f64).sqrt()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
struct Rope {
|
struct Rope {
|
||||||
@ -55,21 +61,31 @@ struct Rope {
|
|||||||
|
|
||||||
impl Rope {
|
impl Rope {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Rope { ..Rope::default() }
|
let mut rope = Self::default();
|
||||||
|
rope.head_visited.insert(Location::default());
|
||||||
|
rope.tail_visited.insert(Location::default());
|
||||||
|
|
||||||
|
rope
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_head(&mut self, moves: Move) {
|
pub fn move_head(&mut self, moves: Move) {
|
||||||
let from = self.head;
|
|
||||||
|
|
||||||
for _ in 0..moves.amount {
|
for _ in 0..moves.amount {
|
||||||
let mut x = from.x;
|
let mut x = self.head.x;
|
||||||
let mut y = from.y;
|
let mut y = self.head.y;
|
||||||
|
|
||||||
match moves.dir {
|
match moves.dir {
|
||||||
Up => y += 1,
|
Up => {
|
||||||
Down => y -= 1,
|
y += 1;
|
||||||
Left => x -= 1,
|
}
|
||||||
Right => x += 1,
|
Down => {
|
||||||
|
y -= 1;
|
||||||
|
}
|
||||||
|
Left => {
|
||||||
|
x -= 1;
|
||||||
|
}
|
||||||
|
Right => {
|
||||||
|
x += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let to = Location::new(x, y);
|
let to = Location::new(x, y);
|
||||||
@ -80,7 +96,42 @@ impl Rope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_tail(&mut self, head: Location) {}
|
fn must_tail_move(&mut self, head: Location) -> bool {
|
||||||
|
let distance = self.tail.get_distance(head);
|
||||||
|
|
||||||
|
distance >= 2.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_tail(&mut self, head: Location) {
|
||||||
|
if !self.must_tail_move(head) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut tail = self.tail.clone();
|
||||||
|
|
||||||
|
if tail.y != head.y {
|
||||||
|
if head.y - tail.y < 0 {
|
||||||
|
tail.y -= 1;
|
||||||
|
} else {
|
||||||
|
tail.y += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tail.x != head.x {
|
||||||
|
if head.x - tail.x < 0 {
|
||||||
|
tail.x -= 1;
|
||||||
|
} else {
|
||||||
|
tail.x += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.tail = tail;
|
||||||
|
self.tail_visited.insert(tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_tail_pos_count(&self) -> usize {
|
||||||
|
self.tail_visited.len()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -93,6 +144,10 @@ fn main() {
|
|||||||
.lines()
|
.lines()
|
||||||
.map(Move::from_line)
|
.map(Move::from_line)
|
||||||
.for_each(|m| rope.move_head(m));
|
.for_each(|m| rope.move_head(m));
|
||||||
|
|
||||||
|
let tail_positions = rope.get_tail_pos_count();
|
||||||
|
|
||||||
|
println!("Part 1: Number of tail movements: {}", tail_positions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -102,4 +157,27 @@ mod tests {
|
|||||||
fn get_data() -> &'static str {
|
fn get_data() -> &'static str {
|
||||||
include_str!("test-input.txt")
|
include_str!("test-input.txt")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_location_get_distance() {
|
||||||
|
let a = Location::new(0, 0);
|
||||||
|
|
||||||
|
assert_eq!(a.get_distance(Location::new(0, 0)), 0.0);
|
||||||
|
assert_eq!(a.get_distance(Location::new(1, 0)), 1.0);
|
||||||
|
assert_eq!(a.get_distance(Location::new(1, 1)), 2.0f64.sqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_tail_position_count() {
|
||||||
|
let mut rope = Rope::new();
|
||||||
|
|
||||||
|
assert_eq!(rope.get_tail_pos_count(), 1);
|
||||||
|
|
||||||
|
get_data()
|
||||||
|
.lines()
|
||||||
|
.map(Move::from_line)
|
||||||
|
.for_each(|m| rope.move_head(m));
|
||||||
|
|
||||||
|
assert_eq!(rope.get_tail_pos_count(), 13);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user