2022 Day 9
This commit is contained in:
parent
8642d4f4c4
commit
5b09988025
3 changed files with 235 additions and 0 deletions
56
2022/Cargo.lock
generated
56
2022/Cargo.lock
generated
|
|
@ -25,6 +25,7 @@ dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
"path-absolutize",
|
"path-absolutize",
|
||||||
"regex",
|
"regex",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -72,6 +73,24 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.47"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.7.0"
|
version = "1.7.0"
|
||||||
|
|
@ -88,3 +107,40 @@ name = "regex-syntax"
|
||||||
version = "0.6.28"
|
version = "0.6.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.149"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.149"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.105"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
||||||
|
|
|
||||||
|
|
@ -8,3 +8,4 @@ anyhow = "1.0.66"
|
||||||
itertools = "0.10.5"
|
itertools = "0.10.5"
|
||||||
path-absolutize = "3.0.14"
|
path-absolutize = "3.0.14"
|
||||||
regex = "1.7.0"
|
regex = "1.7.0"
|
||||||
|
serde = { version = "1.0.149", features = ["derive"] }
|
||||||
|
|
|
||||||
178
2022/src/bin/day09.rs
Normal file
178
2022/src/bin/day09.rs
Normal file
|
|
@ -0,0 +1,178 @@
|
||||||
|
use std::{collections::HashSet, str::FromStr};
|
||||||
|
|
||||||
|
use serde::{
|
||||||
|
de::{value, IntoDeserializer},
|
||||||
|
Deserialize,
|
||||||
|
};
|
||||||
|
|
||||||
|
const INPUT: &str = include_str!("../../input/day09.txt");
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("{}", part1(INPUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(input: &str) -> usize {
|
||||||
|
let steps = parse_input(input);
|
||||||
|
|
||||||
|
let num_knots = 10;
|
||||||
|
let tail = num_knots - 1;
|
||||||
|
|
||||||
|
let mut knots = vec![RC::new(0, 0); num_knots];
|
||||||
|
|
||||||
|
let mut tail_visited: HashSet<RC> = HashSet::new();
|
||||||
|
tail_visited.insert(knots[tail]);
|
||||||
|
|
||||||
|
// render(&knots, &tail_visited);
|
||||||
|
for step in steps {
|
||||||
|
println!("> {:?}, {}", step.d, step.n);
|
||||||
|
|
||||||
|
for _ in 0..(step.n) {
|
||||||
|
knots[0] = knots[0].mv(step.d.delta());
|
||||||
|
for i in 1..(knots.len()) {
|
||||||
|
knots[i] = knots[i].follow(knots[i - 1]);
|
||||||
|
}
|
||||||
|
// dbg!(head);
|
||||||
|
// dbg!(tail);
|
||||||
|
|
||||||
|
tail_visited.insert(knots[tail]);
|
||||||
|
|
||||||
|
// render(&knots, &tail_visited);
|
||||||
|
}
|
||||||
|
|
||||||
|
// render(&knots, &tail_visited);
|
||||||
|
// std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
|
}
|
||||||
|
|
||||||
|
render(&knots, &tail_visited);
|
||||||
|
tail_visited.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input(input: &str) -> Vec<Step> {
|
||||||
|
aoc::split_lines(input)
|
||||||
|
.iter()
|
||||||
|
.map(|line| {
|
||||||
|
let words = aoc::split_words(line);
|
||||||
|
|
||||||
|
let d = Direction::from_str(words[0]).unwrap();
|
||||||
|
let n = words[1].parse::<i64>().unwrap();
|
||||||
|
|
||||||
|
Step { d, n }
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
struct Step {
|
||||||
|
d: Direction,
|
||||||
|
n: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
struct RC {
|
||||||
|
r: i64,
|
||||||
|
c: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RC {
|
||||||
|
fn new(r: i64, c: i64) -> Self {
|
||||||
|
Self { r, c }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn origin() -> Self {
|
||||||
|
Self::new(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mv(&self, delta: RC) -> RC {
|
||||||
|
RC {
|
||||||
|
r: self.r + delta.r,
|
||||||
|
c: self.c + delta.c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn follow(&self, head: RC) -> RC {
|
||||||
|
// dbg!(head.r);
|
||||||
|
// dbg!(head.c);
|
||||||
|
// dbg!(self.r);
|
||||||
|
// dbg!(self.c);
|
||||||
|
|
||||||
|
let dr = head.r - self.r;
|
||||||
|
let dc = head.c - self.c;
|
||||||
|
|
||||||
|
// dbg!(dr);
|
||||||
|
// dbg!(dc);
|
||||||
|
|
||||||
|
// Adjacent
|
||||||
|
if dr.abs() < 2 && dc.abs() < 2 {
|
||||||
|
// dbg!("OK");
|
||||||
|
return *self;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dbg!(sign(dr));
|
||||||
|
// dbg!(sign(dc));
|
||||||
|
|
||||||
|
RC::new(self.r + sign(dr), self.c + sign(dc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Deserialize)]
|
||||||
|
enum Direction {
|
||||||
|
U,
|
||||||
|
D,
|
||||||
|
L,
|
||||||
|
R,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Direction {
|
||||||
|
fn delta(&self) -> RC {
|
||||||
|
use Direction::*;
|
||||||
|
match self {
|
||||||
|
U => RC::new(1, 0),
|
||||||
|
D => RC::new(-1, 0),
|
||||||
|
L => RC::new(0, -1),
|
||||||
|
R => RC::new(0, 1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Direction {
|
||||||
|
type Err = value::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
Self::deserialize(s.into_deserializer())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(knots: &[RC], tail_visited: &HashSet<RC>) {
|
||||||
|
let rcs = knots.iter().chain(tail_visited.iter());
|
||||||
|
let (lo, hi) = rcs.fold((RC::origin(), RC::origin()), |(lo, hi), RC { r, c }| {
|
||||||
|
(
|
||||||
|
RC::new(lo.r.min(*r), lo.c.min(*c)),
|
||||||
|
RC::new(hi.r.max(*r), hi.c.max(*c)),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
let chr = move |r: i64, c: i64| -> char {
|
||||||
|
for (i, rc) in knots.iter().enumerate() {
|
||||||
|
if (r, c) == (rc.r, rc.c) {
|
||||||
|
return char::from_digit(i as u32, 10).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tail_visited.contains(&RC::new(r, c)) {
|
||||||
|
'#'
|
||||||
|
} else {
|
||||||
|
'.'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for r in (lo.r..=hi.r).rev() {
|
||||||
|
for c in lo.c..=hi.c {
|
||||||
|
print!("{}", chr(r, c));
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sign(n: i64) -> i64 {
|
||||||
|
n.cmp(&0) as i64
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue