introduction
J'ai déjà créé deux défis où l'idée est de reconstruire un objet en utilisant le moins possible d'opérations de type requête; ce sera le troisième.
La tâche
Vos entrées doivent être une chaîne non vide S
sur l'alphabet abc
et sa longueur, et votre sortie doit l'être S
. Sans aucune restriction, ce serait bien sûr une tâche insignifiante; le hic, c'est que vous n'êtes pas autorisé à accéder S
directement. La seule chose que vous êtes autorisé à faire S
est d'appeler la fonction num_occur(T, S)
, où se T
trouve une autre chaîne, et num_occur
compte le nombre d'occurrences de T
in S
. Les occurrences qui se chevauchent sont comptées comme distinctes, donc num_occur(T, S)
renvoie vraiment le nombre d'indices i
tels que
S[i, i+1, …, i+length(T)-1] == T
Par exemple, num_occur("aba", "cababaababb")
reviendra 3
. Notez également que num_occur(S, S)
cela reviendra 1
. Le résultat de num_occur("", S)
n'est pas défini et vous ne devez pas appeler la fonction sur une chaîne vide.
En bref, vous devez écrire une fonction ou un programme qui prend S
et length(S)
comme entrées, appelle num_occur
des chaînes plus courtes et S
un certain nombre de fois, reconstruit à S
partir de ces informations et les renvoie.
Règles et notation
Votre objectif est d'écrire un programme qui appelle le moins d'appels num_occur
possible. Dans ce référentiel , vous trouverez un fichier appelé abc_strings.txt
. Le fichier contient 100 chaînes, chacune sur sa propre ligne, entre les longueurs 50 et 99. Votre score est le nombre total d'appels vers num_occur
ces entrées , un score plus bas étant meilleur. Votre solution conservera de préférence ce numéro pendant son exécution et l'imprimera à la fin. Les chaînes sont générées en choisissant des lettres uniformément aléatoires parmi abc
; vous êtes autorisé à optimiser pour cette méthode de génération des chaînes, mais pas les chaînes elles-mêmes.
Il n'y a pas de limite de temps, sauf que vous devez exécuter votre solution sur les cas de test avant de la soumettre. Votre solution doit fonctionner pour toute entrée valide S
, pas seulement pour les cas de test.
num_occur
Nous vous encourageons à partager votre mise en œuvre de trop, si vous n'utilisez pas quelqu'un d'autre. Pour démarrer, voici une implémentation 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
la source
S
, ou seulement pour les cas de test?all non-empty strings
quelle que soit la longueur?Réponses:
Javascript,
1432514311 appelsNous commençons avec une chaîne vide et nous reprenons notre chemin de manière récursive en ajoutant une nouvelle lettre à la fin ou au début de la chaîne actuelle alors que nous avons encore au moins une correspondance.
Tous les résultats précédents
numOccur()
sont enregistrés dans l'sym
objet et nous utilisons ces données pour rejeter immédiatement toute nouvelle chaîne qui ne peut éventuellement pas être candidate.EDIT : Parce que nous commençons toujours par
'a'
, nous connaissons toujours le nombre exact dea
dans la chaîne. Nous utilisons ces informations pour terminer le processus plus tôt lorsque nous détectons qu'il nea
manque qu'une séquence de . Correction également de l'expression régulière qui n'était pas valide dans Chrome et IE.Extrait exécutable complet ci-dessous.
Afficher l'extrait de code
la source
Python, 15205 appels
Cette soumission est très probablement sous-optimale, car elle utilise uniquement
num_occur
qu'à vérifier si une chaîne est une sous-chaîne deS
, et elle ne l'utilise jamais pour réellement compter la quantité de sous-chaînes.L'algorithme fonctionne en stockant une chaîne
current
qui est construite pour être égale àS
la fin. Voici toutes les étapes de l'algorithme:Nous fixons
current
égal à''
Parcourez chaque lettre de l'alphabet et procédez comme suit:
2.1. Créez une nouvelle chaîne
current_new
et définissez-la égale àcurrent
suivie de la lettre.2.2. Vérifiez si
current_new
est inclus dansS
en exécutantnum_occur
dessus et voyez si le résultat est supérieur à un.2.3. Si
current_new
est inclus dansS
, ensemblecurrent
àcurrent_new
et revenir à l' étape 2. Sinon, nous allons à la lettre suivante.Si la longueur de
current
est égale à la longueur deS
nous pouvons dire que nous avons terminé. Sinon, nous revenons à l'étape 2, mais modifions l'étape 2.1 pour qu'elle soitcurrent_new
égale à la lettre suivie par à lacurrent
place. Lorsque nous atteignons à nouveau cette étape, nous avons terminé.la source
AppelsPython 2,1495214754Très similaire à la première réponse, mais n'essaie pas les caractères suivants, ce qui entraîne des sous-chaînes impossibles qui:
nous savons
num_occur
qu'ils ne se produisent pas dans la cible (des appels précédents)nous avons déjà utilisé la sous-chaîne plus souvent qu'elle ne se produit selon
num_occur
(ajoutera le comptage des sous-chaînes dans une minute)faitla source
AppelsPython1270512632J'ai utilisé le squelette de la fonction Loovjo. Je n'ai jamais codé en Python, j'avais besoin d'une botte
EDIT:
Code ajouté pour les chaînes de longueur d'un caractère
Code ajouté pour rejeter les modèles déjà appariés
la source