简体   繁体   English

提高 codility 的代码性能

[英]increasing code performance of codility

today i heard about this website called codility where a user can give various programming test to check their code's performance.今天我听说了这个名为 codility 的网站,用户可以在该网站上进行各种编程测试以检查其代码的性能。

When I started, they presented me with this sample test,当我开始时,他们向我展示了这个样本测试,

Task description A small frog wants to get to the other side of the road.任务描述 一只小青蛙想去马路的另一边。 The frog is currently located at position X and wants to get to a position greater than or equal to Y. The small frog always jumps a fixed distance, D. Count the minimal number of jumps that the small frog must perform to reach its target.青蛙目前位于 position X 并且想要到达大于或等于 Y 的 position。小青蛙总是跳跃固定的距离,D。计算小青蛙必须执行的最小跳跃次数才能达到其目标。

Write a function: class Solution { public int solution(int X, int Y, int D); }写一个 function: class Solution { public int solution(int X, int Y, int D); } class Solution { public int solution(int X, int Y, int D); } that, given three integers X , Y and D , returns the minimal number of jumps from position X to a position equal to or greater than Y . class Solution { public int solution(int X, int Y, int D); }给定三个整数XYD ,返回从 position X到等于或大于Y的 position 的最小跳跃次数。

For example, given:例如,给定:
X = 10
Y = 85
D = 30 the function should return 3 , because the frog will be positioned as follows: D = 30 function 应该返回3 ,因为青蛙的位置如下:

after the first jump, at position 10 + 30 = 40第一次跳跃后,在 position 10 + 30 = 40

after the second jump, at position 10 + 30 + 30 = 70第二次跳跃后,在 position 10 + 30 + 30 = 70

after the third jump, at position 10 + 30 + 30 + 30 = 100第三次跳跃后,在 position 10 + 30 + 30 + 30 = 100

Assume that: X, Y and D are integers within the range假设:X、Y、D为范围内的整数

[1..1,000,000,000]; [1..1,000,000,000]; X ≤ Y. Complexity: expected worst-case time X ≤ Y. 复杂性:预期的最坏情况时间

complexity is O(1);复杂度为 O(1); expected worst-case space complexity is O(1).预期的最坏情况空间复杂度为 O(1)。

The question was pretty straight forward and it took me like 2 minutes to write the solution, which is following,这个问题非常简单,我花了大约 2 分钟来编写解决方案,下面是,

class Solution {
    public int solution(int X, int Y, int D) {

        int p = 0;
        while (X < Y){
            p++;
            X = X + D;
        }
    return p;
    }
}

However, the test result shows that the performance of my code is just 20% and I scored just 55% ,但是,测试结果显示我的代码的性能只有20% ,而我的得分只有55%

在此处输入图像描述

Here is the link to result, https://codility.com/demo/results/demo66WP2H-K25/这是结果的链接, https://codility.com/demo/results/demo66WP2H-K25/

That was so simple code, where I have just used a single while loop, how could it possibly be make much faster?这么简单的代码,我只用了一个while循环,怎么可能做得更快呢?

Basic math:基础数学:

X + nD >= Y
nD >= Y - X
n >= (Y - X) / D

The minimum value for n will be the result of rounding up the division of (Y - X) by D. n 的最小值将是 (Y - X) 除以 D 的结果。

Big O analysis for this operation:此操作的大 O 分析:

  • Complexity: O(1).复杂度:O(1)。 It's a difference, a division and a round up这是一个差异,一个分裂和一个回合
  • Worst-case space complexity is O(1): you can have at most 3 more variables:最坏情况的空间复杂度为 O(1):您最多可以有 3 个以上的变量:
    • Difference for Y - X, let's assign this into Z. Y - X 的差异,让我们将其分配给 Z。
    • Division between Z by D, let's assign this into E. Z 与 D 之间的除法,让我们将其分配给 E。
    • Rounding E up, let's assign this into R (from result).将 E 向上舍入,让我们将其分配给 R(来自结果)。

Java(One Line), Correctness 100%, Performance 100%, Task score 100% Java(一行),正确性100%,性能100%,任务得分100%

// you can also use imports, for example:
// import java.util.*;

// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");

