File tree Expand file tree Collapse file tree 2 files changed +56
-0
lines changed Expand file tree Collapse file tree 2 files changed +56
-0
lines changed Original file line number Diff line number Diff line change 1+ use utils:: prelude:: * ;
2+
3+ /// Simulating a circular buffer.
4+ #[ derive( Clone , Debug ) ]
5+ pub struct Day17 {
6+ step_size : u32 ,
7+ }
8+
9+ impl Day17 {
10+ pub fn new ( input : & str , _: InputType ) -> Result < Self , InputError > {
11+ Ok ( Self {
12+ step_size : parser:: u32 ( ) . parse_complete ( input) ?,
13+ } )
14+ }
15+
16+ #[ must_use]
17+ pub fn part1 ( & self ) -> u32 {
18+ let mut buffer = Vec :: with_capacity ( 2018 ) ;
19+ buffer. push ( 0 ) ;
20+
21+ let mut i = 0 ;
22+ for iteration in 1 ..=2017u16 {
23+ i = ( i + self . step_size as usize ) % buffer. len ( ) ;
24+ buffer. insert ( i + 1 , iteration) ;
25+ i += 1 ;
26+ }
27+
28+ buffer[ ( i + 1 ) % buffer. len ( ) ] as u32
29+ }
30+
31+ #[ must_use]
32+ pub fn part2 ( & self ) -> u32 {
33+ let mut result = 0u32 ;
34+
35+ // 0 is always at the start of the buffer, so the answer is the last value in position 1,
36+ // which is the last value inserted when the spinlock is at 0.
37+ let ( mut i, mut iteration) = ( 0 , 1 ) ;
38+ while iteration <= 50_000_000 {
39+ if i == 0 {
40+ result = iteration;
41+ }
42+
43+ // Skip iterations until the spinlock wraps around to the start of the buffer again
44+ let skip_iterations = ( iteration - i) . div_ceil ( self . step_size + 1 ) ;
45+ iteration += skip_iterations;
46+ i = ( i + skip_iterations * ( self . step_size + 1 ) ) % iteration;
47+ }
48+
49+ result
50+ }
51+ }
52+
53+ examples ! ( Day17 -> ( u32 , u32 ) [
54+ { input: "3" , part1: 638 } ,
55+ ] ) ;
Original file line number Diff line number Diff line change @@ -20,4 +20,5 @@ utils::year!(2017 => year2017, ${
2020 14 => day14:: Day14 ,
2121 15 => day15:: Day15 ,
2222 16 => day16:: Day16 ,
23+ 17 => day17:: Day17 ,
2324} ) ;
You can’t perform that action at this time.
0 commit comments