[Codility]LESSON6

Posted ViviranZ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Codility]LESSON6相关的知识,希望对你有一定的参考价值。

Task1

Write a function

def solution(A)

that, given an array A consisting of N integers, returns the number of distinct values in array A.

For example, given array A consisting of six elements such that:

A[0] = 2 A[1] = 1 A[2] = 1 A[3] = 2 A[4] = 3 A[5] = 1

the function should return 3, because there are 3 distinct values appearing in array A, namely 1, 2 and 3.

Write an efficient algorithm for the following assumptions:

  • N is an integer within the range [0..100,000];
  • each element of array A is an integer within the range [−1,000,000..1,000,000].

Copyright 2009–2022 by Codility Limited. All Rights Reserved. Unauthorized copying, publication or disclosure prohibited.

# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")

def solution(A):
    # write your code in Python 3.6
    n=len(A)
    if n==0:
        return 0
    A.sort()
    result=1
    for i in range(1,n):
        if A[i]!=A[i-1]:
            result=result+1
    return result

Task2

A non-empty array A consisting of N integers is given. The product of triplet (P, Q, R) equates to A[P] * A[Q] * A[R] (0 ≤ P < Q < R < N).

For example, array A such that:

A[0] = -3 A[1] = 1 A[2] = 2 A[3] = -2 A[4] = 5 A[5] = 6

contains the following example triplets:

  • (0, 1, 2), product is −3 * 1 * 2 = −6
  • (1, 2, 4), product is 1 * 2 * 5 = 10
  • (2, 4, 5), product is 2 * 5 * 6 = 60

Your goal is to find the maximal product of any triplet.

Write a function:

def solution(A)

that, given a non-empty array A, returns the value of the maximal product of any triplet.

For example, given array A such that:

A[0] = -3 A[1] = 1 A[2] = 2 A[3] = -2 A[4] = 5 A[5] = 6

the function should return 60, as the product of triplet (2, 4, 5) is maximal.

Write an efficient algorithm for the following assumptions:

  • N is an integer within the range [3..100,000];
  • each element of array A is an integer within the range [−1,000..1,000].
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")

def solution(A):
    # write your code in Python 3.6
    A.sort()
    maxi=A[-1]*A[-2]*A[-3]
    temp=A[-1]*A[0]*A[1]
    if temp>maxi:
        maxi=temp
    return maxi

 Test3:

An array A consisting of N integers is given. A triplet (P, Q, R) is triangular if 0 ≤ P < Q < R < N and:

  • A[P] + A[Q] > A[R],
  • A[Q] + A[R] > A[P],
  • A[R] + A[P] > A[Q].

For example, consider array A such that:

A[0] = 10 A[1] = 2 A[2] = 5 A[3] = 1 A[4] = 8 A[5] = 20

Triplet (0, 2, 4) is triangular.

Write a function:

def solution(A)

that, given an array A consisting of N integers, returns 1 if there exists a triangular triplet for this array and returns 0 otherwise.

For example, given array A such that:

A[0] = 10 A[1] = 2 A[2] = 5 A[3] = 1 A[4] = 8 A[5] = 20

the function should return 1, as explained above. Given array A such that:

A[0] = 10 A[1] = 50 A[2] = 5 A[3] = 1

the function should return 0.

Write an efficient algorithm for the following assumptions:

  • N is an integer within the range [0..100,000];
  • each element of array A is an integer within the range [−2,147,483,648..2,147,483,647].

 最终得分93%,有一个timeout,懒得改了就这样吧。

# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")

def solution(A):
    # write your code in Python 3.6
    A.sort()
    N=len(A)
    #print(A,N)
    if N<=2:
        return 0
    B=[]
    for k in range(N):
        if A[k]>0:
            break
    for i in range(k,N):
        B.append(A[i])
    N=len(B)
    #print(B)
    if N<=2:
        return 0    
    for i in range(N-2):
        for j in range(i+1,N-1):
            k=N-1
            #print("j=",j)
            while k>j and B[k]-B[j]>B[i]:
                k=k-1
                #print("k=",k,"B[k]-B[j]=",B[k]-B[j],"B[i]=",B[i])
            if k>j and B[k]-B[j]<B[i]:
                return 1
    return 0

第二天:决定还是改一下,想想k是不用循环的,因为B[i]和B[j]之和能超过B[j+1]就行

# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
 
def solution(A):
    # write your code in Python 3.6
    A.sort()
    N=len(A)
    #print(A,N)
    if N<=2:
        return 0
    B=[]
    for k in range(N):
        if A[k]>0:
            break
    for i in range(k,N):
        B.append(A[i])
    N=len(B)
    #print(B)
    if N<=2:
        return 0    
    for i in range(N-2):
        for j in range(i+1,N-1):
            k=j+1
            if k<N and B[k]-B[j]<B[i]:
                return 1
    return 0

Task4:

We draw N discs on a plane. The discs are numbered from 0 to N − 1. An array A of N non-negative integers, specifying the radiuses of the discs, is given. The J-th disc is drawn with its center at (J, 0) and radius A[J].

We say that the J-th disc and K-th disc intersect if J ≠ K and the J-th and K-th discs have at least one common point (assuming that the discs contain their borders).

The figure below shows discs drawn for N = 6 and A as follows:

A[0] = 1 A[1] = 5 A[2] = 2 A[3] = 1 A[4] = 4 A[5] = 0

There are eleven (unordered) pairs of discs that intersect, namely:

  • discs 1 and 4 intersect, and both intersect with all the other discs;
  • disc 2 also intersects with discs 0 and 3.

