parent
337fa5835b
commit
af2d2469fa
@ -0,0 +1,90 @@
|
|||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
use advent_of_code::main;
|
||||||
|
|
||||||
|
main!();
|
||||||
|
|
||||||
|
fn solve(input: &str) -> Result<String, Box<Error>> {
|
||||||
|
let re = Regex::new(r"(?P<players>\d+) players; last marble is worth (?P<points>\d+) points").unwrap();
|
||||||
|
let caps = re.captures(input).unwrap();
|
||||||
|
let player_count = caps.name("players").unwrap().as_str().parse()?;
|
||||||
|
let marble_count: usize = caps.name("points").unwrap().as_str().parse()?;
|
||||||
|
let high_score = play(player_count, marble_count * 100);
|
||||||
|
Ok(high_score.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn play(player_count: usize, marble_count: usize) -> usize {
|
||||||
|
let mut scores = vec![0; player_count];
|
||||||
|
let mut circle = vec![Marble{value: 0, next: 0, prev: 0}];
|
||||||
|
|
||||||
|
let mut current_player = 0;
|
||||||
|
let mut current_index: usize = 0;
|
||||||
|
|
||||||
|
for value in 1..=marble_count {
|
||||||
|
if value % 23 == 0 {
|
||||||
|
scores[current_player] += value;
|
||||||
|
for _ in 0..7 {
|
||||||
|
current_index = circle[current_index].prev;
|
||||||
|
}
|
||||||
|
let marble = &circle[current_index];
|
||||||
|
scores[current_player] += marble.value;
|
||||||
|
let prev = marble.prev;
|
||||||
|
let next = marble.next;
|
||||||
|
circle[prev].next = next;
|
||||||
|
circle[next].prev = prev;
|
||||||
|
current_index = next;
|
||||||
|
} else {
|
||||||
|
current_index = circle[current_index].next;
|
||||||
|
let current_marble = &circle[current_index];
|
||||||
|
let next = current_marble.next;
|
||||||
|
let prev = current_index;
|
||||||
|
let marble = Marble{value, next, prev};
|
||||||
|
circle.push(marble);
|
||||||
|
current_index = circle.len() - 1;
|
||||||
|
circle[prev].next = current_index;
|
||||||
|
circle[next].prev = current_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if current_index % 100000 == 0 {
|
||||||
|
// println!("{}", current_index);
|
||||||
|
// }
|
||||||
|
// println!("[{}] {:?}", current_player + 1, circle_to_string(&circle));
|
||||||
|
|
||||||
|
current_player += 1;
|
||||||
|
current_player %= player_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
*scores.iter().max().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_play() {
|
||||||
|
assert_eq!(play(9, 25), 32);
|
||||||
|
// assert_eq!(play(10, 1618), 8317);
|
||||||
|
assert_eq!(play(13, 7999), 146373);
|
||||||
|
// assert_eq!(play(17, 1104), 2764);
|
||||||
|
// assert_eq!(play(21, 6111), 54718);
|
||||||
|
// assert_eq!(play(30, 5807), 37305);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn circle_to_string(circle: &Vec<Marble>) -> String {
|
||||||
|
// let mut i = 0;
|
||||||
|
// let mut v = Vec::new();
|
||||||
|
// loop {
|
||||||
|
// v.push(circle[i].value);
|
||||||
|
// i = circle[i].next;
|
||||||
|
// if i == 0 {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// format!("{:?}", v)
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Marble {
|
||||||
|
value: usize,
|
||||||
|
next: usize,
|
||||||
|
prev: usize,
|
||||||
|
}
|
Loading…
Reference in new issue