@@ -343,6 +343,25 @@ impl StakingQuerier {
343
343
}
344
344
}
345
345
346
+ /// Performs a perfect shuffle (in shuffle)
347
+ ///
348
+ /// https://en.wikipedia.org/wiki/Riffle_shuffle_permutation#Perfect_shuffles
349
+ /// https://en.wikipedia.org/wiki/In_shuffle
350
+ pub fn riffle_shuffle < T : Clone > ( input : & [ T ] ) -> Vec < T > {
351
+ assert ! (
352
+ input. len( ) % 2 == 0 ,
353
+ "Method only defined for even number of elements"
354
+ ) ;
355
+ let mid = input. len ( ) / 2 ;
356
+ let ( left, right) = input. split_at ( mid) ;
357
+ let mut out = Vec :: < T > :: with_capacity ( input. len ( ) ) ;
358
+ for i in 0 ..mid {
359
+ out. push ( right[ i] . clone ( ) ) ;
360
+ out. push ( left[ i] . clone ( ) ) ;
361
+ }
362
+ out
363
+ }
364
+
346
365
#[ cfg( test) ]
347
366
mod test {
348
367
use super :: * ;
@@ -610,4 +629,36 @@ mod test {
610
629
let dels = get_delegator ( & staking, user_c. clone ( ) , val2. clone ( ) ) ;
611
630
assert_eq ! ( dels, Some ( del2c. clone( ) ) ) ;
612
631
}
632
+
633
+ #[ test]
634
+ fn riffle_shuffle_works ( ) {
635
+ // Example from https://en.wikipedia.org/wiki/In_shuffle
636
+ let start = [ 0xA , 0x2 , 0x3 , 0x4 , 0x5 , 0x6 ] ;
637
+ let round1 = riffle_shuffle ( & start) ;
638
+ assert_eq ! ( round1, [ 0x4 , 0xA , 0x5 , 0x2 , 0x6 , 0x3 ] ) ;
639
+ let round2 = riffle_shuffle ( & round1) ;
640
+ assert_eq ! ( round2, [ 0x2 , 0x4 , 0x6 , 0xA , 0x3 , 0x5 ] ) ;
641
+ let round3 = riffle_shuffle ( & round2) ;
642
+ assert_eq ! ( round3, start) ;
643
+
644
+ // For 14 elements, the original order is restored after 4 executions
645
+ // See https://en.wikipedia.org/wiki/In_shuffle#Mathematics and https://oeis.org/A002326
646
+ let original = [ 12 , 33 , 76 , 576 , 0 , 44 , 1 , 14 , 78 , 99 , 871212 , -7 , 2 , -1 ] ;
647
+ let mut result = Vec :: from ( original) ;
648
+ for _ in 0 ..4 {
649
+ result = riffle_shuffle ( & result) ;
650
+ }
651
+ assert_eq ! ( result, original) ;
652
+
653
+ // For 24 elements, the original order is restored after 20 executions
654
+ let original = [
655
+ 7 , 4 , 2 , 4656 , 23 , 45 , 23 , 1 , 12 , 76 , 576 , 0 , 12 , 1 , 14 , 78 , 99 , 12 , 1212 , 444 , 31 ,
656
+ 111 , 424 , 34 ,
657
+ ] ;
658
+ let mut result = Vec :: from ( original) ;
659
+ for _ in 0 ..20 {
660
+ result = riffle_shuffle ( & result) ;
661
+ }
662
+ assert_eq ! ( result, original) ;
663
+ }
613
664
}
0 commit comments