From af2d2469fa2781b981f80820c49421963bc15d0a Mon Sep 17 00:00:00 2001 From: Alpha Chen Date: Sun, 9 Dec 2018 15:47:18 -0800 Subject: [PATCH] [2018][rust][09] --- 2018/rust/src/bin/day_09.rs | 90 +++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 2018/rust/src/bin/day_09.rs diff --git a/2018/rust/src/bin/day_09.rs b/2018/rust/src/bin/day_09.rs new file mode 100644 index 0000000..c41514e --- /dev/null +++ b/2018/rust/src/bin/day_09.rs @@ -0,0 +1,90 @@ +use std::error::Error; + +use regex::Regex; + +use advent_of_code::main; + +main!(); + +fn solve(input: &str) -> Result> { + let re = Regex::new(r"(?P\d+) players; last marble is worth (?P\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) -> 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, +}