Contexte
Incident est un langage de programmation assez inhabituel, dans la mesure où sa liste de jetons n'est pas prédéterminée, mais plutôt déduite de l'entrée. En tant que tel, la tokenisation d'un programme Incident peut être assez difficile, surtout si vous voulez le faire efficacement. Cette tâche consiste à le faire vous-même.
La tâche
Votre programme recevra une chaîne en entrée. Voici l'algorithme utilisé par Incident pour le tokeniser:
- Identifiez toutes les chaînes qui se produisent en tant que sous-chaîne de l'entrée de trois manières exactement (c'est-à-dire qu'il y a exactement trois occurrences de cette chaîne dans l'entrée).
- Supprimez l'une de ces chaînes qui sont une sous-chaîne d'une autre chaîne de ce type (par exemple, pour l'entrée
ababab
, la seule chaîne restante seraitab
, nona
oub
, cara
etb
sont les deux sous-chaînes deab
). - Ignorez toutes les chaînes qui se chevauchent dans l'entrée. (Par exemple,
aaaa
contient exactement trois copies deaa
, mais ces copies se chevauchent aux deuxième et troisième caractères, elles seront donc supprimées. De même, dansabababa
, il y a trois copies deab
et trois copies deba
, mais les deuxième à sixième caractères se trouvent chacun au chevauchement de anab
et aba
, donc les deuxab
etba
seraient rejetés). - Toutes les chaînes qui restent à ce stade sont les jetons utilisés par le programme. Tokenisez l'entrée d'origine dans une séquence de ces jetons (en raison de la suppression à l'étape précédente, il n'y aura qu'une seule façon de le faire). Tous les caractères de l'entrée qui ne font partie d'aucun jeton sont traités comme des commentaires et supprimés.
Votre programme doit prendre une chaîne en entrée et renvoyer la tokenisation correspondante de la chaîne (une liste de jetons, chacun étant exprimé sous forme de chaînes) en sortie. De plus, cela doit être fait au moins modérément efficacement; en particulier, le programme doit fonctionner en temps quadratique ("O (n²)") ou mieux. (Par ailleurs, il est presque certainement possible d'aller plus vite que quadratique, mais ce n'est pas l' algorithme le plus rapide , alors n'hésitez pas à utiliser l'algorithme le plus ters que vous pouvez trouver qui correspond aux limites de la complexité.)
Clarifications
- Bien que les programmes d'incident puissent en théorie contenir n'importe lequel des 256 octets, il est acceptable dans le cadre de ce défi que votre programme ne gère que les entrées formées en ASCII imprimable (y compris l'espace), plus la nouvelle ligne et l'onglet. (Tous les programmes d'incident connus se limitent à ce sous-ensemble). Notez que l'espace / nouvelle ligne / tabulation n'est pas spécial et peut apparaître au milieu des jetons; L'incident traite les 256 octets comme opaques.
- La définition du "temps quadratique" est "si la taille de l'entrée est doublée, le programme fonctionnera plus lentement d'une constante plus un facteur de 4", c'est-à-dire si t ( x ) est le temps maximum que prend votre programme pour traiter une entrée de taille x , alors il doit y avoir une constante k telle que t (2 x ) <4 t ( x ) + k pour tout x . Gardez à l'esprit que la comparaison des chaînes prend du temps proportionnel à la longueur des chaînes.
- Votre programme devrait théoriquement être capable de gérer des programmes d'entrée de n'importe quelle longueur s'il est exécuté dans une variante (éventuellement hypothétique) de votre langue qui a une mémoire illimitée et utilise des nombres entiers illimités (c'est OK si le programme ne parvient pas à atteindre cet objectif lorsqu'il est exécuté dans la pratique en raison de les entiers ou la mémoire du langage étant en fait finement grands). Vous pouvez supposer (aux fins du calcul de la complexité) que les entiers qui ne dépassent pas la longueur de l'entrée peuvent être comparés en temps constant (bien que gardez à l'esprit que si vous utilisez des valeurs plus grandes, par exemple en raison de la conversion de l'entrée en un entier unique, ils mettront un certain temps à comparer proportionnellement au nombre de chiffres dont ils disposent).
- Vous pouvez utiliser n'importe quel algorithme qui respecte les limites de la complexité, même s'il ne suit pas les mêmes étapes que l'algorithme publié ci-dessus, tant qu'il produit les mêmes résultats.
- Ce puzzle consiste à tokeniser l'entrée, pas vraiment à formater la sortie. Si le moyen le plus naturel de produire une liste dans votre langue implique un format ambigu (par exemple, séparé par des sauts de ligne lorsque les chaînes contiennent des sauts de ligne littéraux, ou sans délimiteurs entre les chaînes), ne vous inquiétez pas du fait que la sortie finit par être ambiguë ( tant que la liste est réellement construite). Vous souhaiterez peut-être créer une deuxième version de votre soumission qui produira une sortie sans ambiguïté, pour faciliter les tests, mais la version d'origine est la version qui compte pour la notation.
Cas de test
Pour la chaîne d'entrée suivante:
aaabcbcbcdefdfefedghijghighjkllkklmmmmonono-nonppqpq-pqprsrsrstststuvuvu
votre programme devrait produire la liste de sortie suivante:
a a a bc bc bc d e f d f e f e d gh gh gh k l l k k l pq pq pq u u u
Condition de victoire
Il s'agit de code-golf , donc le programme valide le plus court (c'est-à-dire un comportement d'entrée / sortie correct et suffisamment rapide pour s'exécuter), mesuré en octets, gagne.