13
13
//!
14
14
//! Additionally we store the Trie in a flat `vec`. This is simpler and faster than creating
15
15
//! objects on the heap using [`Box`].
16
- type Input = ( u64 , u64 ) ;
16
+ type Input = ( usize , usize ) ;
17
17
18
18
pub fn parse ( input : & str ) -> Input {
19
19
let ( prefix, suffix) = input. split_once ( "\n \n " ) . unwrap ( ) ;
@@ -37,7 +37,7 @@ pub fn parse(input: &str) -> Input {
37
37
}
38
38
}
39
39
40
- trie[ i] . towel = true ;
40
+ trie[ i] . set_towel ( ) ;
41
41
}
42
42
43
43
let mut part_one = 0 ;
@@ -70,44 +70,51 @@ pub fn parse(input: &str) -> Input {
70
70
}
71
71
72
72
// Add the number of possible ways this prefix can be reached.
73
- if trie[ i] . towel {
74
- ways[ end + 1 ] += ways[ start] ;
75
- }
73
+ ways[ end + 1 ] += trie[ i] . towels ( ) * ways[ start] ;
76
74
}
77
75
}
78
76
}
79
77
80
78
// Last element is the total possible combinations.
81
79
let total = ways[ size] ;
82
- part_one += ( total > 0 ) as u64 ;
80
+ part_one += ( total > 0 ) as usize ;
83
81
part_two += total;
84
82
}
85
83
86
84
( part_one, part_two)
87
85
}
88
86
89
- pub fn part1 ( input : & Input ) -> u64 {
87
+ pub fn part1 ( input : & Input ) -> usize {
90
88
input. 0
91
89
}
92
90
93
- pub fn part2 ( input : & Input ) -> u64 {
91
+ pub fn part2 ( input : & Input ) -> usize {
94
92
input. 1
95
93
}
96
94
97
95
/// Hashes the five possible color values white (w), blue (u), black (b), red (r), or green (g)
98
- /// to 6, 4, 0, 1 and 5 respectively. This compresses the range to fit into an array of 7 elements.
96
+ /// to 0, 2, 4, 5 and 1 respectively. This compresses the range to fit into an array of 6 elements.
99
97
fn perfect_hash ( b : u8 ) -> usize {
100
- ( b as usize + ( b as usize >> 4 ) ) % 8
98
+ let n = b as usize ;
99
+ ( n ^ ( n >> 4 ) ) % 8
101
100
}
102
101
103
102
/// Simple Node object that uses indices to link to other nodes.
104
103
struct Node {
105
- towel : bool ,
106
- next : [ usize ; 7 ] ,
104
+ next : [ usize ; 6 ] ,
107
105
}
108
106
109
107
impl Node {
110
108
fn new ( ) -> Self {
111
- Node { towel : false , next : [ 0 ; 7 ] }
109
+ Node { next : [ 0 ; 6 ] }
110
+ }
111
+
112
+ // Index 3 is not used by the hash, so we cheekily repurpose for the number of towels.
113
+ fn set_towel ( & mut self ) {
114
+ self . next [ 3 ] = 1 ;
115
+ }
116
+
117
+ fn towels ( & self ) -> usize {
118
+ self . next [ 3 ]
112
119
}
113
120
}
0 commit comments