Write a function:

def solution(A)

that, given an array A describing N discs as explained above, returns the number of (unordered) pairs of intersecting discs. The function should return −1 if the number of intersecting pairs exceeds 10,000,000.

Given array A shown above, the function should return 11, as explained above.

Write an efficient algorithm for the following assumptions:

  • N is an integer within the range [0..100,000];
  • each element of array A is an integer within the range [0..2,147,483,647].

 啊时间又太长了O(n^2)……改吧

# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")

def solution(A):
    # write your code in Python 3.6
    count=0
    N=len(A)
    if N<=1:
        return 0
    for i in range(N-1):
        if A[i]<0:
            print("ERROR")
            return 0
        for j in range(i+1,N):
            if A[j]<0:
                print("ERROR")
                return 0
            if A[j]+A[i]>=j-i:
                count=count+1
            if count >10000000:
                return -1
    return count

 两个多小时终于搞出来了……但是大数字总是不对啊啊啊啊啊啊啊!!睡醒了再看。留下75%的泪水

class interval():
    def __init__(self,a,b):
        self.ini=a
        self.end=b
def comp(a):
    return a.ini
def binary_search(B,i,N,x):#左右均不包含
    #print("i=",i,"N=",N,"x=",x)
    if i>=N:
        print("ERROR!")
        return -1
    if i<N:
        mid=(i+N)//2
        #print("mid=",mid)
        if B[mid].ini==x:
            #print("==")
            return mid
        elif B[mid].ini>x:
            #print(">")
            return binary_search(B,i,mid,x)
        else:#B[mid].ini<x
            #print("<")
            if B[mid+1].ini>x:
                return mid
            return binary_search(B,mid,N,x)
    
def solution(A):
    # write your code in Python 3.6
    B=[]
    N=len(A)
    for i in range(N):
        inv = interval(i-A[i],i+A[i])
        B.append(inv)
    B.sort(key=comp)#首先按照起始点升序排列好
#     for i in range(N):
#         print("i=",i,B[i].ini,B[i].end)
    count=0#初始没有点
    for i in range(N-1):
        ie=B[i].end
        #print("when i=",i)
        if ie>=B[N-1].ini:
            loc=N-1
        else:
            loc=binary_search(B,i,N,ie)
        if loc>i:
            count=count+(loc-i)
            #print("when i=",i,"loc=",loc,"add=",loc-i,"count=",count)
    return count

找熊哥帮我看了一下代码,发现处理多个圆左端点在同一位置的地方有问题,这期间又写了一个class版本

# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
class Solution:
    def findFarestCircle(self,B,i,N):
        cookie = N-1
        ie=B[i].end
        while cookie > i:
            if B[cookie].ini > ie:
                cookie=cookie-1
            else:
                break
        return cookie
def comp(a):
    return a.ini
class interval():
    def __init__(self,a,b):
        self.ini=a-b
        self.index=a
        self.end=a+b
def solution(A):
    # write your code in Python 3.6
    B=[]
    N=len(A)
    for i in range(N):
        inv = interval(i,A[i])
        B.append(inv)
    B.sort(key=comp)
    S = Solution()
    count=0
    for i in range(N):
        result=0
        cookie=S.findFarestCircle(B,i,N)
        if cookie>=(i+1):
            result=(cookie-i)
        count = count + result
        if count>10000000:
            return -1
    return count

但是很可惜,这个方法的复杂度也是O(n^2)的,因此还是需要用Binary search优化……改了优化条件!

class interval():
    def __init__(self,a,b):
        self.ini=a
        self.end=b
        
def comp(a):
    return a.ini

def binary_search(B,i,N,x):#左右均不包含
    #print("i=",i,"N=",N,"x=",x)
    if i>=N:
        print("ERROR!")
        return -1
    if i<N:
        mid=(i+N)//2
        #print("mid=",mid)
        if B[mid].ini>x:
            #print(">")
            return binary_search(B,i,mid,x)
        elif B[mid].ini<=x:
            #print("<")
            if B[mid+1].ini>x:
                return mid
#             elif mid+1==N-1:
#                 return mid
            return binary_search(B,mid+1,N,x)
    
def solution(A):
    # write your code in Python 3.6
    B=[]
    N=len(A)
    for i in range(N):
        inv = interval(i-A[i],i+A[i])
        B.append(inv)
#     for i in range(N):
#         print("ii=",i,B[i].ini,B[i].end)
    count=0#初始没有点
    B.sort(key=comp)#首先按照起始点升序排列好
#     for i in range(N):
#         print("i=",i,B[i].ini,B[i].end)
    count=0#初始没有点
    for i in range(N-1):
        ie=B[i].end
        #print("when ii=",i)#从第1个B[0]一直做到倒数第二个B[N-2]
        if ie>=B[N-1].ini:
            loc=N-1#N-1的初始包含在内
        else:
            loc=binary_search(B,i,N,ie)#左右均不包含,输出包含在内的最大i值
        if loc>i:
            count=count+(loc-i)
            #print("when i=",i,"loc=",loc,"add=",loc-i,"count=",count)
            if count>10000000:
                return -1
    return count

最终满分通过哈哈哈哈哈哈哈哈

以上是关于[Codility]LESSON6的主要内容,如果未能解决你的问题,请参考以下文章

升序数据中找到二元组为固定之和

自测之Lesson6:低级I/O库

重温JavaScript(lesson6):函数

斯坦福《机器学习》Lesson6感想———1函数间隔和几何间隔

关于 Codility 的 HilbertMaze 任务

Codility 任务 TapEquilibrium 正确性仅为 33%