I have already read through the answers on this question - Codility NailingPlanks. This is not a duplicate, as I'm trying to solve this problem using a different approach - instead of running a binary search on the planks that a given nail can cover, I'm trying to run it on the total number of nails required to cover all the planks.
This is my code:
def solution(A, B, C):
min_nails = 1
max_nails = len(C)
valid = []
while (min_nails <= max_nails):
mid_nails = (min_nails + max_nails) // 2
if (is_valid_nails_amount(mid_nails,A,B,C)):
max_nails = mid_nails - 1
valid.append(mid_nails)
else:
min_nails = mid_nails + 1
return -1 if len(valid) == 0 else min(valid)
def is_valid_nails_amount(nails,A,B,C):
candidates=C[0:nails]
min_cover = min(candidates)
max_cover = max(candidates)
isValid = True
for (a,b) in zip(A,B):
if not(min_cover in range(a, b + 1) or max_cover in range(a, b + 1) or a in range(min_cover, max_cover + 1) or b in range(min_cover, max_cover + 1)):
isValid = False
break
return isValid
The algorithm begins by checking the first len(C) + 1 / 2
nails in C:
min_cover
and max_cover
).(min_cover, max_cover)
.False
, we update min_nails
to be mid_nails + 1
and repeat. If the result is True
, we store the number of nails in the valid
array, and attempt to find a smaller amount of nails which would also work, by setting max_nails = mid_nails - 1
This approach scores 100% correctness, however fails on the performance tests because it produces incorrect results - for each of the performance tests, the minimum number of nails obtained is much lower than the expected result. I suspect the error would be in this line: if not(min_cover in range(a, b + 1) or max_cover in range(a, b + 1) or a in range(min_cover, max_cover + 1) or b in range(min_cover, max_cover + 1))
but I can't figure out what it is.
The problem with your if
condition can be seen with this sample input:
A = [1,3,5]
B = [2,4,6]
C = [1,5,3]
print(solution(A, B, C))
This will print 2, but the expected output is 3, as all three nails are needed.
Yet, your code will have is_valid_nails_amount(2, A, B, C)
return True
, despite the fact that the second plank is not nailed by those two nails.
The problem is that neither of these conditions guarantees that a nail hits the plank (a, b)
:
a in range(min_cover, max_cover + 1)
b in range(min_cover, max_cover + 1)
Your algorithm really needs to check if there is a nail in that min/max range that is available for hitting the plank.