class Solution {
    public int solution(int X, int Y, int D) {
      return (int) Math.ceil((double) (Y - X) / (double) D);
    }
}
class Solution {
  public int solution(int x, int y, int d) {
    return (y - x + d - 1) / d;
  }
}
class Solution {
    public int solution(int x, int y, int d) {
        // write your code in Java SE 8
        System.out.println("this is a debug message"+(y-x)%d);
        if((y-x)%d == 0)
            return ((y-x)/d);
        else
            return (((y-x)/d)+1);
    }
}

C# got 100 out of 100 points C# 得到 100 分(满分 100 分)

using System;
// you can also use other imports, for example:
// using System.Collections.Generic;

// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");

class Solution {
    public int solution(int X, int Y, int D) {

        int Len= Y-X;
        if (Len%D==0)
        {
            return Len/D;
        }
        else
        {
            return (Len/D)+1;
        }
    }
}

Here is the 100% total score Python solution :这是100% 总分的 Python 解决方案

def solution(X, Y, D):
    # write your code in Python 3.6
    s = (Y-X)/D
    return int(-(-s // 1))

Here's Scala solution:这是Scala解决方案:

def solution(X: Int, Y: Int, D: Int): Int = {

    //divide distance (Y-X) with fixed jump distance. If there is reminder then add 1 to result to
    // cover that part with one jump

    val jumps  =   (Y-X) / D  + (if(((Y-X) % D) >0 ) 1 else 0)

    jumps

  }

Performance: https://codility.com/demo/results/trainingTQS547-ZQW/性能: https : //codility.com/demo/results/trainingTQS547-ZQW/

Here is a solution that brings the test performance to 100%这是一个使测试性能达到 100% 的解决方案

class Solution {
    public int solution(int X, int Y, int D) {
        if (X >= Y) return 0;

        if (D == 0) return -1;

        int minJump = 0;

        if ((Y - X) % D == 0) {
            minJump = (Y - X) / D;
        } else minJump= (Y - X) / D +1;

        return minJump;
    }
}

JavaScript solution 100/100 JavaScript 解决方案 100/100

function solution (x,y,d) {
    if ((y-x) % d === 0) {
        return (y-x)/d;
    } else {
        return Math.ceil((y-x)/d);
    }
}

Javascript solution, 100/100, and shorter than the existing answer: Javascript 解决方案,100/100,比现有答案更短:

function solution(Y, Y, D) {
 return Math.ceil((Y - X) / D);
}

Using Java perfect code使用Java完美代码

100 score code in Java

public int solution(int X, int Y, int D) {公共 int 解决方案(int X,int Y,int D){

if(X<0 && Y<0) return 0; if(X<0 && Y<0) 返回 0;

  if(X==Y)
          return 0;

     if((Y-X)%D==0)
         return (Y-X)/D;
     else
         return (((Y-X)/D)+1);  

}

this is corrected code using java giving 91% pass这是使用 java 进行更正的代码,通过率 91%

int solution(int A[]) {

        int len = A.length;
        if (len == 2) {
            return Math.abs(A[1] - A[0]);
        }
        int[] sumArray = new int[A.length];
        int sum = 0;
        for (int j = 0; j < A.length; j++) {
            sum = sum + A[j];
            sumArray[j] = sum;
        }
        int min = Integer.MAX_VALUE;
        for (int j = 0; j < sumArray.length; j++) {
            int difference = Math.abs(sum - 2 * sumArray[j]);
            // System.out.println(difference);
            if (difference < min)
                min = difference;
        }
        return min;
    }

This is my solution with 100% (C#):这是我 100% (C#) 的解决方案:

       int result = 0;
        if (y <= x || d == 0)
        {
            result = 0;
        }
        else
        {
            result = (y - x + d - 1) / d;

        }

        return result;

Here is my solution in PHP, 100% performance.这是我的 PHP 解决方案,100% 性能。

   function solution($X, $Y, $D) {
       return (int)ceil(($Y-$X)/$D); //ceils returns a float and so we cast (int)
   }

YX gives you the actual distance object has to be travel ,if that distance is directly divsible by object jump(D) then ans will be (sum/D) if some decimal value is there then we have to add 1 more into it ie(sum/D)+1 YX 为您提供了对象必须移动的实际距离,如果该距离可以直接被对象 jump(D) 整除,那么 ans 将是 (sum/D),如果存在某个十进制值,那么我们必须在其中再加 1,即(总和/D)+1

    int  sum=Y-X;
    if(X!=Y && X<Y){
    if(sum%D==0){
        return (int )(sum/D);
    }
    else{
        return ((int)(sum/D)+1);
    }}
    else{
        return 0;
    }

I like all the rest of the solutions, especially "(y - x + d - 1) / d".我喜欢所有其余的解决方案,尤其是“(y - x + d - 1) / d”。 That was awesome.这太棒了。 This is what I came up with.这就是我想出的。

public int solution(int X, int Y, int D) {
        if (X == Y || X > Y || D == 0) {
            return 0;
        }

        int total = (Y - X) / D;
        int left = (Y - X) - (D * total);

        if (left > 0) {
            total++;
        }

        return total;
    }
// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');

function solution(X, Y, D) {
  let jumps = 0

  //If 0 -> 100 with 2 step
  // Answer would be 100/2 = 50
  //If 10 -> 100 with 2 step
  //Answer would be (100 - 10) / 2 = 45
  jumps = Math.ceil((Y - X) / D)
  return jumps
}

swift solution 100% PASS - O(1) complexity快速解决方案 100% PASS - O(1) 复杂度

import Foundation
import Glibc

public func solution(_ X : Int, _ Y : Int, _ D : Int) -> Int {

if X == Y {
    return 0
}

var jumps = (Y-X)/D

if jumps * D + X < Y {
    jumps += 1
}

return jumps

}
import math


def solution(X, Y, D):
    if (X >= Y): return 0

    if (D == 0): return -1

    minJump = 0

    #if ((Y - X) % D == 0):
    minJump = math.ceil((Y - X) / D)
    #else: 
        #minJump = math.ceil((Y - X) / D) +1

    return minJump

This solution worked for me in Java 11:这个解决方案在 Java 11 中对我有用:

public int solution(int X, int Y, int D) {
    return X == Y ? 0 : (Y - X - 1) / D + 1;
}

Correctness 100%, Performance 100%, Task score 100%正确率 100%,性能 100%,任务得分 100%

@Test
void solution() {
    assertThat(task1.solution(0, 0, 30)).isEqualTo(0);
    assertThat(task1.solution(10, 10, 10)).isEqualTo(0);
    assertThat(task1.solution(10, 10, 30)).isEqualTo(0);
    assertThat(task1.solution(10, 30, 30)).isEqualTo(1);
    assertThat(task1.solution(10, 40, 30)).isEqualTo(1);
    assertThat(task1.solution(10, 45, 30)).isEqualTo(2);
    assertThat(task1.solution(10, 70, 30)).isEqualTo(2);
    assertThat(task1.solution(10, 75, 30)).isEqualTo(3);
    assertThat(task1.solution(10, 80, 30)).isEqualTo(3);
    assertThat(task1.solution(10, 85, 30)).isEqualTo(3);
    assertThat(task1.solution(10, 100, 30)).isEqualTo(3);
    assertThat(task1.solution(10, 101, 30)).isEqualTo(4);
    assertThat(task1.solution(10, 105, 30)).isEqualTo(4);
    assertThat(task1.solution(10, 110, 30)).isEqualTo(4);
}

Here is the JS implementation这是JS实现

function frogJumbs(x, y, d) {
    if ((y - x) % d == 0) {
        return Math.floor((y - x) / d);
    }
    return Math.floor((y - x) / d + 1);
}
console.log(frogJumbs(0, 150, 30));

100% C# solution: 100% C# 解决方案:

public int solution(int X, int Y, int D)
{
  var result = Math.Ceiling((double)(Y - X) / D);
  return Convert.ToInt32(result);
}

It divides the total distance by length of a jump and rounds up the result.它将总距离除以跳跃长度并将结果四舍五入 It came after multiple attempts and some web searches.它是在多次尝试和一些网络搜索之后出现的。

Here is the solution in Python giving a score of 100 on Codility:这是 Python 中的解决方案,在 Codility 上得分为 100:

import math
return math.ceil((Y-X)/D)

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

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