Implement day 9 part 2.

Linked lists in rust are a pain, but we got there.
This commit is contained in:
2018-12-09 10:57:47 +01:00
parent e101dbd58c
commit 9b04e3b2c9
3 changed files with 43 additions and 18 deletions

View File

@@ -9,3 +9,4 @@ clap = "2.32"
regex = "1.1.0"
chrono = "0.4.6"
itertools = "0.7.11"
intrusive-collections = "0.7.8"

View File

@@ -1,30 +1,53 @@
use common::Solution;
use std::cell::Cell;
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 {
let mut scores = vec![0usize; elves];
let mut state = Vec::new();
state.push(0);
let mut current = 0;
let mut state: LinkedList<_> = LinkedList::new(MarbleAdapter::new());
state.push_front(Marble::new(0));
let mut current = state.front_mut();
for marble in 1..=marbles {
if marble % 23 == 0 {
let player = marble % elves;
for _ in 0..7 {}
let to_remove = (current + state.len() - 7) % state.len();
scores[player] += marble + state[to_remove];
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);
for _ in 0..7 {
current.move_prev();
if current.is_null() {
current.move_prev();
}
}
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();
}
}

View File

@@ -1,4 +1,5 @@
extern crate chrono;
#[macro_use] extern crate intrusive_collections;
#[macro_use] extern crate itertools;
extern crate regex;