finish day 9

This commit is contained in:
Joseph Montanaro 2022-12-09 22:41:21 -08:00
parent 9236e70abe
commit 9ef31dde55

View File

@ -1,4 +1,5 @@
use std::collections::HashSet;
use std::fmt::{Display, Formatter};
use std::str::FromStr;
@ -35,14 +36,14 @@ struct Pos {
#[derive(Debug)]
struct Rope<const L: usize> {
knots: [Pos; L],
tail_visited: HashSet<Pos>
tail_visited: HashSet<Pos>,
}
impl<const L: usize> Rope<L> {
fn new() -> Self {
Rope {
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()) {
self.move_follower(i);
self.move_follower(i);
}
self.tail_visited.insert(*self.knots.last().unwrap());
@ -72,9 +73,9 @@ impl<const L: usize> Rope<L> {
let dy = leader.y - follower.y;
// check to make sure that we didn't do anything wrong previously
if dx.abs() + dy.abs() > 3
|| dx.abs() == 0 && dy.abs() == 3
|| dx.abs() == 3 && dy.abs() == 0
if dx.abs() + dy.abs() > 4
|| dx.abs() == 0 && dy.abs() > 2
|| dx.abs() > 2 && dy.abs() == 0
{
panic!("Invalid head and tail positions: {dx}, {dy}");
}
@ -98,6 +99,43 @@ impl<const L: usize> Rope<L> {
follower.y += dy;
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>>()?;
let mut rope = Rope::<10>::new();
for (dir, dist) in instructions {
rope.do_move(dir, dist)
let mut rope1 = Rope::<2>::new();
for &(dir, dist) in &instructions {
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(())
}
// const DATA: &'static str = include_str!("../data/day9.txt");
const DATA: &'static str = "
R 5
U 8
L 8
D 3
R 17
D 10
L 25
U 20
";
const DATA: &'static str = include_str!("../data/day9.txt");
// const DATA: &'static str = "
// R 5
// U 8
// L 8
// D 3
// R 17
// D 10
// L 25
// U 20
// ";