[rs] Solve 2022_09 part 2
This commit is contained in:
parent
25d4e0298d
commit
6812df3cfe
7 changed files with 93 additions and 50 deletions
|
|
@ -1,2 +1,2 @@
|
||||||
Part 1: 6311
|
Part 1: 6311
|
||||||
Part 2: ???
|
Part 2: 2482
|
||||||
|
|
|
||||||
|
|
@ -1,60 +1,93 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
use std::iter;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
fn move_head(dir: &str, head: (i32, i32)) -> (i32, i32) {
|
||||||
enum Direction {
|
match dir {
|
||||||
Left,
|
"L" => (head.0 - 1, head.1),
|
||||||
Right,
|
"R" => (head.0 + 1, head.1),
|
||||||
Down,
|
"D" => (head.0, head.1 - 1),
|
||||||
Up,
|
"U" => (head.0, head.1 + 1),
|
||||||
|
_ => head,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Direction {
|
fn move_tail(anchor: (i32, i32), tail: (i32, i32)) -> (i32, i32) {
|
||||||
fn from_str(s: &str) -> Option<Self> {
|
let mut dx = anchor.0 - tail.0;
|
||||||
match s {
|
let mut dy = anchor.1 - tail.1;
|
||||||
"L" => Some(Self::Left),
|
|
||||||
"R" => Some(Self::Right),
|
if dx.abs() == dy.abs() {
|
||||||
"D" => Some(Self::Down),
|
// Move diagonally
|
||||||
"U" => Some(Self::Up),
|
dx = dx.signum();
|
||||||
_ => None,
|
dy = dy.signum();
|
||||||
}
|
} else {
|
||||||
|
// Move diagonally until either dx or dy is 0, then catch up along the
|
||||||
|
// remaining axis.
|
||||||
|
let diagonal_steps = dx.abs().min(dy.abs());
|
||||||
|
dx = (dx - dx.signum() * diagonal_steps).signum();
|
||||||
|
dy = (dy - dy.signum() * diagonal_steps).signum();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_head(self, head: (i32, i32)) -> (i32, i32) {
|
(anchor.0 - dx, anchor.1 - dy)
|
||||||
match self {
|
}
|
||||||
Self::Left => (head.0 - 1, head.1),
|
|
||||||
Self::Right => (head.0 + 1, head.1),
|
|
||||||
Self::Down => (head.0, head.1 - 1),
|
|
||||||
Self::Up => (head.0, head.1 + 1),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn move_tail(self, anchor: (i32, i32), tail: (i32, i32)) -> (i32, i32) {
|
fn simulate_rope(input: &str, segments: usize) -> usize {
|
||||||
match self {
|
let mut head = (0, 0);
|
||||||
Self::Left if tail.0 > anchor.0 + 1 => (anchor.0 + 1, anchor.1),
|
let mut tails = vec![(0, 0); segments - 1];
|
||||||
Self::Right if tail.0 < anchor.0 - 1 => (anchor.0 - 1, anchor.1),
|
let mut tail_trail = HashSet::new();
|
||||||
Self::Down if tail.1 > anchor.1 + 1 => (anchor.0, anchor.1 + 1),
|
for line in input.lines() {
|
||||||
Self::Up if tail.1 < anchor.1 - 1 => (anchor.0, anchor.1 - 1),
|
let (dir, amount) = line.split_once(' ').unwrap();
|
||||||
_ => tail,
|
let amount = amount.parse::<i32>().unwrap();
|
||||||
|
for _ in 0..amount {
|
||||||
|
head = move_head(dir, head);
|
||||||
|
let mut anchor = head;
|
||||||
|
for tail in &mut tails {
|
||||||
|
*tail = move_tail(anchor, *tail);
|
||||||
|
anchor = *tail;
|
||||||
}
|
}
|
||||||
|
tail_trail.insert(anchor);
|
||||||
}
|
}
|
||||||
|
// eprint_field(head, &tails, &tail_trail);
|
||||||
|
}
|
||||||
|
tail_trail.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn solve(input: String) {
|
pub fn solve(input: String) {
|
||||||
// +x points right, +y points up
|
println!("Part 1: {}", simulate_rope(&input, 2));
|
||||||
let mut head = (0, 0);
|
println!("Part 2: {}", simulate_rope(&input, 10));
|
||||||
let mut tail = (0, 0);
|
}
|
||||||
let mut tail_trail = HashSet::new();
|
|
||||||
|
fn eprint_field(head: (i32, i32), tails: &[(i32, i32)], trail: &HashSet<(i32, i32)>) {
|
||||||
for line in input.lines() {
|
let coords = iter::once((0, 0))
|
||||||
let (dir, amount) = line.split_once(' ').unwrap();
|
.chain(iter::once(head))
|
||||||
let dir = Direction::from_str(dir).unwrap();
|
.chain(tails.iter().cloned())
|
||||||
let amount = amount.parse::<i32>().unwrap();
|
.chain(trail.iter().cloned())
|
||||||
for _ in 0..amount {
|
.collect::<Vec<_>>();
|
||||||
head = dir.move_head(head);
|
let min_x = *coords.iter().map(|(x, _)| x).min().unwrap();
|
||||||
tail = dir.move_tail(head, tail);
|
let max_x = *coords.iter().map(|(x, _)| x).max().unwrap();
|
||||||
tail_trail.insert(tail);
|
let min_y = *coords.iter().map(|(_, y)| y).min().unwrap();
|
||||||
}
|
let max_y = *coords.iter().map(|(_, y)| y).max().unwrap();
|
||||||
}
|
let width = (max_x - min_x + 1) as usize;
|
||||||
|
let height = (max_y - min_y + 1) as usize;
|
||||||
println!("Part 1: {}", tail_trail.len());
|
let mut field = vec![vec!['.'; width]; height];
|
||||||
|
let set = |field: &mut [Vec<char>], x: i32, y: i32, c: char| {
|
||||||
|
field[(y - min_y) as usize][(x - min_x) as usize] = c;
|
||||||
|
};
|
||||||
|
for (x, y) in trail.iter() {
|
||||||
|
set(&mut field, *x, *y, '#');
|
||||||
|
}
|
||||||
|
for (i, (x, y)) in tails.iter().enumerate().rev() {
|
||||||
|
set(&mut field, *x, *y, (('1' as usize) + i) as u8 as char);
|
||||||
|
}
|
||||||
|
set(&mut field, head.0, head.1, 'H');
|
||||||
|
set(&mut field, 0, 0, 's');
|
||||||
|
for row in field.into_iter().rev() {
|
||||||
|
eprintln!(
|
||||||
|
"{}",
|
||||||
|
row.iter()
|
||||||
|
.map(|c| format!("{c}"))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
eprintln!();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
sample_inputs/2022/2022_09.01.solution
Normal file
2
sample_inputs/2022/2022_09.01.solution
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
Part 1: 13
|
||||||
|
Part 2: 1
|
||||||
8
sample_inputs/2022/2022_09.02.input
Normal file
8
sample_inputs/2022/2022_09.02.input
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
R 5
|
||||||
|
U 8
|
||||||
|
L 8
|
||||||
|
D 3
|
||||||
|
R 17
|
||||||
|
D 10
|
||||||
|
L 25
|
||||||
|
U 20
|
||||||
2
sample_inputs/2022/2022_09.02.solution
Normal file
2
sample_inputs/2022/2022_09.02.solution
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
Part 1: 88
|
||||||
|
Part 2: 36
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
Part 1: 13
|
|
||||||
Part 2: ???
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue