@@ -226,46 +226,6 @@ ror64 (uint64_t x,
226226 return !(n &= 63U ) ? x : (x >> n | x << (64U - n ));
227227}
228228
229- static uint64_t
230- is_b26 (uint64_t const x ,
231- unsigned * const rot )
232- {
233- uint64_t y = x << 6U | x >> (64U - 6U );
234- uint64_t m = 0U ;
235- unsigned r = 0U ;
236- unsigned n = 0U ;
237-
238- do {
239- y >>= 1U ;
240- uint64_t b = UINT64_C (1 ) << (y & 63U );
241- uint64_t m_ = m ;
242- m |= b ;
243- if (m == m_ )
244- return 0U ;
245- ++ n ;
246- if (b == 1U )
247- r = n & 63U ;
248- } while (n < 6U );
249-
250- y = x ;
251- do {
252- y >>= 1U ;
253- uint64_t b = UINT64_C (1 ) << (y & 63U );
254- uint64_t m_ = m ;
255- m |= b ;
256- if (m == m_ )
257- return 0U ;
258- ++ n ;
259- if (b == 1U )
260- r = n & 63U ;
261- } while (m != UINT64_MAX );
262-
263- if (rot )
264- * rot = r ;
265-
266- return ror64 (x , r );
267- }
268-
269229static force_inline size_t
270230mapping (struct ptab * tab ,
271231 unsigned idx )
@@ -947,8 +907,13 @@ bag_gen (struct bag *const a,
947907}
948908
949909static int64_t
950- b26_find (uint64_t const * ptr ,
951- uint64_t key );
910+ b26_find (uint64_t seq ,
911+ uint64_t const * arr );
912+
913+ static uint64_t
914+ b26_identify (uint64_t x ,
915+ uint32_t * id ,
916+ uint64_t const * arr );
952917
953918static void
954919bags_scan (struct bag * const b ,
@@ -959,36 +924,33 @@ bags_scan (struct bag *const b,
959924 for (unsigned i = 0 ; i < 119U ; ++ i ) {
960925 for (unsigned j = i ; j < 119U ; ++ j ) {
961926 for (unsigned r = 0U ; r < 16U ; ++ r , bag_move_head (& b [j ], 1 , 1 )) {
962- unsigned rot = 0 ;
963- uint64_t u64 = is_b26 (bag_gen (& b [i ], & b [j ]), & rot );
927+ uint32_t id = 0 ;
928+ uint64_t u64 = b26_identify (bag_gen (& b [i ], & b [j ]), & id , b26 );
964929 if (u64 ) {
965- int64_t id = b26_find (b26 , u64 );
966930 printf ("a=%3u 0x%08" PRIx32 " b=%3u 0x%08" PRIx32
967- " r=%2u 0x%016" PRIx64 " (%" PRId64 ",%u )\n" , i , b [i ].seq ,
968- j , b [j ].seq , r , u64 , id , rot );
931+ " r=%2u 0x%016" PRIx64 " (%" PRIu32 ",%" PRIu32 " )\n" , i , b [i ].seq ,
932+ j , b [j ].seq , r , u64 , id >> 6U , id & 63U );
969933 }
970934 if (i == j )
971935 continue ;
972- rot = 0 ;
973- u64 = is_b26 (bag_gen (& b [j ], & b [i ]), & rot );
936+ id = 0 ;
937+ u64 = b26_identify (bag_gen (& b [j ], & b [i ]), & id , b26 );
974938 if (u64 ) {
975- int64_t id = b26_find (b26 , u64 );
976939 printf ("a=%3u 0x%08" PRIx32 " b=%3u 0x%08" PRIx32
977- " r=%2u 0x%016" PRIx64 " (%" PRId64 ",%u )\n" , j , b [j ].seq ,
978- i , b [i ].seq , r , u64 , id , rot );
940+ " r=%2u 0x%016" PRIx64 " (%" PRIu32 ",%" PRIu32 " )\n" , j , b [j ].seq ,
941+ i , b [i ].seq , r , u64 , id >> 6U , id & 63U );
979942 }
980943 }
981944 if (i == j )
982945 continue ;
983946 for (unsigned r = 0U ; r < 16U ; ++ r , bag_move_head (& b [i ], 1 , 1 )) {
984- unsigned rot = 0 ;
985- uint64_t u64 = is_b26 (bag_gen (& b [j ], & b [i ]), & rot );
986- if (u64 ) {
987- int64_t id = b26_find (b26 , u64 );
988- printf ("a=%3u 0x%08" PRIx32 " b=%3u 0x%08" PRIx32
989- " r=%2u 0x%016" PRIx64 " (%" PRId64 ",%u)\n" , j , b [j ].seq ,
990- i , b [i ].seq , r , u64 , id , rot );
991- }
947+ uint32_t id = 0 ;
948+ uint64_t u64 = b26_identify (bag_gen (& b [j ], & b [i ]), & id , b26 );
949+ if (!u64 )
950+ continue ;
951+ printf ("a=%3u 0x%08" PRIx32 " b=%3u 0x%08" PRIx32
952+ " r=%2u 0x%016" PRIx64 " (%" PRIu32 ",%" PRIu32 ")\n" ,
953+ j , b [j ].seq , i , b [i ].seq , r , u64 , id >> 6U , id & 63U );
992954 }
993955 }
994956 }
@@ -1088,21 +1050,77 @@ b26_cmp (void const *pkey,
10881050}
10891051
10901052static int64_t
1091- b26_find (uint64_t const * const ptr ,
1092- uint64_t const key )
1053+ b26_find (uint64_t const seq ,
1054+ uint64_t const * const arr )
10931055{
1094- if (!ptr )
1056+ if (!arr )
10951057 return -1 ;
10961058
10971059#if UINTPTR_MAX >= 0x3f79d71b4cb0a89
1098- void const * k = (void const * )key ;
1060+ void const * k = (void const * )seq ;
10991061#else
1100- void const * k = (void const * )& key ;
1062+ void const * k = (void const * )& seq ;
11011063#endif
1102- uint64_t const * ret = bsearch (k , ptr , UINT64_C (1 ) << 26U ,
1103- sizeof * ptr , b26_cmp );
1064+ uint64_t const * ret = bsearch (k , arr , UINT64_C (1 ) << 26U ,
1065+ sizeof * arr , b26_cmp );
11041066 if (!ret )
11051067 return -1 ;
11061068
1107- return (int64_t )(ptrdiff_t )(ret - ptr );
1069+ return (int64_t )(ptrdiff_t )(ret - arr );
1070+ }
1071+
1072+ static uint64_t
1073+ is_b26 (uint64_t const x ,
1074+ unsigned * const rot )
1075+ {
1076+ uint64_t y = x << 6U | x >> (64U - 6U );
1077+ uint64_t m = 0U ;
1078+ unsigned r = 0U ;
1079+ unsigned n = 0U ;
1080+
1081+ do {
1082+ y >>= 1U ;
1083+ uint64_t b = UINT64_C (1 ) << (y & 63U );
1084+ uint64_t m_ = m ;
1085+ m |= b ;
1086+ if (m == m_ )
1087+ return 0U ;
1088+ ++ n ;
1089+ if (b == 1U )
1090+ r = n & 63U ;
1091+ } while (n < 6U );
1092+
1093+ y = x ;
1094+ do {
1095+ y >>= 1U ;
1096+ uint64_t b = UINT64_C (1 ) << (y & 63U );
1097+ uint64_t m_ = m ;
1098+ m |= b ;
1099+ if (m == m_ )
1100+ return 0U ;
1101+ ++ n ;
1102+ if (b == 1U )
1103+ r = n & 63U ;
1104+ } while (m != UINT64_MAX );
1105+
1106+ if (rot )
1107+ * rot = r ;
1108+
1109+ return ror64 (x , r );
1110+ }
1111+
1112+ static uint64_t
1113+ b26_identify (uint64_t x ,
1114+ uint32_t * const id ,
1115+ uint64_t const * const arr )
1116+ {
1117+ unsigned rot = 0 ;
1118+ x = is_b26 (x , & rot );
1119+ if (x ) {
1120+ int64_t i = b26_find (x , arr );
1121+ if (i < 0 )
1122+ return 0U ;
1123+ * id = ((uint32_t )i << 6U ) | rot ;
1124+ }
1125+ return x ;
11081126}
0 commit comments