 What's up guys my name is Michael and welcome to my YouTube channel today We are going to go over brute forcing with bit masks I know this is like one of those topics where it's like super duper confusing Because like bit masks are like what one zero one zero zero one stuff like that And I know it's pretty difficult to understand So what I'm gonna do is I'm going to explain to you guys how bit masks work and why they work for brute forcing Okay, so let's actually do a problem where given a set of numbers That's so given a set. So this is a problem given a set of numbers Find all possible subsets. We're gonna brute force this using bit masks And what do I mean by a subset? So let's say I'm given these set numbers of one two and three I want you to brute force and give me all possible subsets So a subset basically is it's like a set of numbers from this one two and three We could pick values off of it, right? I could pick one that'll be a subset of one two three Right because I picked that one number of one, right? I could pick one from one two three. I could pick two From one two three. I'll be another number another subset out of the numbers one two and three So let's actually label all possible subsets. You could have okay the sake of this video when I say set one two is the same thing That's two one one two. This is gonna be able this is equivalent to two one and the reason why this is equivalent to two one is because you're picking one and two and Those two values. It's the same thing as picking two and one now Let's actually label all possible subsets of this problem. So given one two and three How many different subsets can I pick first of all I could pick nothing, right? So I just pick an empty set. So this is just gonna be empty, right? I pick nothing right then empty set is just nothing right because this is a possibility of Picking a subset out of this at one two three. I just pick nothing, right? What else can I pick? Well, I could pick one by itself. So that'll just be one So that'll be a single number one. I just pick one right out of the subset of one two three I could just also just pick two just pick the single number two and I also could just pick three, right? So this is another subset three well about other possible values Well, I could for one I could pick one and two right I could pick one two because that's that's another way I could pick one two I could pick one and three What else go to pick I could pick one two and three so pick the whole all the values of the subset Right all the values so one two now what about two well two I could pick one and two again But two and one is the same thing as one two. So we're not gonna pick choose one We could pick two and three because we haven't chosen that yet. So let's actually pick two and three We cannot pick three and three because that's just by itself. So that doesn't count There's not there's not another three number here. So that doesn't count. Yeah, that's it That's all we could pick for two. Alright, so now let's look at three three We could pick three one, but we already wrote three one, right? We already have one or three you could pick three two, but we already wrote two and three, right? So Three three you can't really pick a three three because that's just itself number, right? We don't have another three here. So yeah, so how many different possible subsets do we have we have one? two three four five six seven and also eight Eight eight of these subsets, right? So given the length of this set this length is equal to three But there's three numbers, right? One two and three this length of the set the cardinality of the set how the size of it is three because there's three numbers Given this the all the counting of all the possible subsets we have we have a total of eight, right? one two three four five six seven eight now let's try to represent this eight as a Mathematical function considering the number of values we have then the size of our set so our size of our set is three Right, so wait a minute eight is actually a third, right? And this three is the same thing as this n a Various value of n the size of our set So the number of total number possible subsets we have is actually two to the end Two to the end where n is the size of our set so to the end is the total possible subsets if we're gonna Compute all the possible subsets We know we have a total of two to the end So that means that our outer loop that we write in the code is going to be two to the end because we have to go Through all the possible subsets and that's the total possible subsets two to the end So how do you write that in bits to write this in bit equivalence? So every time you shift to the left you multiply it by two remember recall that if I shift down like this I Shift down right whenever I shift something down like you like this, right? I'm actually multiplying the value by two. So if I want to get this this to the end and Into the equivalence. I'm actually going to actually shift this the current value of one right shift it down and Times right because this is going to multiply multiply this value one By two n times Okay, in terms of bit equivalence like every time I shift something down to the left You're actually multiplying the current number by two. So this number one I'm actually going to multiply it by two every single time for n Okay, so that's what this this is doing It's out of loop that we're gonna go through is gonna start from i equals zero and it's gonna go up to one shift left to the end right Because it's gonna go through all the different possible subsets values of it, okay now Let's talk about the inner loop now How are we going to get every single possible initial value in our set by brute-forcing simple Based on our original set one two and three, right? How are we gonna get every single value for each outcome? So one one two one two three two two three three an empty set How about I label each value in the set Representing one if I'm including it zero if I'm not so for an empty set that means I'm not including any values So this empty set We're not including any values. So So, what does that mean? So that means all the values here one two and three I'm not gonna include one so I'm put a zero now. I'm gonna include two so I'm gonna put a zero and three I'm not gonna include that either so this bit equivalent is going to be zero zero zero Okay, now let's look at one if I'm gonna include one What does that mean? That means I include the the first value of one so I'll be that'll be a one But then I'm not including the rest. So I'm gonna put zeros for those, okay? To to that means I'm gonna include the second value to but I'm gonna not include one and three So I'm gonna put zero one zero. Okay. All right. Now let's talk about three So have a one for the and then the rest of these zeros Okay, so I hope you guys started starting to see a pattern here. Okay, so if we're gonna look at one two We're gonna include one and two So we're gonna have ones in the places of one and two and the third one. We're not including it So this third value we're not including so we're gonna put a zero there Let's see two three Two three is going to a not include one So we're gonna put zero there and then values two and three we're gonna include there. So put one one Okay, and then one two and three one two and three is a Hopefully you guys can see this one two and three. We're gonna include all of them So that would be one one one. Okay, cuz we're including all values one on one Okay, so I basically just relabeled all the possible subsets with the equivalent to one zeros Just really just rewriting it so that it's more readable for you guys now What we have to do is we have to go through all the bits from Zero up to the length of our current set and check if it's turned on because if the bit is Equivalently turned on so if like this this bit is turned on right we turn this bit on Then that that we have we include that into the set right so we could see here too. This bit is turned on right Including to this bit is turn on this bit is also in this bit is also turned on right and then basically guys now What we have to do is we hit we need to check if the current bit in The Rigidal number is actually turned on right so current bit is turned on so we're gonna loop through the numbers from To up to 2dn right from all the possible combinations, so this is eight. There's eight choices, right? Have to go through all eight and then turn on the ones for each value. We have to turn it on so in this case Zero there's nothing turned on right all the bits are all zeros. So we just do nothing there, okay? Now if it's a one Right, basically we need to turn on all these bits. So how many bits are there? There's three of them Right, there's there's a places of three and we need to turn each one of these on so like if this one this bit is One right we have to turn this on so that's why I've got to include this value and this one We have to just we turn this bit on so I also include this and this one we also include this So that's actually convert each of these numbers into its equivalent number form To make sure you guys actually understand the bits. So here zero zero zero is gonna be zero because it's still The same thing one zero zero in base two is to the second, which is four. This is gonna be four This is gonna be two This is going to be one. We're gonna be six gonna be three All right, so one zero one is going to equal to Four plus one is five. So this is gonna be five. Okay, so this one is gonna be Plus four seven. Yeah, this is gonna use seven. So now we have the equivalent number form. So this is gonna be one two Zero one two three four five six seven now We need to basically turn on these bits, right? The the equivalent ith bit. So if you want to turn these bits on where you have to loop through the number of Values in your array. So this is gonna be three because there's three bits, right three bits of these It's gonna loop through these three bits and we're gonna actually just check if the current bit is turned on Okay, so our outer loop goes from zero to Eight, right? Because this is gonna go zero to eight. So this is gonna go to not including eight, right? So it's gonna go to seven, right? Our inner loop is actually going to go from zero to three Right because there's three there's three bits that we have to turn on and what we're gonna do is we're actually going to And the outer our outer loop of the I value is gonna end it With one shift left down by J And I'm gonna explain why this is the case one shift down by J If you recall means that we are going to keep multiplying this current value by two and whenever you shift something down You are actually padding values to it padding equivalent bits to it. So let's go over an example Yeah, let's say our our I value is five. Okay. Now. What is five represents in binary five represents one zero one It's actually pad zero in front of it. Just to have make sure we have four numbers Okay, we could do that. So what is my inner loop gonna do my inner loop is gonna go to zero one two and three and What do I do? basically If I shift left by J that means I'm going to include one bit and then I'm going to pad zeros to the right Okay, so in this case if J is zero what's gonna happen to one shift left by By zero. So if I do one shift left by zero That means I don't change anything Right, I don't actually change anything. So in this case, right J is equal to zero So if I'm shifting left by zero One shift left by zero. I'm not gonna pad anything. So that's gonna just be a one to the end Here and then you have bunch of zeros here. So now What does this do? So remember this is our this this value is one so this The value of on the bottom is one shift right by zero. So that's what this bit this value is doing Okay, so this is what it's this is what? Representing this this okay, so now when we end it by I so this is our I Alright, this is our five right five. I is equal to five. So this is what this represents zero one zero one Now if I and both of these basically all values that are ones Both ones are going to become one the rest are going to become zeros, right? So if I and and all these together One one becomes one and the rest becomes zeros So this means that I'm going to include the first value of One here, which is gonna be three I'm gonna include this three Okay, and when J becomes one and now what happens when J becomes one So now I'm gonna shift one left by one So that means that at this point I'm gonna pad of a one here and then I'm gonna have a zero here right because I just shifted left by one Original zero zero zero one now shift a lot by one so Now I have one zero so one zero on the right and the rest of these are zeros Okay, so now what happens when I and these together, right? I and these together. Well one zero becomes zero One zero one becomes zero one zero becomes zero zero zero becomes zero, okay? These are all zeros right that means that No matter what I'm not actually including anything, right? And this value this number here is not greater than Yeah, greater than zero right so this basically means that I just include a nothing So I'm not actually gonna include anything to the set. Okay, when JB comes to We have one here and we padded two zeros to the back right because we just reshifted our left value our value of one to the left By two right so originally a zero zero zero one now we shifted let down by two so now this is what One shift left by two is okay. This is what it's doing Now I'm gonna add a zero to the front. Okay, so now when you add both of these One zero becomes zero zero zero becomes zero one one is one zero zero becomes zero, right? Now we have zero one zero zero is this value greater than zero Right. Yes, it is because we're zero one zero zero and this represents in binary Four right this represents binary four and this is greater than zero So this means that we're gonna include the set of one so the set of one So basically this is going through every single possible subset possible By going through every number from zero to eight not including eight by the way not including eight And also zero to three not including three because we're we're gonna go up to but not including three, right? It'll also go to zero one and two and it's gonna include whichever bits that is turned on and It'll just print those values. That'll be considered as one subset Okay, so I hope I hope this makes a little more sense and then we could just show you the code now All right guys, so basically what I did was here's the code I create a vector which is an array of values one two and three just like what we said in the example and Here I created my value n is equal to three n is the size of the set of three So that's why I said n equal to three three n is just like a variable. I initialize to three For Looping from i equals zero and I'm going up to but not including one shift left by n so this is gonna be I less than equal to less than eight. That's what this is doing and I plus plus This J is gonna go from zero and it's going to go up to n which is going to be three So this is gonna be J is gonna go from zero to three and J plus plus then if if the current value is my current I value and by One shift left by J is greater than zero then I'm going to include the value into my subset Otherwise I don't so in the end it's actually going to go through all possible subsets So if we actually run the code right now Each subset is actually the inner loop right so each subset That we're running is this inner loop right so that's gonna that's each subset So the first time we print it out empty Which is gonna be nothing in the subset then it prints out one Then it prints out two then it's gonna print out one and then two Then it's gonna print out just three then it's gonna print out one and three then it's gonna print out two and three And it's gonna print out one two and three So we actually could step inside each iteration of the loop and to explain to you guys what what it's doing So here I'm gonna step into side Okay, so we start with zero initially and J is zero so now one shift left by zero is just one and I zero so all these values are gonna be zero so It's gonna be zero so it's not gonna do anything Then Remember I still zero right so then J is zero right now J's J's actually gonna become one now right because we just stepped in so J is now one Right here. We see J is equal to one and now we're gonna shift one down by one Which is going to pad a zero at the end and because our I value zero. It's also not gonna do anything Right because our I values all zero, so it's not gonna do anything So that's not include anything again, and then when it's two J's to My I values I value still zero so it's not gonna include anything So this basically just included nothing throughout the whole set and that's why it's empty The first part is just gonna be empty and That's why it prints out a new line. All right now our I value is one so that's Equivalent at zero zero one right and now we're gonna go through all the bits of three, right? Okay, so now here As J zero so J is zero right so if we shift left by zero Last bit is just one right so one and one is going to be one so I think we do include this Yeah, we do include it so we're gonna include J of zero so that's going to be One yeah, so we're gonna include one current value one So include that and that's why it prints out one But now J is one and when J is one we shift left by one so that's going to be Shift left by one is going to be I think zero one to zero two one two right and because our eyes one There's no bits on the other side, so it's not going to include these also, right? So yeah, it didn't include anything else. So now we print out a new line. So we just only included the value of one Okay Now our I values two and our J value is we're gonna go through all the bits and check if value of bits set for all the bits of two so If you look at two If only we could look at the bit equivalents in the allocator, but they don't give us that Damn, okay, but anyway, this should be There's actually a way to convert this into assembly but I don't have Not sure if I could do that here Okay, damn, whatever Anyway, two is just gonna add the first two bit for when I is equal to two. It's gonna. Yeah Let's see if adds those so it includes this one Includes two and then it doesn't include the rest. So yeah for two it just includes two. It doesn't include rest. So it's empty For three, let's see. What does it include? It includes one and two. Yeah, so it includes one and that includes Two and then it doesn't include the three right because for three There's the bit equivalence of three is one one zero, right, but it was these one zero So we only include one and two Right and we don't include the third one. Okay. Um, now, let's see am I at four? Yeah, four is include First one thing three. Yeah, just three. Okay. Um, so yeah So that's growing to be including three. So that's just gonna give us three Okay, what could you keep going continue going on this but yeah, let's see five What does that include us? Five it gives us One and three. Okay. Yeah, and if you just continue going on through all end choices, you're gonna get all those values So but that's basically what this code is doing Yeah, I just went through all of them. But yeah, it's basically converting the The I value number into its equivalent bit equivalence and then including those values to check if they're right or not So that's basically how you do this problem Hope you guys enjoyed this video how I explain bits I might do more videos on how to use bit bit masks to include sets. But yeah, great calm subscribe I'll check you guys later. Peace