Codility Challenge

时间:2014-10-25 09:09:32

标签: python arrays algorithm

我正在努力完成编纂挑战,以提高我的编程技能,或者说缺乏编程技能。挑战的细节在这里。

  

在一个房间里有N条绳索和N个重量。每根绳子都连接着   正好一个重量(仅在一端),每根绳子都有一个特殊的重量   耐久性 - 它可以暂停的最大重量。还有一个   挂钩,附在天花板上。绳索可以连接到钩子上   通过绑定没有重量的结束。绳索也可以连接到   其他重量;也就是说,绳索和重物可以连接到一个   链中的另一个。如果连接的重量总和,绳子将断裂   它直接或间接地大于它的耐久性。

     

我们知道我们想要附加N条绳索的顺序。更确切地说,   我们知道绳子的参数(耐久性和重量)和   每个附件的位置。耐久性,重量和位置是   在三个零索引数组A,B,C中给出长度为N.对于每个I(0   ≤I< N):A [I]是第I条绳索的耐久性,B [I]是重量   连接到第I条绳索,C [I](使得C [I]

A= [4,3,1]
B = [2,2,1]
C = [-1,0,1]
     

该功能应该返回2,好像我们连接第三根绳子然后一根绳子会断裂,因为重量总和大于它   耐久性(2 + 2 + 1 = 5和5> 4)。

以下是我尝试的解决方案。我有一个名为add_weights的辅助函数,如果添加最新的绳索不会导致任何其他绳索断裂,则返回True,否则返回false。

def add_weights(A, ancestors, weights, weight, rope):
    #add weight(int) to rope and ancestors
    if (rope == -1):
        return (True)
    else:
        weights[rope] += weight
        if (A[rope] < weights[rope]):
            print "Rope that breaks", rope
            return False
        ancestor = ancestors[rope]
        print ancestor
        add_weights(A, ancestors, weights, weight, ancestor)




def solution(A, B, C):
    # write your code in Python 2.7
    weights = {}
    ancestors = {}
    for i in range(len(B)):
        weights[i] = B[i]
    for i in range(len(C)):
        #attaching rope i to rope x
        x = C[i]
        ancestors[i] = x
        broke = add_weights(A, ancestors, weights, B[i], x)
        if (not broke):
            return i
    return len(C)

问题是在函数解决方案的for循环的第二次迭代期间(当我尝试添加绳索1时),变量break以某种方式评估为None,当我可以清楚地看到add_weights返回True时。我也用调试器对它进行了测试,所以我不完全确定发生了什么。欢迎任何帮助。

4 个答案:

答案 0 :(得分:0)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Exercise5_DurablityofRopes
{
    class Program
    {
           static int[] A_Durability = new int[] { 15, 6, 2,3,1 };
           static int[] B_Weight = new int[] { 2, 1, 2,3,1 };
           static int[] C_Position = new int[] { -1, 0, 1 ,2,3};
           static int no_of_ropes_attached = 0;
           static int maxropeattached = 0;
           static void Main(string[] args)
        {
           // first position cannot necessarily be -1 hence Checking for each position How many maximum ropes can be attached
            for (int i = 0; i <= C_Position.Length - 1; i++)
            {
                int[] Copy_Durability = new int[A_Durability.Length];
                for (int l = 0; l <= C_Position.Length - 1; l++)
                {
                    Copy_Durability[l] = A_Durability[l];
                }
                AddNextRope(i, B_Weight[i], Copy_Durability);          
                Console.WriteLine("Total Number of ropes can be attached to " + C_Position[i] + " ropes are" + no_of_ropes_attached);
                if (no_of_ropes_attached>=maxropeattached)
                {
                    maxropeattached = no_of_ropes_attached;
                }
                no_of_ropes_attached = 0;
            }

            Console.WriteLine("Total Number of ropes can be attached is  " + maxropeattached);
            Console.ReadKey();
        }

        private static void AddNextRope(int currentRopePosition,int newWeight,int[] Durability)
        {
            if (currentRopePosition == C_Position.Length - 1) return;
            // decrease same amount of weight from all ansestors from their durability and check if any of them breaks (durability <0) with new weight added
            for (int k = currentRopePosition; k != 0; k--)
            {
                Durability[k] = Durability[k] - newWeight;
                if(Durability[k]<0)
                {
                    return;
                }
            }
            no_of_ropes_attached = no_of_ropes_attached + 1; 

            for (int i = 0; i <= C_Position.Length - 1; i++)
                {
                    if (C_Position[i] == C_Position[currentRopePosition] + 1)
                    {
                        if (A_Durability[i] > B_Weight[i])
                        {
                            AddNextRope(i, B_Weight[i], Durability);
                        }
                        else
                        {
                            return;
                        }
                    }
                }
        }
    }
}

答案 1 :(得分:0)

我已经完成了一个解决方案,但它不是n(log n),并且它在最后一次线性测试中失败了很多。

def solution(A, B, C):    
  num_ropes = len(C)

  for i in xrange(num_ropes):
    node = i
    while(node != -1):
      A[node] -= B[i]
      if A[node] < 0:
        return i
      node = C[node]
  return num_ropes

可以使用最后一部分进行测试

if __name__ == '__main__':
  A = [5, 3, 6, 3, 3]
  B = [2, 3, 1, 1, 2]
  C = [-1, 0, -1, 0, 3]
  assert solution(A, B, C) == 3

  A = [4, 3, 1]
  B = [2, 2, 1]
  C = [-1, 0, 1]
  assert solution(A, B, C) == 2

答案 2 :(得分:0)

我没有时间将其翻译成Python,但您可以通过查看此JS代码获得一个想法:

function keysOrderedByValues(array) {
    var result = [];
    for (var i = 0; i < array.length; i++) {
        result[array[i] + 1] = i;
    }
    return result;
}

function findFirstPositiveElem(array) {
    for (var i = 0; i < array.length; i++) {
        if (array[i]>0) {
            return i;
        }
    }
    return null;
}

function accumulativeArray(array) {
    var result = [];
    var sum = 0;
    for (var i = 0; i < array.length; i++) {
        sum = sum + array[i];
        result.push(sum);
    }
    return result;
}

Array.prototype.indexedByArray = function(array) {
    result = [];
    for (var i = 0; i < array.length; i++) {
        result.push(this[array[i]])
    }
    return result;
}

function test(ds, ws, ords) {
    return findFirstPositiveElem(ws.indexedByArray(keysOrderedByValues(ords)), ds);
}

console.log(test([4,3,1], [2,2,1], [-1,0,1]))

答案 3 :(得分:-1)

忘记提及:这是O(n)和数组B2的一些空间复杂性

    int Solution (int[]A, int[] B, int[] C)
    {
        if (A==null || B==null || C==null)
            return -1;
        if (A.Length==0 || B.Length==0 || C.Length==0)
            return -1;
        if (A.Length != B.Length && A.Length != C.Length)
            return -1;


        var bLen=B.Count();
        var B2 = new int[bLen];
        for (int i = 0; i < bLen; i++)
            B2[i]=(i==0? 0 : B2[i-1]) + B[i]; //cumulative sum


        var ret=-1;
        var skip=0;
        for (int i = 0; i < A.Length; i++)
        {
            skip=C[i]+1;
            if (A[i] - (B2[bLen-1] - (skip>0 ? B2[skip-1] : 0)) < 0) 
            {
                ret=bLen-skip-1;
                break;
            }
        }
        return ret;
    }