Fondo
Incident es un lenguaje de programación bastante inusual, ya que su lista de tokens no está predeterminada, sino que se infiere de la entrada. Como tal, tokenizar un programa de Incidentes puede ser bastante difícil, especialmente si desea hacerlo de manera eficiente. Esta tarea se trata de hacerlo tú mismo.
La tarea
Su programa recibirá una cadena como entrada. Aquí está el algoritmo que Incident usa para tokenizarlo:
- Identifique todas las cadenas que ocurren como una subcadena de la entrada de exactamente tres maneras (es decir, hay exactamente tres ocurrencias de esa cadena dentro de la entrada).
- Descarte cualquiera de estas cadenas que sean una subcadena de otra cadena (por ejemplo, para la entrada
ababab
, la única cadena restante seríaab
, noa
ob
, porquea
yb
son ambas subcadenas deab
). - Deseche cualquier cadena que se superponga dentro de la entrada. (Por ejemplo,
aaaa
contiene exactamente tres copias deaa
, pero estas copias se superponen en el segundo y tercer caracteres, por lo que se descartarán. Del mismo modo, enabababa
, hay tres copias deab
y tres copias deba
, pero los caracteres del segundo al sexto están en el la superposición de unaab
yba
, por lo tantoab
, yba
serían descartados). - Las cadenas que quedan en este punto son los tokens utilizados por el programa. Tokenice la entrada original en una secuencia de estos tokens (debido al descarte en el paso anterior, solo habrá una forma de hacerlo). Los caracteres de la entrada que no forman parte de ningún token se tratan como comentarios y se descartan.
Su programa tiene que tomar una cadena como entrada y devolver la tokenización correspondiente de la cadena (una lista de tokens, cada uno de los cuales se expresa como cadenas) como salida. Además, esto debe hacerse al menos de manera moderadamente eficiente; específicamente, el programa tiene que ejecutarse en tiempo cuadrático ("O (n²)") o mejor. (Por cierto, es casi seguro que sea posible ir más rápido que el cuadrático, pero este no es el algoritmo más rápido , así que siéntase libre de usar el algoritmo más exhaustivo que pueda encontrar que se ajuste a los límites de complejidad).
Aclaraciones
- Aunque los programas de incidentes pueden contener, en teoría, cualquiera de los 256 octetos, es aceptable para este desafío que su programa maneje solo entradas formadas de ASCII imprimible (incluyendo espacio), además de nueva línea y tabulación. (Todos los programas de incidentes conocidos se limitan a este subconjunto). Tenga en cuenta que space / newline / tab no son especiales y pueden aparecer en medio de tokens; El incidente trata los 256 octetos como opacos.
- La definición de "tiempo cuadrático" es "si el tamaño de la entrada se duplica, el programa se ejecutará más lentamente en no más de una constante más un factor de 4", es decir, si t ( x ) es el tiempo máximo que tarda su programa en procesar una entrada de tamaño x , entonces debe haber alguna constante k tal que t (2 x ) <4 t ( x ) + k para todo x . Tenga en cuenta que comparar cadenas requiere un tiempo proporcional a la longitud de las cadenas.
- Teóricamente, su programa debería ser capaz de manejar programas de entrada de cualquier longitud si se ejecuta en una variante (posiblemente hipotética) de su idioma que tiene memoria ilimitada y utiliza enteros ilimitados (está bien si el programa no logra este objetivo cuando se ejecuta en la práctica debido a los enteros o la memoria del lenguaje en realidad son finitamente grandes). Puede suponer (con el propósito de calcular la complejidad) que los enteros que no son mayores que la longitud de la entrada se pueden comparar en tiempo constante (aunque tenga en cuenta que si usa valores más grandes, por ejemplo, debido a la conversión de la entrada en un entero único, tomarán un tiempo para comparar proporcionalmente al número de dígitos que tienen).
- Puede usar cualquier algoritmo que se ajuste a los límites de complejidad, incluso si no sigue los mismos pasos que el algoritmo publicado anteriormente, siempre que produzca los mismos resultados.
- Este rompecabezas se trata de tokenizar la entrada, no se trata de formatear la salida. Si la forma más natural de generar una lista en su idioma implica un formato ambiguo (por ejemplo, separado por una nueva línea cuando las cadenas contienen nuevas líneas literales, o sin delimitadores entre las cadenas), no se preocupe por el hecho de que la salida termina siendo ambigua ( siempre y cuando la lista esté realmente construida). Es posible que desee hacer una segunda versión de su envío que produzca resultados inequívocos, para ayudar en las pruebas, pero la versión original es la versión que cuenta para la puntuación.
Caso de prueba
Para la siguiente cadena de entrada:
aaabcbcbcdefdfefedghijghighjkllkklmmmmonono-nonppqpq-pqprsrsrstststuvuvu
su programa debe producir la siguiente lista de resultados:
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
Condición de victoria
Este es el código de golf , por lo que gana el programa válido más corto (es decir, el comportamiento correcto de entrada / salida y lo suficientemente rápido para ejecutarse), medido en bytes.