1313//!
1414//! Additionally we store the Trie in a flat `vec`. This is simpler and faster than creating
1515//! objects on the heap using [`Box`].
16- type Input = ( u64 , u64 ) ;
16+ type Input = ( usize , usize ) ;
1717
1818pub fn parse ( input : & str ) -> Input {
1919 let ( prefix, suffix) = input. split_once ( "\n \n " ) . unwrap ( ) ;
@@ -37,7 +37,7 @@ pub fn parse(input: &str) -> Input {
3737 }
3838 }
3939
40- trie[ i] . towel = true ;
40+ trie[ i] . set_towel ( ) ;
4141 }
4242
4343 let mut part_one = 0 ;
@@ -70,44 +70,51 @@ pub fn parse(input: &str) -> Input {
7070 }
7171
7272 // 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] ;
7674 }
7775 }
7876 }
7977
8078 // Last element is the total possible combinations.
8179 let total = ways[ size] ;
82- part_one += ( total > 0 ) as u64 ;
80+ part_one += ( total > 0 ) as usize ;
8381 part_two += total;
8482 }
8583
8684 ( part_one, part_two)
8785}
8886
89- pub fn part1 ( input : & Input ) -> u64 {
87+ pub fn part1 ( input : & Input ) -> usize {
9088 input. 0
9189}
9290
93- pub fn part2 ( input : & Input ) -> u64 {
91+ pub fn part2 ( input : & Input ) -> usize {
9492 input. 1
9593}
9694
9795/// 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.
9997fn 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
101100}
102101
103102/// Simple Node object that uses indices to link to other nodes.
104103struct Node {
105- towel : bool ,
106- next : [ usize ; 7 ] ,
104+ next : [ usize ; 6 ] ,
107105}
108106
109107impl Node {
110108 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 ]
112119 }
113120}
0 commit comments