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:
- First it calculates the smallest and largest value that the nails in this range can cover (
min_cover
andmax_cover
). - Next, it looks through A & B, and checks whether each plank can be nailed by any of the nails in the range
(min_cover, max_cover)
. - If the result is
False
, we updatemin_nails
to bemid_nails 1
and repeat. If the result isTrue
, we store the number of nails in thevalid
array, and attempt to find a smaller amount of nails which would also work, by settingmax_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.
CodePudding user response:
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.