1
- #![ cfg_attr( feature = "const_fn" , feature( rank_lookup) ) ]
2
1
use std:: convert:: TryFrom ;
3
2
4
3
#[ cfg( feature = "rank_lookup" ) ]
@@ -84,18 +83,6 @@ pub fn rank(value: usize, k: u8) -> u128 {
84
83
// assert rank(70, 3) == 304 # 100110000
85
84
}
86
85
87
- #[ test]
88
- fn test_rank ( ) {
89
- assert_eq ! ( rank( 0 , 3 ) , 7 ) ;
90
- assert_eq ! ( rank( 2 , 3 ) , 13 ) ;
91
- assert_eq ! ( rank( 0 , 3 ) . count_ones( ) , 3 ) ;
92
- assert_eq ! ( rank( 2 , 3 ) . count_ones( ) , 3 ) ;
93
- assert_eq ! ( rank( 35001 , 4 ) . count_ones( ) , 4 ) ;
94
-
95
- // Maximum value of 64 choose 3
96
- assert_eq ! ( rank( 41663 , 3 ) . count_ones( ) , 3 ) ;
97
- }
98
-
99
86
pub fn unrank ( marker : u128 ) -> usize {
100
87
// val = choose(rank(0), 1) + choose(rank(1), 2) + choose(rank(2), 3) + ...
101
88
let mut working_marker = marker;
@@ -110,22 +97,6 @@ pub fn unrank(marker: u128) -> usize {
110
97
value as usize
111
98
}
112
99
113
- #[ test]
114
- fn test_unrank ( ) {
115
- // 3 bit markers
116
- assert_eq ! ( unrank( 7 ) , 0 ) ;
117
- assert_eq ! ( unrank( 13 ) , 2 ) ;
118
- }
119
-
120
- #[ test]
121
- fn test_rank_and_unrank ( ) {
122
- for k in 1 ..4u8 {
123
- for value in [ 1 as usize , 23 , 45 ] . iter ( ) {
124
- assert_eq ! ( unrank( rank( * value, k) ) , * value) ;
125
- }
126
- }
127
- }
128
-
129
100
/// (Hopefully) fast implementation of a binomial
130
101
///
131
102
/// This uses a preset group of equations for k < 8 and then falls back to a
@@ -170,61 +141,94 @@ pub fn choose(n: u64, k: u8) -> u64 {
170
141
}
171
142
}
172
143
173
- #[ test]
174
- fn test_choose ( ) {
175
- assert_eq ! ( choose( 1 , 1 ) , 1 ) ;
176
- assert_eq ! ( choose( 10 , 1 ) , 10 ) ;
144
+ #[ inline]
145
+ fn next_rank ( marker : u128 ) -> u128 {
146
+ let t = marker | ( marker - 1 ) ;
147
+ ( t + 1 ) | ( ( ( !t & ( t + 1 ) ) - 1 ) >> ( marker. trailing_zeros ( ) + 1 ) )
148
+ }
149
+
150
+ #[ cfg( test) ]
151
+ mod tests {
152
+ use super :: * ;
153
+
154
+ #[ test]
155
+ fn test_rank ( ) {
156
+ assert_eq ! ( rank( 0 , 3 ) , 7 ) ;
157
+ assert_eq ! ( rank( 2 , 3 ) , 13 ) ;
158
+ assert_eq ! ( rank( 0 , 3 ) . count_ones( ) , 3 ) ;
159
+ assert_eq ! ( rank( 2 , 3 ) . count_ones( ) , 3 ) ;
160
+ assert_eq ! ( rank( 35001 , 4 ) . count_ones( ) , 4 ) ;
161
+
162
+ // Maximum value of 64 choose 3
163
+ assert_eq ! ( rank( 41663 , 3 ) . count_ones( ) , 3 ) ;
164
+ }
177
165
178
- assert_eq ! ( choose( 5 , 2 ) , 10 ) ;
166
+ #[ test]
167
+ fn test_unrank ( ) {
168
+ // 3 bit markers
169
+ assert_eq ! ( unrank( 7 ) , 0 ) ;
170
+ assert_eq ! ( unrank( 13 ) , 2 ) ;
171
+ }
179
172
180
- assert_eq ! ( choose( 5 , 3 ) , 10 ) ;
173
+ #[ test]
174
+ fn test_rank_and_unrank ( ) {
175
+ for k in 1 ..4u8 {
176
+ for value in [ 1 as usize , 23 , 45 ] . iter ( ) {
177
+ assert_eq ! ( unrank( rank( * value, k) ) , * value) ;
178
+ }
179
+ }
180
+ }
181
181
182
- assert_eq ! ( choose( 5 , 4 ) , 5 ) ;
182
+ #[ test]
183
+ fn test_choose ( ) {
184
+ assert_eq ! ( choose( 1 , 1 ) , 1 ) ;
185
+ assert_eq ! ( choose( 10 , 1 ) , 10 ) ;
183
186
184
- assert_eq ! ( choose( 5 , 5 ) , 1 ) ;
185
- assert_eq ! ( choose( 20 , 5 ) , 15504 ) ;
187
+ assert_eq ! ( choose( 5 , 2 ) , 10 ) ;
186
188
187
- assert_eq ! ( choose( 20 , 6 ) , 38760 ) ;
189
+ assert_eq ! ( choose( 5 , 3 ) , 10 ) ;
188
190
189
- assert_eq ! ( choose( 20 , 7 ) , 77520 ) ;
190
- assert_eq ! ( choose( 23 , 7 ) , 245157 ) ;
191
+ assert_eq ! ( choose( 5 , 4 ) , 5 ) ;
191
192
192
- // test the last branch
193
- assert_eq ! ( choose( 8 , 8 ) , 1 ) ;
194
- assert_eq ! ( choose( 9 , 8 ) , 9 ) ;
193
+ assert_eq ! ( choose( 5 , 5 ) , 1 ) ;
194
+ assert_eq ! ( choose( 20 , 5 ) , 15504 ) ;
195
195
196
- // every value of 64 choose n should work
197
- assert_eq ! ( choose( 64 , 0 ) , 1 ) ;
198
- assert_eq ! ( choose( 64 , 1 ) , 64 ) ;
199
- assert_eq ! ( choose( 64 , 16 ) , 488526937079580 ) ;
200
- assert_eq ! ( choose( 64 , 32 ) , 1832624140942590534 ) ;
201
- assert_eq ! ( choose( 64 , 48 ) , 488526937079580 ) ;
202
- assert_eq ! ( choose( 64 , 63 ) , 64 ) ;
203
- assert_eq ! ( choose( 64 , 64 ) , 1 ) ;
196
+ assert_eq ! ( choose( 20 , 6 ) , 38760 ) ;
204
197
205
- // super high values can overflow; these are approaching the limit
206
- assert_eq ! ( choose( 128 , 11 ) , 2433440563030400 ) ;
207
- assert_eq ! ( choose( 128 , 13 ) , 211709328983644800 ) ;
208
- assert_eq ! ( choose( 256 , 9 ) , 11288510714272000 ) ;
209
- }
198
+ assert_eq ! ( choose( 20 , 7 ) , 77520 ) ;
199
+ assert_eq ! ( choose( 23 , 7 ) , 245157 ) ;
210
200
211
- #[ test]
212
- #[ should_panic( expected = "256 choose 20 is greater than 2**64" ) ]
213
- fn test_choose_overflow ( ) {
214
- assert_eq ! ( choose( 256 , 20 ) , 11288510714272000 ) ;
215
- }
201
+ // test the last branch
202
+ assert_eq ! ( choose( 8 , 8 ) , 1 ) ;
203
+ assert_eq ! ( choose( 9 , 8 ) , 9 ) ;
216
204
217
- #[ inline]
218
- fn next_rank ( marker : u128 ) -> u128 {
219
- let t = marker | ( marker - 1 ) ;
220
- ( t + 1 ) | ( ( ( !t & ( t + 1 ) ) - 1 ) >> ( marker. trailing_zeros ( ) + 1 ) )
221
- }
205
+ // every value of 64 choose n should work
206
+ assert_eq ! ( choose( 64 , 0 ) , 1 ) ;
207
+ assert_eq ! ( choose( 64 , 1 ) , 64 ) ;
208
+ assert_eq ! ( choose( 64 , 16 ) , 488526937079580 ) ;
209
+ assert_eq ! ( choose( 64 , 32 ) , 1832624140942590534 ) ;
210
+ assert_eq ! ( choose( 64 , 48 ) , 488526937079580 ) ;
211
+ assert_eq ! ( choose( 64 , 63 ) , 64 ) ;
212
+ assert_eq ! ( choose( 64 , 64 ) , 1 ) ;
213
+
214
+ // super high values can overflow; these are approaching the limit
215
+ assert_eq ! ( choose( 128 , 11 ) , 2433440563030400 ) ;
216
+ assert_eq ! ( choose( 128 , 13 ) , 211709328983644800 ) ;
217
+ assert_eq ! ( choose( 256 , 9 ) , 11288510714272000 ) ;
218
+ }
219
+
220
+ #[ test]
221
+ #[ should_panic( expected = "256 choose 20 is greater than 2**64" ) ]
222
+ fn test_choose_overflow ( ) {
223
+ assert_eq ! ( choose( 256 , 20 ) , 11288510714272000 ) ;
224
+ }
222
225
223
- #[ test]
224
- fn test_next_rank ( ) {
225
- assert_eq ! ( next_rank( 0b1 ) , 0b10 ) ;
226
- assert_eq ! ( next_rank( 0b100 ) , 0b1000 ) ;
226
+ #[ test]
227
+ fn test_next_rank ( ) {
228
+ assert_eq ! ( next_rank( 0b1 ) , 0b10 ) ;
229
+ assert_eq ! ( next_rank( 0b100 ) , 0b1000 ) ;
227
230
228
- assert_eq ! ( next_rank( 0b111 ) , 0b1011 ) ;
229
- assert_eq ! ( next_rank( 0b1000101 ) , 0b1000110 ) ;
231
+ assert_eq ! ( next_rank( 0b111 ) , 0b1011 ) ;
232
+ assert_eq ! ( next_rank( 0b1000101 ) , 0b1000110 ) ;
233
+ }
230
234
}
0 commit comments