Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 371df3c

Browse files
committed
Add depth as parameter
This will give a more general API.
1 parent 85b9514 commit 371df3c

File tree

1 file changed

+50
-47
lines changed

1 file changed

+50
-47
lines changed

brute_force_by_depth.gp

Lines changed: 50 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,54 +6,57 @@
66
{
77
\\ Loop through all possible indices with certain weight, sorted by depth.
88
\\ 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))))
1011
\\ As another example, to count the number of bitmasks generated (for sanity
1112
\\ 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 1s 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 1s 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 1s 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 1s 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 1s 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 1s 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);
5860
)
61+
)
5962
}

0 commit comments

Comments
 (0)