finish day 9
This commit is contained in:
parent
9236e70abe
commit
9ef31dde55
@ -1,4 +1,5 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
|
||||||
@ -35,14 +36,14 @@ struct Pos {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Rope<const L: usize> {
|
struct Rope<const L: usize> {
|
||||||
knots: [Pos; L],
|
knots: [Pos; L],
|
||||||
tail_visited: HashSet<Pos>
|
tail_visited: HashSet<Pos>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const L: usize> Rope<L> {
|
impl<const L: usize> Rope<L> {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Rope {
|
Rope {
|
||||||
knots: [Pos {x: 0, y: 0}; L],
|
knots: [Pos {x: 0, y: 0}; L],
|
||||||
tail_visited: HashSet::new(),
|
tail_visited: HashSet::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ impl<const L: usize> Rope<L> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i in 1..(self.knots.len()) {
|
for i in 1..(self.knots.len()) {
|
||||||
self.move_follower(i);
|
self.move_follower(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tail_visited.insert(*self.knots.last().unwrap());
|
self.tail_visited.insert(*self.knots.last().unwrap());
|
||||||
@ -72,9 +73,9 @@ impl<const L: usize> Rope<L> {
|
|||||||
let dy = leader.y - follower.y;
|
let dy = leader.y - follower.y;
|
||||||
|
|
||||||
// check to make sure that we didn't do anything wrong previously
|
// check to make sure that we didn't do anything wrong previously
|
||||||
if dx.abs() + dy.abs() > 3
|
if dx.abs() + dy.abs() > 4
|
||||||
|| dx.abs() == 0 && dy.abs() == 3
|
|| dx.abs() == 0 && dy.abs() > 2
|
||||||
|| dx.abs() == 3 && dy.abs() == 0
|
|| dx.abs() > 2 && dy.abs() == 0
|
||||||
{
|
{
|
||||||
panic!("Invalid head and tail positions: {dx}, {dy}");
|
panic!("Invalid head and tail positions: {dx}, {dy}");
|
||||||
}
|
}
|
||||||
@ -98,6 +99,43 @@ impl<const L: usize> Rope<L> {
|
|||||||
follower.y += dy;
|
follower.y += dy;
|
||||||
follower.x += dx / 2;
|
follower.x += dx / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// offset by 2 in both dimensions
|
||||||
|
if dx.abs() == 2 && dy.abs() == 2 {
|
||||||
|
follower.x += dx / 2;
|
||||||
|
follower.y += dy / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
impl<const L: usize> Display for Rope<L> {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
|
||||||
|
let min_x = self.knots.iter().map(|pos| pos.x).min().unwrap();
|
||||||
|
let max_x = self.knots.iter().map(|pos| pos.x).max().unwrap();
|
||||||
|
let min_y = self.knots.iter().map(|pos| pos.y).min().unwrap();
|
||||||
|
let max_y = self.knots.iter().map(|pos| pos.y).max().unwrap();
|
||||||
|
|
||||||
|
let n_rows = usize::try_from(max_y - min_y + 1).unwrap();
|
||||||
|
let n_cols = usize::try_from(max_x - min_x + 1).unwrap();
|
||||||
|
let mut grid = vec![vec!['.'; n_cols]; n_rows];
|
||||||
|
|
||||||
|
for (i, kt) in self.knots.iter().enumerate() {
|
||||||
|
let rel_x = usize::try_from(kt.x - min_x).unwrap();
|
||||||
|
let rel_y = usize::try_from(max_y - kt.y).unwrap();
|
||||||
|
let tgt = &mut grid[rel_y][rel_x];
|
||||||
|
if *tgt == '.' {
|
||||||
|
*tgt = char::from_digit(i as u32, 10).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for row in grid {
|
||||||
|
write!(f, "{}\n", row.iter().collect::<String>())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,24 +155,30 @@ fn main() -> Result<(), String> {
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<(Direction, isize)>, String>>()?;
|
.collect::<Result<Vec<(Direction, isize)>, String>>()?;
|
||||||
|
|
||||||
let mut rope = Rope::<10>::new();
|
let mut rope1 = Rope::<2>::new();
|
||||||
for (dir, dist) in instructions {
|
for &(dir, dist) in &instructions {
|
||||||
rope.do_move(dir, dist)
|
rope1.do_move(dir, dist);
|
||||||
}
|
}
|
||||||
println!("{}", rope.tail_visited.len());
|
println!("Part 1: {}", rope1.tail_visited.len());
|
||||||
|
|
||||||
|
let mut rope2 = Rope::<10>::new();
|
||||||
|
for &(dir, dist) in &instructions {
|
||||||
|
rope2.do_move(dir, dist);
|
||||||
|
}
|
||||||
|
println!("Part 2: {}", rope2.tail_visited.len());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// const DATA: &'static str = include_str!("../data/day9.txt");
|
const DATA: &'static str = include_str!("../data/day9.txt");
|
||||||
const DATA: &'static str = "
|
// const DATA: &'static str = "
|
||||||
R 5
|
// R 5
|
||||||
U 8
|
// U 8
|
||||||
L 8
|
// L 8
|
||||||
D 3
|
// D 3
|
||||||
R 17
|
// R 17
|
||||||
D 10
|
// D 10
|
||||||
L 25
|
// L 25
|
||||||
U 20
|
// U 20
|
||||||
";
|
// ";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user