简体   繁体   English

这是针对代码战的挑战,我通过了所有测试,但它说我的代码运行时间太长?

[英]This is for a codewars challenge, I pass all the tests yet it says my code takes too long to run?

I am solving the CodeWars challenge Bouncing Balls :我正在解决 CodeWars 挑战Bouncing Balls

A child is playing with a ball on the nth floor of a tall building.一个孩子在高楼的n层玩球。 The height of this floor, h , is known.该楼层的高度h是已知的。

He drops the ball out of the window.他将球从 window 中掉出来。 The ball bounces (for example), to two-thirds of its height (a bounce of 0.66).球反弹(例如)到其高度的三分之二(反弹 0.66)。

His mother looks out of a window 1.5 meters from the ground.他的母亲从距离地面 1.5 米的 window 向外看。

How many times will the mother see the ball pass in front of her window (including when it's falling and bouncing?妈妈会看到多少次球从她的 window 前面传过去(包括它下落弹跳的时候?

Three conditions must be met for a valid experiment:一个有效的实验必须满足三个条件:

  • Float parameter "h" in meters must be greater than 0以米为单位的浮点参数“h”必须大于 0
  • Float parameter "bounce" must be greater than 0 and less than 1浮点参数“bounce”必须大于 0 且小于 1
  • Float parameter "window" must be less than h.浮点参数“window”必须小于 h。

If all three conditions above are fulfilled, return a positive integer, otherwise return -1.如果以上三个条件都满足,则返回正 integer,否则返回 -1。

Note:笔记:

The ball can only be seen if the height of the rebounding ball is strictly greater than the window parameter.只有反弹球的高度严格大于window 参数时才能看到球。

My code:我的代码:

def bouncing_ball(h, bounce, window):
    ball_h = h
    num = 0 
    #initial drop
    if ball_h>window:
        num+=1
        ball_h = ball_h*bounce
    else:
        num = -1

    while ball_h > window:
        num +=2
        ball_h = ball_h*bounce
        
    return num

My code passes all the tests yet it says my code takes too long to run, what could be the problem?我的代码通过了所有测试,但它说我的代码运行时间太长,可能是什么问题?

Thanks谢谢

There is a closed formula for this (which avoids doing the loop in Python code -- and therefor can be expected to run faster).有一个封闭的公式(它避免在 Python 代码中执行循环——因此可以预期运行得更快)。

Let n be the number of times that the ball reaches a relative peak height that is still high enough, then the following condition is true:n为球达到仍足够高的相对峰高的次数,则以下条件为真:

h * bounce n > window h * 反弹n > window

From this we can derive n :由此我们可以得出n

n = log bounce (window / h)) n = 日志反弹(窗口/小时))

We need to multiply this n with 2 (for up and down) and subtract one as the original position of the ball is at a peak (there is no corresponding "up").我们需要将此n乘以 2(向上和向下)并减去 1,因为球的原始 position 处于峰值(没有相应的“向上”)。

This leads to the following code:这导致以下代码:

from math import log, ceil

def bouncing_ball(h, bounce, window):
    if not (0 <= bounce < 1) or h < 0: 
        return -1 
    return ceil(log(window / h, bounce)) * 2 - 1

You forgot to check the conditions and thus got into an infinite loop.您忘记检查条件,因此进入了无限循环。 If you add this at the start of your code, it easily gets accepted:如果您在代码开头添加它,它很容易被接受:

    if not (h > 0 and 0 < bounce < 1 and window < h):
        return -1

Often, such constraints are guarantees , ie, you can assume that every input fulfills them.通常,这样的约束是保证,也就是说,您可以假设每个输入都满足它们。 But in this case, you're told to return -1 if they're not fulfilled, so you must not assume them to be.但是在这种情况下,如果它们没有被满足,你会被告知返回-1 ,所以你不能假设它们是。

That said, trincot's closed formula should be better.也就是说,trincot 的封闭式公式应该更好。 Maybe there's a harder version of the problem on codewars, where that is needed.也许需要的地方,代码战问题有一个更难的版本。 But in this one, both your solution (with the above fix) and trincot's get accepted in about 0.5 seconds (so that seems to be the baseline, most of the time actually taken by the judge, your solution actually takes something like 0.000034 seconds and trincot's 0.000023 seconds (measured by running codewars' test cases elsewhere (you get to see them once you solved the kata)).但是在这一个中,您的解决方案(具有上述修复)和 trincot 都在大约 0.5 秒内被接受(所以这似乎是基线,大部分时间实际上是由法官花费的,您的解决方案实际上需要大约 0.000034 秒和trincot 的 0.000023 秒(通过在其他地方运行 codewars 的测试用例来测量(一旦你解决了 kata 就可以看到它们))。

I also added assert num <= 87 before the return, that still got accepted.我还在返回之前添加了assert num <= 87 ,它仍然被接受。 With 86 it failed. 86失败了。 So your loop in fact only has very little to do.所以你的循环实际上只有很少的事情要做。 At first I suspected that maybe they're not testing harder cases because large results might require too much precision for float , but not even that seems to be the case.起初我怀疑他们可能没有测试更难的案例,因为大型结果可能需要太多的精度float ,但似乎情况并非如此。 For example for arguments 100, 0.9999999, 1.5 , both you and trincot return the same result, 83994097. And yours takes several seconds while trincot's only takes microseconds:例如,对于 arguments 100, 0.9999999, 1.5 ,您和 trincot 都返回相同的结果,83994097。您的需要几秒钟,而 trincot 只需要几微秒:

83994097  3571749 us  Julian
83994097       61 us  trincot

Try it online! 在线尝试!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM