6
6
{
7
7
\\ Loop through all possible indices with certain weight, sorted by depth.
8
8
\\ For example, to print the bitmasks in binary notations:
9
- \\ brute_force_by_depth (5 , (bitmask)->print (binary (bitmask)))
9
+ \\ weight = 5 ;
10
+ \\ for (depth = 1 , weight, brute_force_by_depth (weight, (bitmask)->print (binary (bitmask))))
10
11
\\ As another example, to count the number of bitmasks generated (for sanity
11
12
\\ check):
12
- \\ count = 0 ; brute_force_by_depth (15 , (bitmask)->count++); print (count)
13
- brute_force_by_depth (weight, func) =
14
- for (number_of_ones = 1 , weight,
15
- \\ The variable bitmask is initialized with the smallest possible number
16
- \\ that has number_of_ones bits of 1 s in the binary representation.
17
- bitmask = (1 << (weight - 1 )) + (1 << (number_of_ones - 1 )) - 1 ;
18
-
19
- \\ Loop until bitmask is greater than the biggest possible number that has
20
- \\ number_of_ones bits of 1 s in the binary representation.
21
- until (bitmask > ((1 << number_of_ones) - 1 ) << (weight - number_of_ones),
22
- func (bitmask);
23
-
24
- \\ We will find the smallest number whose binary representation
25
- \\ contains exactly number_of_ones 1 bits and greater than
26
- \\ bitmask. We will call it the " next bitmask" .
27
-
28
- \\ Get the right -most bit 1 from bitmask. For example, if the
29
- \\ original bitmask is 100111100 , last_one will be 000000100 .
30
- last_one = bitand (bitmask, bitneg (bitmask - 1 ));
31
-
32
- \\ Get the last group of 1 s from bitmask. For example, if the
33
- \\ original bitmask is 100111100 (as above), last_group_of_ones
34
- \\ will be 000111100 .
35
- last_group_of_ones = bitand (bitmask, bitneg (bitmask + last_one));
36
-
37
- \\ Consider the case 100111100 above. The next bitmask can be
38
- \\ constructed by splitting the last_group_of_ones so that we
39
- \\ shift the left most 1 of the last_group_of_ones one bit to the
40
- \\ left and shift the rest to the right most bits: 10100111 .
41
- \\ Another example, 101100011100 . Then, we will split the group
42
- \\ of 111 to be: 101100100011 .
43
-
44
- \\ First, replace the last_group_of_ones with bit 1 right to
45
- \\ the left of the group.
46
- \\ For example, 101100011100 becomes 101100100000 .
47
- bitmask = bitmask + last_one;
48
-
49
- \\ Finally, we add the remaining of the last_group_of_ones to
50
- \\ right -most bits. Notes that the trick below will also work
51
- \\ even when last_group_of_ones contains only one bit of 1 .
52
- \\ For example, the previous line will change 101100011100
53
- \\ to 101100100000 . This line now will add the remaining bits
54
- \\ to be 101100100011 .
55
- \\ Here, bitmask is now the next bitmask of the original one.
56
- bitmask = bitmask + ((last_group_of_ones / last_one) >> 1 );
57
- )
13
+ \\ weight = 15 ; count = 0 ;
14
+ \\ for (depth = 1 , weight, brute_force_by_depth (weight, (bitmask)->count++));
15
+ \\ print (count)
16
+ brute_force_by_depth (weight, depth, func) =
17
+ number_of_ones = depth;
18
+ \\ The variable bitmask is initialized with the smallest possible number
19
+ \\ that has number_of_ones bits of 1 s in the binary representation.
20
+ bitmask = (1 << (weight - 1 )) + (1 << (number_of_ones - 1 )) - 1 ;
21
+
22
+ \\ Loop until bitmask is greater than the biggest possible number that has
23
+ \\ number_of_ones bits of 1 s in the binary representation.
24
+ until (bitmask > ((1 << number_of_ones) - 1 ) << (weight - number_of_ones),
25
+ func (bitmask);
26
+
27
+ \\ We will find the smallest number whose binary representation
28
+ \\ contains exactly number_of_ones 1 bits and greater than
29
+ \\ bitmask. We will call it the " next bitmask" .
30
+
31
+ \\ Get the right -most bit 1 from bitmask. For example, if the
32
+ \\ original bitmask is 100111100 , last_one will be 000000100 .
33
+ last_one = bitand (bitmask, bitneg (bitmask - 1 ));
34
+
35
+ \\ Get the last group of 1 s from bitmask. For example, if the
36
+ \\ original bitmask is 100111100 (as above), last_group_of_ones
37
+ \\ will be 000111100 .
38
+ last_group_of_ones = bitand (bitmask, bitneg (bitmask + last_one));
39
+
40
+ \\ Consider the case 100111100 above. The next bitmask can be
41
+ \\ constructed by splitting the last_group_of_ones so that we
42
+ \\ shift the left most 1 of the last_group_of_ones one bit to the
43
+ \\ left and shift the rest to the right most bits: 10100111 .
44
+ \\ Another example, 101100011100 . Then, we will split the group
45
+ \\ of 111 to be: 101100100011 .
46
+
47
+ \\ First, replace the last_group_of_ones with bit 1 right to
48
+ \\ the left of the group.
49
+ \\ For example, 101100011100 becomes 101100100000 .
50
+ bitmask = bitmask + last_one;
51
+
52
+ \\ Finally, we add the remaining of the last_group_of_ones to
53
+ \\ right -most bits. Notes that the trick below will also work
54
+ \\ even when last_group_of_ones contains only one bit of 1 .
55
+ \\ For example, the previous line will change 101100011100
56
+ \\ to 101100100000 . This line now will add the remaining bits
57
+ \\ to be 101100100011 .
58
+ \\ Here, bitmask is now the next bitmask of the original one.
59
+ bitmask = bitmask + ((last_group_of_ones / last_one) >> 1 );
58
60
)
61
+ )
59
62
}
0 commit comments