Skip to content

Commit 7539172

Browse files
committed
Optimize 2018 day 9 further by only computing required marbles
This gives another 55% speedup, halving runtime
1 parent a44ed5e commit 7539172

File tree

1 file changed

+60
-55
lines changed

1 file changed

+60
-55
lines changed

crates/year2018/src/day09.rs

Lines changed: 60 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ impl Day09 {
3232
let batches = marbles / 23;
3333

3434
// Each batch does 23x pop_back, 7x push_back and 37x push_front, meaning the buffer only
35-
// grows towards the front. Allocate a vec large enough to avoid needing to wrap around.
36-
let len = batches as usize * 37;
35+
// grows towards the front and the head pointer progresses far faster than the tail pointer.
36+
// The score only depends on values near the tail and within each batch is computed before
37+
// the tail is overwritten.
38+
let len = ((batches - 1) as usize * 16).next_multiple_of(37) + 22;
3739
let mut circle = vec![0u32; len];
3840

3941
// Start with the first batch completed to ensure there are enough entries to pop
@@ -54,59 +56,62 @@ impl Day09 {
5456
scores[((base + 23) % players) as usize] +=
5557
(base + 23) as u64 + circle[tail - 19] as u64;
5658

57-
let push_front = [
58-
base + 18,
59-
circle[tail - 18],
60-
base + 17,
61-
circle[tail - 17],
62-
base + 16,
63-
circle[tail - 16],
64-
base + 15,
65-
circle[tail - 15],
66-
base + 14,
67-
circle[tail - 14],
68-
base + 13,
69-
circle[tail - 13],
70-
base + 12,
71-
circle[tail - 12],
72-
base + 11,
73-
circle[tail - 11],
74-
base + 10,
75-
circle[tail - 10],
76-
base + 9,
77-
circle[tail - 9],
78-
base + 8,
79-
circle[tail - 8],
80-
base + 7,
81-
circle[tail - 7],
82-
base + 6,
83-
circle[tail - 6],
84-
base + 5,
85-
circle[tail - 5],
86-
base + 4,
87-
circle[tail - 4],
88-
base + 3,
89-
circle[tail - 3],
90-
base + 2,
91-
circle[tail - 2],
92-
base + 1,
93-
circle[tail - 1],
94-
circle[tail],
95-
];
96-
let push_back = [
97-
base + 22,
98-
circle[tail - 22],
99-
base + 21,
100-
circle[tail - 21],
101-
base + 20,
102-
circle[tail - 20],
103-
base + 19,
104-
];
105-
106-
circle[head - 37..head].copy_from_slice(&push_front);
107-
circle[tail - 22..tail - 15].copy_from_slice(&push_back);
108-
109-
head -= 37;
59+
if head > 0 {
60+
let push_front = [
61+
base + 18,
62+
circle[tail - 18],
63+
base + 17,
64+
circle[tail - 17],
65+
base + 16,
66+
circle[tail - 16],
67+
base + 15,
68+
circle[tail - 15],
69+
base + 14,
70+
circle[tail - 14],
71+
base + 13,
72+
circle[tail - 13],
73+
base + 12,
74+
circle[tail - 12],
75+
base + 11,
76+
circle[tail - 11],
77+
base + 10,
78+
circle[tail - 10],
79+
base + 9,
80+
circle[tail - 9],
81+
base + 8,
82+
circle[tail - 8],
83+
base + 7,
84+
circle[tail - 7],
85+
base + 6,
86+
circle[tail - 6],
87+
base + 5,
88+
circle[tail - 5],
89+
base + 4,
90+
circle[tail - 4],
91+
base + 3,
92+
circle[tail - 3],
93+
base + 2,
94+
circle[tail - 2],
95+
base + 1,
96+
circle[tail - 1],
97+
circle[tail],
98+
];
99+
let push_back = [
100+
base + 22,
101+
circle[tail - 22],
102+
base + 21,
103+
circle[tail - 21],
104+
base + 20,
105+
circle[tail - 20],
106+
base + 19,
107+
];
108+
109+
circle[head - 37..head].copy_from_slice(&push_front);
110+
circle[tail - 22..tail - 15].copy_from_slice(&push_back);
111+
112+
head -= 37;
113+
}
114+
110115
tail -= 16;
111116
}
112117

0 commit comments

Comments
 (0)