Day 20, part 1
This commit is contained in:
parent
f825de9426
commit
63fecbd235
9
src/bin/d20p1.rs
Normal file
9
src/bin/d20p1.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
use aoc22::{day20, util};
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let nodes = day20::parse_file(&util::parse_input());
|
||||||
|
|
||||||
|
day20::mix(&nodes);
|
||||||
|
|
||||||
|
println!("Sum of coordinates: {}", day20::calc_coordinates(&nodes));
|
||||||
|
}
|
118
src/day20.rs
Normal file
118
src/day20.rs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
use std::{cell::RefCell, fmt::Debug, ops::Deref, rc::Rc};
|
||||||
|
|
||||||
|
pub struct Node {
|
||||||
|
pub val: isize,
|
||||||
|
pub next: Option<Rc<RefCell<Node>>>,
|
||||||
|
pub prev: Option<Rc<RefCell<Node>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default Debug implementation will loop indefinitely, since we have a ring buffer
|
||||||
|
impl Debug for Node {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Node")
|
||||||
|
.field("val", &self.val)
|
||||||
|
.field("next", &self.next.as_ref().map(|n| n.borrow().val))
|
||||||
|
.field("prev", &self.prev.as_ref().map(|n| n.borrow().val))
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_next(node: &Rc<RefCell<Node>>, n: usize) -> Rc<RefCell<Node>> {
|
||||||
|
let mut curr = node.clone();
|
||||||
|
for _ in 0..n {
|
||||||
|
let next = curr.borrow().next.as_ref().unwrap().clone();
|
||||||
|
curr = next;
|
||||||
|
}
|
||||||
|
curr
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_prev(node: &Rc<RefCell<Node>>, n: usize) -> Rc<RefCell<Node>> {
|
||||||
|
let mut curr = node.clone();
|
||||||
|
for _ in 0..n {
|
||||||
|
let prev = curr.borrow().prev.as_ref().unwrap().clone();
|
||||||
|
curr = prev;
|
||||||
|
}
|
||||||
|
curr
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_file(input: &String) -> Vec<Rc<RefCell<Node>>> {
|
||||||
|
let mut result = Vec::new();
|
||||||
|
|
||||||
|
let mut last = None;
|
||||||
|
for line in input.lines() {
|
||||||
|
let val: isize = line.parse().unwrap();
|
||||||
|
let node = Rc::new(RefCell::new(Node {
|
||||||
|
val,
|
||||||
|
next: None,
|
||||||
|
prev: last.clone(),
|
||||||
|
}));
|
||||||
|
if let Some(l) = last {
|
||||||
|
l.as_ref().borrow_mut().next = Some(node.clone());
|
||||||
|
}
|
||||||
|
result.push(node.clone());
|
||||||
|
last = Some(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(result.len() > 0);
|
||||||
|
|
||||||
|
let last_refcell = last.as_ref().unwrap().deref();
|
||||||
|
last_refcell.borrow_mut().next = Some(result[0].clone());
|
||||||
|
let first_refcell = &*result[0];
|
||||||
|
first_refcell.borrow_mut().prev = Some(last.as_ref().unwrap().clone());
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mix(nodes: &Vec<Rc<RefCell<Node>>>) {
|
||||||
|
for node in nodes {
|
||||||
|
let n = node.borrow().val;
|
||||||
|
if n == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove from current position
|
||||||
|
let prev = get_prev(node, 1);
|
||||||
|
let next = get_next(node, 1);
|
||||||
|
prev.borrow_mut().next = Some(next.clone());
|
||||||
|
next.borrow_mut().prev = Some(prev.clone());
|
||||||
|
|
||||||
|
let prev = if n > 0 {
|
||||||
|
get_next(node, n as usize)
|
||||||
|
} else {
|
||||||
|
get_prev(node, (-n as usize) + 1)
|
||||||
|
};
|
||||||
|
let next = get_next(&prev, 1);
|
||||||
|
prev.deref().borrow_mut().next = Some(node.clone());
|
||||||
|
next.deref().borrow_mut().prev = Some(node.clone());
|
||||||
|
|
||||||
|
let mut n_mut = node.deref().borrow_mut();
|
||||||
|
n_mut.prev = Some(prev.clone());
|
||||||
|
n_mut.next = Some(next.clone());
|
||||||
|
drop(n_mut);
|
||||||
|
|
||||||
|
// print_nodes(&nodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_nodes(nodes: &Vec<Rc<RefCell<Node>>>) {
|
||||||
|
let mut curr = nodes.iter().find(|n| n.borrow().val == 0).unwrap().clone();
|
||||||
|
loop {
|
||||||
|
print!("{}, ", curr.borrow().val);
|
||||||
|
|
||||||
|
let next = curr.borrow().next.as_ref().unwrap().clone();
|
||||||
|
curr = next;
|
||||||
|
if curr.borrow().val == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print!("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn calc_coordinates(nodes: &Vec<Rc<RefCell<Node>>>) -> isize {
|
||||||
|
let zero = nodes.iter().find(|n| n.borrow().val == 0).unwrap();
|
||||||
|
let first = get_next(zero, 1000).borrow().val;
|
||||||
|
let second = get_next(zero, 2000).borrow().val;
|
||||||
|
let third = get_next(zero, 3000).borrow().val;
|
||||||
|
|
||||||
|
first + second + third
|
||||||
|
}
|
@ -10,6 +10,7 @@ pub mod day17;
|
|||||||
pub mod day18;
|
pub mod day18;
|
||||||
pub mod day19;
|
pub mod day19;
|
||||||
pub mod day2;
|
pub mod day2;
|
||||||
|
pub mod day20;
|
||||||
pub mod day3;
|
pub mod day3;
|
||||||
pub mod day4;
|
pub mod day4;
|
||||||
pub mod day5;
|
pub mod day5;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user