-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday_09.rs
83 lines (74 loc) · 2.29 KB
/
day_09.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! https://adventofcode.com/2018/day/9
//! https://adventofcode.com/2018/day/9/input
use std::{fs::read_to_string, time::Instant};
fn parse(input: &str) -> (usize, usize) {
let mut parts = input.split_whitespace();
(
parts.next().unwrap().parse().unwrap(),
parts.nth(5).unwrap().parse().unwrap(),
)
}
#[derive(Copy, Clone, Default)]
struct Marble {
prev: usize,
next: usize,
}
fn play(players: usize, marbles: usize) -> usize {
let mut points = vec![0; players];
let mut nodes = vec![Marble { prev: 0, next: 0 }; marbles + 1];
let mut current = 0;
let mut player = 0;
for marble in 1..=marbles {
if marble % 23 != 0 {
let left = nodes[current].next;
let right = nodes[left].next;
nodes[left].next = marble;
nodes[right].prev = marble;
nodes[marble].prev = left;
nodes[marble].next = right;
current = marble;
} else {
points[player] += marble;
let mut to_remove = current;
for _ in 0..7 {
to_remove = nodes[to_remove].prev;
}
let left = nodes[to_remove].prev;
let right = nodes[to_remove].next;
nodes[left].next = right;
nodes[right].prev = left;
points[player] += to_remove;
current = right;
}
player = (player + 1) % players;
}
*points.iter().max().unwrap()
}
pub mod part1 {
use super::{parse, play};
pub fn solve(input: &str) -> usize {
let (players, marbles) = parse(input);
play(players, marbles)
}
}
pub mod part2 {
use super::{parse, play};
pub fn solve(input: &str) -> usize {
let (players, marbles) = parse(input);
play(players, marbles * 100)
}
}
pub fn main(test: bool) {
let test_input = "10 players; last marble is worth 1618 points".to_owned();
let puzzle_input = if test {
test_input
} else {
read_to_string("../inputs/2018/day_09_input.txt").unwrap()
};
let start = Instant::now();
println!("{}", part1::solve(&puzzle_input));
println!("Run in {:?}", start.elapsed());
let start = Instant::now();
println!("{}", part2::solve(&puzzle_input));
println!("Run in {:?}", start.elapsed());
}