mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-26 21:30:31 +01:00
Implement day 9 part 2.
Linked lists in rust are a pain, but we got there.
This commit is contained in:
@@ -9,3 +9,4 @@ clap = "2.32"
|
|||||||
regex = "1.1.0"
|
regex = "1.1.0"
|
||||||
chrono = "0.4.6"
|
chrono = "0.4.6"
|
||||||
itertools = "0.7.11"
|
itertools = "0.7.11"
|
||||||
|
intrusive-collections = "0.7.8"
|
||||||
|
|||||||
@@ -1,30 +1,53 @@
|
|||||||
use common::Solution;
|
use std::cell::Cell;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
|
use intrusive_collections::{LinkedList, LinkedListLink};
|
||||||
|
|
||||||
|
use common::Solution;
|
||||||
|
|
||||||
|
struct Marble {
|
||||||
|
link: LinkedListLink,
|
||||||
|
value: Cell<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Marble {
|
||||||
|
pub fn new(value: usize) -> Box<Self> {
|
||||||
|
Box::new(Marble {
|
||||||
|
link: LinkedListLink::new(),
|
||||||
|
value: Cell::new(value),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
intrusive_adapter!(MarbleAdapter = Box<Marble>: Marble { link: LinkedListLink });
|
||||||
|
|
||||||
fn winning_marbles(elves: usize, marbles: usize) -> usize {
|
fn winning_marbles(elves: usize, marbles: usize) -> usize {
|
||||||
let mut scores = vec![0usize; elves];
|
let mut scores = vec![0usize; elves];
|
||||||
let mut state = Vec::new();
|
let mut state: LinkedList<_> = LinkedList::new(MarbleAdapter::new());
|
||||||
state.push(0);
|
state.push_front(Marble::new(0));
|
||||||
let mut current = 0;
|
let mut current = state.front_mut();
|
||||||
|
|
||||||
for marble in 1..=marbles {
|
for marble in 1..=marbles {
|
||||||
if marble % 23 == 0 {
|
if marble % 23 == 0 {
|
||||||
let player = marble % elves;
|
let player = marble % elves;
|
||||||
for _ in 0..7 {}
|
for _ in 0..7 {
|
||||||
let to_remove = (current + state.len() - 7) % state.len();
|
current.move_prev();
|
||||||
|
if current.is_null() {
|
||||||
scores[player] += marble + state[to_remove];
|
current.move_prev();
|
||||||
|
}
|
||||||
state.remove(to_remove);
|
|
||||||
current = to_remove;
|
|
||||||
} else {
|
|
||||||
let after = (current + 1) % state.len();
|
|
||||||
if after == state.len() - 1 {
|
|
||||||
state.push(marble);
|
|
||||||
} else {
|
|
||||||
state.insert(after + 1, marble);
|
|
||||||
}
|
}
|
||||||
current = after + 1;
|
|
||||||
|
let to_remove = current.get().unwrap().value.get();
|
||||||
|
|
||||||
|
scores[player] += marble + to_remove;
|
||||||
|
current.remove();
|
||||||
|
} else {
|
||||||
|
current.move_next();
|
||||||
|
if current.is_null() {
|
||||||
|
current.move_next();
|
||||||
|
}
|
||||||
|
current.insert_after(Marble::new(marble));
|
||||||
|
current.move_next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
|
#[macro_use] extern crate intrusive_collections;
|
||||||
#[macro_use] extern crate itertools;
|
#[macro_use] extern crate itertools;
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user