Home > Back-end >  Traversing two lists with two checks
Traversing two lists with two checks

Time:10-27

A function takes three parameters:

  1. A list of numbers pertaining to cost of laptops
  2. A list of string signifying whether the laptop is defective or not, i.e either 'legal' or 'illegal'
  3. An integer signifying number of laptops to be produced in a day.

So if input is something like:

cost = [1,3,2,5,4,1]
labels = ['legal', 'illegal', 'legal', 'legal', 'legal', 'legal']
dailyCount = 2

The output has to be the total max cost incurred therefore for the first day the cost =(1 3 2) i.e 6. We count the cost for illegal item too. The second day gets the next two entries, so cost= (5 4) i.e 9. Next entry(last remaining) is not enough for the daily count so we leave that. Hence total max cost incurred is 6 9 = 15. Which the function returns. This is how far I have gotten after many hours:

    def maxCost(cost, labels, dailyCount):
        count = 0 #counts the number of legal laptops made
        money = 0 #counts daily cost incurred
    
        def calc(labels, count, money):
            if len(labels) > 0:
                for i in range(len(labels)):
                    money  = cost[i]
                    if labels[i] == 'legal':
                        count  = 1
                    if count == dailyCount:
                        calc(labels[i:], 0, money)
            return money
        
        res = calc(labels,count,money)
        return res
cost = [1,2,4,3]
labels = ['legal','illegal','legal','legal']
dailyCount = 2
print(maxCost(cost, labels, dailyCount))

The output should be 5. But it is showing 10 i don't know how?

CodePudding user response:

Issues:

  • The recursive call (if it would be made) returns a money amount, but you ignore that value as you do not assign it to anything.

  • Your code seems to suggest you think that parameters are (sometimes) references to the caller's variables, and that a change to -- let's say -- money will impact the outer money variable, but that is not true. All arguments are passed to local variables, and any assignment to those is not reflected in the variable that was passed as argument.

  • count should be reset to 0 every time you have reached a full day's worth. So count can be a local variable to the calc function. It should not be defined elsewhere, nor be passed as argument (anyway you always pass 0, so that is not very useful).

  • Currently money does not accumulate over the different days. To accumulate, use the return value and add it to a local money variable of the caller. Again, it is not needed to pass money as an argument. Let every call return the money that applies to its case, and let the caller add its own day worth to that.

  • There is no check that you have attained the full amount of laptops in the last day. If not, the already accumulated money should be ignored. So it would be good to immediately return after the recursive call. If then the for loop exits without having done that new return, then we know the count of produced laptops was not enough, and we should do return 0.

  • In the recursive call, you pass [i:], but i was already processed, so you should slice [i 1:].

  • Your recursive call gets a sliced labels list, but cost is not sliced, so the index i is no longer well aligned, and by grabbing cost[i] you are not getting the cost that relates to the i index in the sliced labels list. Instead of slicing, I would therefore suggest that you pass the i index (i 1)

  • The correct output for the last code example should not be 5 either: it should be 7, since the "illegal" cost for the second laptop should be accounted for.

It is a bit overkill to solve this with recursion, but I'll leave that in place in this version:

def maxCost(cost, labels, dailyCount):
    def calc(start):
        count = 0
        money = 0
        if len(labels) > 0:
            for i in range(start, len(labels)):
                money  = cost[i]
                if labels[i] == 'legal':
                    count  = 1
                if count == dailyCount:
                    return money   calc(i 1)
        return 0 # not enough labels
    
    res = calc(0)
    return res

As an alternative, here is a solution that first counts the number of legal laptops, then derives how many should be produced (must be multiple of the daily count), then searches the index of that last legal laptop, and finally sums the costs up to that laptop:

def maxCost(cost, labels, dailyCount):
    numlegals = sum(1 for label in labels if label == 'legal')

    # truncate to a multiple of dailyCount
    numlegals -= numlegals % dailyCount
    for i, label in enumerate(labels):
        if label == 'legal':
            numlegals -= 1
            if numlegals == 0:
                return sum(cost[:i 1])
  • Related