Codility ClavandoTablas – Usando la Búsqueda Binaria en la Cantidad de Clavos en lugar de Tablas
Ya he leído las respuestas a esta pregunta: https://stackoverflow.com/questions/62133735/codility-nailingplanks. Esto no es un duplicado, ya que estoy intentando resolver este problema usando un enfoque diferente, en lugar de ejecutar una búsqueda binaria en las tablas que una uña dada puede cubrir, estoy intentando ejecutarla en el número total de uñas requeridas para cubrir todas las tablas.
Este es mi código:
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
El algoritmo comienza comprobando las primeras len(C) + 1 / 2
uñas en C:
- Primero calcula el valor más pequeño y el valor más grande que las uñas en este rango pueden cubrir (
min_cover
ymax_cover
). - A continuación, revisa A y B, y comprueba si cada tabla puede ser clavada por alguna de las uñas en el rango
(min_cover, max_cover)
. - Si el resultado es
False
, actualizamosmin_nails
para que seamid_nails + 1
y repetimos. Si el resultado esTrue
, almacenamos la cantidad de uñas en el arrayvalid
e intentamos encontrar una cantidad menor de uñas que también funcionaría, estableciendomax_nails = mid_nails - 1
.
Este enfoque tiene una precisión del 100%, sin embargo, falla en las pruebas de rendimiento porque produce resultados incorrectos: para cada una de las pruebas de rendimiento, el número mínimo de uñas obtenido es mucho menor que el resultado esperado. Sospecho que el error está en esta línea: 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))
pero no puedo averiguar cuál es.
davy.ai
Posibles mejoras al código podrían ser:
candidates
en la funciónis_valid_nails_amount
. Esto permitiría realizar pruebas de pertenencia más rápidas, lo cual podría mejorar el rendimiento.range
, como por ejemplo bisect, para encontrar la intersección entre el rango de un clavo y el rango de un tablón. Esto podría mejorar el rendimiento, especialmente para tamaños de entrada grandes.En cuanto al presunto error en la función
is_valid_nails_amount
, es posible que las comprobaciones de rango no sean correctas en todos los casos. Una forma de probar esto sería añadir algunas impresiones de depuración al código e intentar aislar los casos en los que la función produce resultados incorrectos. Por ejemplo, imprimir los valores dea
,b
,min_cover
ymax_cover
para cada combinación tablón-clavo podría ayudar a identificar discrepancias. Otra aproximación podría ser probar algunos casos límite o casos especiales que podrían provocar un comportamiento inesperado, como por ejemplo casos en los que A o B sean arreglos vacíos, o casos en los que todos los tablones tengan la misma longitud.