Skip to content

Instantly share code, notes, and snippets.

@hariketsheth
Created February 16, 2022 15:56
Show Gist options
  • Save hariketsheth/0d416ea892ec23024efa0ffe65e3187a to your computer and use it in GitHub Desktop.
Save hariketsheth/0d416ea892ec23024efa0ffe65e3187a to your computer and use it in GitHub Desktop.
Foobar Google Challenge - Dodge the Lasers!
"""
Dodge the Lasers!
=================
Oh no! You've managed to escape Commander Lambda's collapsing space station in an escape pod with the rescued bunny workers - but Commander Lambda isnt about to let you get away that easily. Lambda sent an elite fighter pilot squadron after you -- and they've opened fire!
Fortunately, you know something important about the ships trying to shoot you down. Back when you were still Lambda's assistant, the Commander asked you to help program the aiming mechanisms for the starfighters. They undergo rigorous testing procedures, but you were still able to slip in a subtle bug. The software works as a time step simulation: if it is tracking a target that is accelerating away at 45 degrees, the software will consider the targets acceleration to be equal to the square root of 2, adding the calculated result to the targets end velocity at each timestep. However, thanks to your bug, instead of storing the result with proper precision, it will be truncated to an integer before adding the new velocity to your current position. This means that instead of having your correct position, the targeting software will erringly report your position as sum(i=1..n, floor(i*sqrt(2))) - not far enough off to fail Commander Lambdas testing, but enough that it might just save your life.
If you can quickly calculate the target of the starfighters' laser beams to know how far off they'll be, you can trick them into shooting an asteroid, releasing dust, and concealing the rest of your escape. Write a function solution(str_n) which, given the string representation of an integer n, returns the sum of (floor(1*sqrt(2)) + floor(2*sqrt(2)) + ... + floor(n*sqrt(2))) as a string. That is, for every number i in the range 1 to n, it adds up all of the integer portions of i*sqrt(2).
For example, if str_n was "5", the solution would be calculated as
floor(1*sqrt(2)) +
floor(2*sqrt(2)) +
floor(3*sqrt(2)) +
floor(4*sqrt(2)) +
floor(5*sqrt(2))
= 1+2+4+5+7 = 19
so the function would return "19".
str_n will be a positive integer between 1 and 10^100, inclusive. Since n can be very large (up to 101 digits!), using just sqrt(2) and a loop won't work. Sometimes, it's easier to take a step back and concentrate not on what you have in front of you, but on what you don't.
Fortunately, you know something important about the ships trying to shoot you down. Back when you were still Commander Lambdas assistant, she asked you to help program the aiming mechanisms for the starfighters. They undergo rigorous testing procedures, but you were still able to slip in a subtle bug. The software works as a time step simulation: if it is tracking a target that is accelerating away at 45 degrees, the software will consider the targets acceleration to be equal to the square root of 2, adding the calculated result to the targets end velocity at each timestep. However, thanks to your bug, instead of storing the result with proper precision, it will be truncated to an integer before adding the new velocity to your current position. This means that instead of having your correct position, the targeting software will erringly report your position as sum(i=1..n, floor(i*sqrt(2))) - not far enough off to fail Commander Lambdas testing, but enough that it might just save your life.
If you can quickly calculate the target of the starfighters' laser beams to know how far off they'll be, you can trick them into shooting an asteroid, releasing dust, and concealing the rest of your escape. Write a function solution(str_n) which, given the string representation of an integer n, returns the sum of (floor(1*sqrt(2)) + floor(2*sqrt(2)) + ... + floor(n*sqrt(2))) as a string. That is, for every number i in the range 1 to n, it adds up all of the integer portions of i*sqrt(2).
For example, if str_n was "5", the solution would be calculated as
floor(1*sqrt(2)) +
floor(2*sqrt(2)) +
floor(3*sqrt(2)) +
floor(4*sqrt(2)) +
floor(5*sqrt(2))
= 1+2+4+5+7 = 19
so the function would return "19".
str_n will be a positive integer between 1 and 10^100, inclusive. Since n can be very large (up to 101 digits!), using just sqrt(2) and a loop won't work. Sometimes, it's easier to take a step back and concentrate not on what you have in front of you, but on what you don't.
Languages
=========
To provide a Java solution, edit Solution.java
To provide a Python solution, edit solution.py
Test cases
==========
Your code should pass the following test cases.
Note that it may also be run against hidden test cases not shown here.
-- Java cases --
Input:
Solution.solution('77')
Output:
4208
Input:
Solution.solution('5')
Output:
19
-- Python cases --
Input:
solution.solution('77')
Output:
4208
Input:
solution.solution('5')
Output:
19
"""
def get_breakpoints(n):
breakpoints = {}
done, even, p, q = False, True, 1,1
while not done:
if even:
if q <= n: breakpoints[q] = p
else: done = True
else:
if p <= n: breakpoints[p] = 2 * q
else: done = True
p, q = p + 2 * q, p + q
even = not even
return breakpoints
def calc_cum_sums(end, keys, breakpoints, cum_sums):
cum_sum, loc, offset = 0,0,0
j = len(keys) - 1
while j >= 0:
key0 = keys[j]
stride = key0
while loc + stride <= end:
cum_sum += cum_sums[key0]
loc += stride
cum_sum += offset * stride
offset += breakpoints[key0]
j -= 1
return cum_sum
def solution(str_n):
n = int(str_n)
breakpoints = get_breakpoints(n)
keys = sorted(breakpoints.keys())
cum_sums = {}
for i in range(len(keys)):
key = keys[i]
cum_sum = calc_cum_sums(key-1, keys[:i], breakpoints, cum_sums)
cum_sums[key] = cum_sum + breakpoints[key]
cum_sum = calc_cum_sums(n, keys, breakpoints, cum_sums)
return str(cum_sum)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment