Introducción
Anteriormente he creado dos desafíos en los que la idea es reconstruir un objeto utilizando la menor cantidad posible de operaciones de tipo consulta; Este será el tercero.
La tarea
Sus entradas serán una cadena no vacía S
sobre el alfabeto abc
y su longitud, y su salida será S
. Sin restricciones, esto sería, por supuesto, una tarea trivial; El problema es que no se te permite acceder S
directamente. Lo único que puede hacer S
es llamar a la función num_occur(T, S)
, donde T
hay alguna otra cadena, y num_occur
contar el número de ocurrencias de T
in S
. Las ocurrencias superpuestas se cuentan como distintas, por lo que num_occur(T, S)
realmente devuelve el número de índices de i
manera que
S[i, i+1, …, i+length(T)-1] == T
Por ejemplo, num_occur("aba", "cababaababb")
volveremos 3
. Tenga en cuenta también que num_occur(S, S)
volverá 1
. El resultado de num_occur("", S)
no está definido y no debe llamar a la función en una cadena vacía.
En resumen, debe escribir una función o programa que tome S
y length(S)
como entradas, invoque num_occur
algunas cadenas más cortas y S
algunas veces, reconstruya a S
partir de esa información y la devuelva.
Reglas y puntaje
Su objetivo es escribir un programa que haga la menor cantidad de llamadas num_occur
posible. En este repositorio , encontrará un archivo llamado abc_strings.txt
. El archivo contiene 100 cadenas, cada una en su propia línea, entre las longitudes 50 y 99. Su puntaje es el número total de llamadas a num_occur
estas entradas , siendo menor el puntaje menor. Preferiblemente, su solución realizará un seguimiento de este número a medida que se ejecuta e imprimirá al finalizar. Las cadenas se generan al elegir letras aleatoriamente uniformes de abc
; puede optimizar para este método de generación de cadenas, pero no las cadenas en sí.
No hay límite de tiempo, excepto que debe ejecutar su solución en los casos de prueba antes de enviarla. Su solución debería funcionar para cualquier entrada válida S
, no solo para los casos de prueba.
Le recomendamos que también comparta su implementación num_occur
, si no está usando la de otra persona. Para que la pelota ruede, aquí hay una implementación en Python:
def num_occur(needle, haystack):
num = 0
for i in range(len(haystack) - len(needle) + 1):
if haystack[i : i + len(needle)] == needle:
num += 1
return num
fuente
S
, o solo para los casos de prueba?all non-empty strings
de cualquier longitud?Respuestas:
Javascript,
1432514311 llamadasComenzamos con una cadena vacía y seguimos nuestro camino de manera recursiva agregando una nueva letra al final o al comienzo de la cadena actual mientras todavía tenemos al menos una coincidencia.
Todos los resultados anteriores
numOccur()
se guardan en elsym
objeto y usamos estos datos para rechazar inmediatamente cualquier nueva cadena que no pueda ser candidata.EDITAR : Debido a que siempre comenzamos con
'a'
, siempre sabemos el número exacto dea
en la cadena. Utilizamos esta información para finalizar el proceso antes cuando detectamos que soloa
falta una secuencia de . También se corrigió la expresión regular que no era válida en Chrome e IE.Fragmento ejecutable completo a continuación.
Mostrar fragmento de código
fuente
Python, 15205 llamadas
Es muy probable que este envío sea subóptimo, porque solo se usa
num_occur
para verificar si una cadena es una subcadenaS
, y nunca la usa para contar la cantidad de subcadenas.El algoritmo funciona almacenando una cadena
current
que se construye para que sea igual alS
final. Aquí están todos los pasos en el algoritmo:Ponemos
current
igual a''
Revisa cada letra del alfabeto y haz lo siguiente:
2.1. Cree una nueva cadena
current_new
y configúrela igual acurrent
seguida de la letra.2.2. Verifique si
current_new
está incluidoS
ejecutándolonum_occur
y vea si el resultado es mayor que uno.2.3. Si
current_new
se incluye enS
, conjuntocurrent
acurrent_new
y volver al paso 2. Si no, vamos a la siguiente letra.Si la longitud de
current
es igual a la longitud deS
podemos decir que hemos terminado. De lo contrario, volvemos al paso 2, pero modificamos el paso 2.1 para que seacurrent_new
igual a la letra seguida en sucurrent
lugar. Cuando alcanzamos este paso de nuevo, hemos terminado.fuente
Python 2,
1495214754 llamadasMuy similar a la primera respuesta, pero no prueba los siguientes caracteres que resultan en subcadenas imposibles que:
sabemos
num_occur
que no ocurren en el objetivo (de llamadas anteriores)ya usamos la subcadena con más frecuencia de lo que ocurre de acuerdo con
num_occur
(agregará el recuento de subcadenas en un minuto)hechofuente
Python
1270512632 llamadasUsé el esqueleto de la función Loovjo. Nunca codifiqué en Python, necesitaba un arranque
EDITAR:
Código agregado para cadenas de longitud de un carácter
Código agregado para rechazar patrones ya coincidentes
fuente