The Google problems are always nice, sometimes even a bit too tricky. This years entry problem was quite nice with some difficulties you could run in.

You need to read the problem first, to follow the article, so here’s the link: http://code.google.com/codejam/contest/dashboard?c=433101#s=p0&a=0

If you’re a hands on programmer first you might just want implement the chain without looking at the problem more extensively. So you might end up with something like this:

// snapping // snapping boolean toggle = true; for (int j = 0; j < snaps; j++) { toggle = true; for (int k = 0; k < snapperCount; k++) { if(toggle == false){ break; } if (toggle == true) { snapper[k] = !snapper[k]; } if (snapper[k] == true) { toggle = false; } } } // we need power on all snappers boolean power = true; for (int j = 0; j < snapperCount; j++) { if (snapper[j] == false) { power = false; break; } }

This basically simulates the toggling of the switch. Works fine. Does solve the small input set without a problem. The thing is, it doesn't perform that good and is really ugly to read.

So it's time to take a closer look to the different states of the snappers. Try writing down the first couple of steps on a piece of paper. You will notice that it's just a binary count. So instead of iterating you can define the output right away, I don't have to tell you what performance benefit this will give.

So let's do this here, with an example.

We take 4 snappers and we snap 47 times. Ok you might notice that is the last example of the challenge, but it's good enough.

So let's look at the binary representation of 47:

101111

We have to read the chain from right to left, so that we can see how far the power actually travels. Now we have 6 digits but only 4 snappers. So we need to truncate the top. So we AND our binary number with our desired result. If we get the desired number, the light's on, if not, it's off.

101111 (the 47) 001111 (we need 4 snappers powered on) -------------- (AND) 001111 (light is on)

Let's do snap nr. 48

110000 (48 snaps) 001111 (the 4 snappers powered) ---------- 000000 (well, the ligh's off now)

So let's see how the code could look like for this way of implementing the problem

int n=4; int k=47; String needed = Integer.toBinaryString((1<<n)-1); String current = Integer.toBinaryString(47); System.out.println("state needed : "+ needed); System.out.println("current state: "+ current ); System.out.println("result of AND: "+ Integer.toBinaryString(k & (1<<n)-1) );

For me, with my somewhat rusted binary skills, the tricky part was to convert the decimal 4 into the four bits we need: 1111. To achieve this, take a 1 and shift it 4 times to the left (the 1 << n part). Then we end up with 10000. If we now subtract 1 we have 01111 or 1111, exactly what we need.

With this approach you can calculate the result without stressing your CPU with loops.

You can find the code here: http://github.com/nheid/unitedcoders-examples/tree/master/src-java/com/unitedcoders/examples/codejam/