A function takes three parameters:
- A list of numbers pertaining to cost of laptops
- A list of string signifying whether the laptop is defective or not, i.e either 'legal' or 'illegal'
- 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 outermoney
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. Socount
can be a local variable to thecalc
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 localmoney
variable of the caller. Again, it is not needed to passmoney
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 doreturn 0
.In the recursive call, you pass
[i:]
, buti
was already processed, so you should slice[i 1:]
.Your recursive call gets a sliced
labels
list, butcost
is not sliced, so the indexi
is no longer well aligned, and by grabbingcost[i]
you are not getting the cost that relates to thei
index in the slicedlabels
list. Instead of slicing, I would therefore suggest that you pass thei
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])