patternpythonMinor
Google FooBar XOR Checksum Challenge
Viewed 0 times
xorgooglefoobarchallengechecksum
Problem
Google FooBar came up a few days ago and I took it as a challenge to learn python quickly while having fun. However, I ran into one challenge today that has left me stumped, I've come up with a solution that finds the correct result, however it is not fast enough for some test cases. How can I improve upon it?
Queue To Do
You're almost ready to make your move to destroy the LAMBCHOP doomsday device, but the security checkpoints that guard the underlying systems of the LAMBCHOP are going to be a problem.
You were able to take one down without tripping any alarms, which is great!
Except that as Commander Lambda's assistant, you've learned that the checkpoints are about to come under automated review,
which means that your sabotage will be discovered and your cover blown - unless you can trick the automated review system.
To trick the system, you'll need to write a program to return the same security checksum that the guards would have after they would have checked all the workers through.
Fortunately, Commander Lambda's desire for efficiency won't allow for hours-long lines, so the checkpoint guards have found ways to quicken the pass-through rate.
Instead of checking each and every worker coming through, the guards instead go over everyone in line while noting their security IDs, then allow the line to fill back up.
Once they've done that they go over the line again, this time leaving off the last worker.
They continue doing this, leaving off one more worker from the line each time but recording the security IDs of those they do check, until they skip the entire line,
at which point they XOR the IDs of all the workers they noted into a checksum and then take off for lunch.
Fortunately, the workers' orderly nature causes them to always line up in numerical order without any gaps.
For example, if the first worker in line has ID 0 and the security checkpoint line holds three workers, the process would look like this:
```
Queue To Do
You're almost ready to make your move to destroy the LAMBCHOP doomsday device, but the security checkpoints that guard the underlying systems of the LAMBCHOP are going to be a problem.
You were able to take one down without tripping any alarms, which is great!
Except that as Commander Lambda's assistant, you've learned that the checkpoints are about to come under automated review,
which means that your sabotage will be discovered and your cover blown - unless you can trick the automated review system.
To trick the system, you'll need to write a program to return the same security checksum that the guards would have after they would have checked all the workers through.
Fortunately, Commander Lambda's desire for efficiency won't allow for hours-long lines, so the checkpoint guards have found ways to quicken the pass-through rate.
Instead of checking each and every worker coming through, the guards instead go over everyone in line while noting their security IDs, then allow the line to fill back up.
Once they've done that they go over the line again, this time leaving off the last worker.
They continue doing this, leaving off one more worker from the line each time but recording the security IDs of those they do check, until they skip the entire line,
at which point they XOR the IDs of all the workers they noted into a checksum and then take off for lunch.
Fortunately, the workers' orderly nature causes them to always line up in numerical order without any gaps.
For example, if the first worker in line has ID 0 and the security checkpoint line holds three workers, the process would look like this:
```
Solution
Let's improve the readability of your second snippet.
You can start by writing your
And use a
You can also remove the need for some operations with a decreasing range:
And this is as readable as you can get.
You can go up to the one-liner:
But I would advice against it as it is not readable anymore.
A more interesting change could be to modify the starting ID rather than the length of the queue as we go:
And extract the core functionality into its own function:
All there is left to do is optimize
You can start by writing your
reduce only once:def answer(start, length):
checksum = 0
i = 0
while length > 0:
checksum ^= reduce(operator.xor, xrange(start, start+length), 0)
start += length + i
length -= 1
i += 1
return checksumAnd use a
for loop instead of the while:def answer(start, length):
checksum = 0
for i in xrange(length):
checksum ^= reduce(operator.xor, xrange(start, start+length), 0)
start += length + i
length -= 1
return checksumYou can also remove the need for some operations with a decreasing range:
def answer(start, length):
checksum = 0
for size in xrange(length, 0, -1):
checksum ^= reduce(operator.xor, xrange(start, start + size), 0)
start += length
return checksumAnd this is as readable as you can get.
You can go up to the one-liner:
def answer(start, length):
return reduce(
operator.xor,
(reduce(operator.xor,
xrange(start + i * length, start + i * length + size),
0)
for i, size in enumerate(xrange(length, 0, -1))),
0)But I would advice against it as it is not readable anymore.
A more interesting change could be to modify the starting ID rather than the length of the queue as we go:
def answer(start, length):
checksum = 0
for i, begin in enumerate(xrange(start, start + length * length, length)):
checksum ^= reduce(operator.xor, xrange(begin, begin + length - i), 0)
return checksumAnd extract the core functionality into its own function:
def xor_in_range(a, b):
return reduce(operator.xor, xrange(a, b), 0)
def answer(start, length):
return reduce(
operator.xor,
(xor_in_range(begin, begin+length-i)
for i, begin in enumerate(xrange(start, start + length * length, length))),
0)All there is left to do is optimize
xor_in_range for speed.Code Snippets
def answer(start, length):
checksum = 0
i = 0
while length > 0:
checksum ^= reduce(operator.xor, xrange(start, start+length), 0)
start += length + i
length -= 1
i += 1
return checksumdef answer(start, length):
checksum = 0
for i in xrange(length):
checksum ^= reduce(operator.xor, xrange(start, start+length), 0)
start += length + i
length -= 1
return checksumdef answer(start, length):
checksum = 0
for size in xrange(length, 0, -1):
checksum ^= reduce(operator.xor, xrange(start, start + size), 0)
start += length
return checksumdef answer(start, length):
return reduce(
operator.xor,
(reduce(operator.xor,
xrange(start + i * length, start + i * length + size),
0)
for i, size in enumerate(xrange(length, 0, -1))),
0)def answer(start, length):
checksum = 0
for i, begin in enumerate(xrange(start, start + length * length, length)):
checksum ^= reduce(operator.xor, xrange(begin, begin + length - i), 0)
return checksumContext
StackExchange Code Review Q#149440, answer score: 2
Revisions (0)
No revisions yet.