fundo
O incidente é uma linguagem de programação bastante incomum, pois sua lista de tokens não é predeterminada, mas inferida a partir da entrada. Como tal, tokenizar um programa de incidentes pode ser bastante difícil, especialmente se você quiser fazer isso com eficiência. Esta tarefa é sobre fazer você mesmo.
A tarefa
Seu programa receberá uma string como entrada. Aqui está o algoritmo que o Incident usa para tokenizá-lo:
- Identifique todas as strings que ocorrem como uma substring da entrada de exatamente três maneiras (ou seja, existem exatamente três ocorrências dessa string na entrada).
- Descarte qualquer uma dessas cadeias de caracteres que sejam uma subcadeia de outra cadeia de caracteres (por exemplo, para entrada
ababab
, a única cadeia restante seriaab
, nãoa
oub
, porquea
eb
são as duas subseqüências deab
). - Descarte quaisquer seqüências que se sobreponham na entrada. (Por exemplo,
aaaa
contém exatamente três cópias deaa
, mas essas cópias se sobrepõem ao segundo e terceiro caracteres, seria descartada. Da mesma forma, emabababa
, existem três cópiasab
e três cópias deba
, mas o segundo ao sexto caracteres estão cada um no sobreposição de anab
e aba
, então ambosab
eba
seriam descartados). - Quaisquer strings que permanecem nesse momento são os tokens usados pelo programa. Tokenize a entrada original em uma sequência desses tokens (devido ao descarte na etapa anterior, haverá apenas uma maneira de fazê-lo). Quaisquer caracteres na entrada que não façam parte de nenhum token são tratados como comentários e descartados.
Seu programa precisa pegar uma string como entrada e retornar a tokenização correspondente da string (uma lista de tokens, cada um dos quais é expresso como strings) como saída. Além disso, isso deve ser feito pelo menos moderadamente com eficiência; especificamente, o programa deve ser executado em tempo quadrático ("O (n²)") ou melhor. (Aliás, é quase certamente possível ir mais rápido que o quadrático, mas esse não é o algoritmo mais rápido , portanto, sinta-se à vontade para usar o algoritmo tersest que você achar que se encaixa dentro dos limites da complexidade.)
Esclarecimentos
- Embora os programas de incidentes possam, em teoria, conter qualquer um dos 256 octetos, é aceitável, para o objetivo deste desafio, que seu programa manipule apenas entradas formadas em ASCII imprimível (incluindo espaço), além de nova linha e guia. (Todos os programas de incidentes conhecidos se restringem a esse subconjunto). Observe que espaço / nova linha / guia não são especiais e podem aparecer no meio dos tokens; O incidente trata todos os 256 octetos como opacos.
- A definição de "tempo quadrático" é "se o tamanho da entrada for duplicado, o programa será executado mais devagar não mais que uma constante mais um fator de 4", ou seja, se t ( x ) for o tempo máximo que seu programa leva para processar uma entrada de tamanho x , então deve haver alguma constante k tal que t (2 x ) <4 t ( x ) + k para todo x . Lembre-se de que comparar cordas leva um tempo proporcional ao comprimento das cordas.
- Teoricamente, seu programa deve ser capaz de lidar com programas de entrada de qualquer tamanho, se for executado em uma variante (possivelmente hipotética) do seu idioma, com memória ilimitada e usar números inteiros ilimitados (tudo bem se o programa falhar em atingir esse objetivo quando for executado na prática devido a os números inteiros ou a memória do idioma são realmente finitos). Você pode supor (com o objetivo de calcular a complexidade) que números inteiros que não sejam maiores que o comprimento da entrada podem ser comparados em tempo constante (embora tenha em mente que, se você usar valores maiores, por exemplo, devido à conversão da entrada em um inteiro inteiro, eles levarão um tempo para comparar proporcionalmente ao número de dígitos que possuem).
- Você pode usar qualquer algoritmo que se enquadre nos limites da complexidade, mesmo que não siga as mesmas etapas do algoritmo postado acima, desde que produza os mesmos resultados.
- Este quebra-cabeça é sobre tokenizar a entrada, não realmente sobre formatar a saída. Se a maneira mais natural de gerar uma lista em seu idioma envolver um formato ambíguo (por exemplo, separados por novas linhas quando as strings contiverem novas linhas literais ou sem delimitadores entre as strings), não se preocupe com o fato de que a saída acaba sendo ambígua ( desde que a lista seja realmente construída). Convém fazer uma segunda versão do seu envio que produza uma saída inequívoca, para ajudar nos testes, mas a versão original é a que conta para a pontuação.
Caso de teste
Para a seguinte sequência de entrada:
aaabcbcbcdefdfefedghijghighjkllkklmmmmonono-nonppqpq-pqprsrsrstststuvuvu
seu programa deve produzir a seguinte lista de saída:
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
Condição de vitória
Este é o código-golfe , portanto o programa mais curto válido (isto é, comportamento correto de entrada / saída e suficientemente rápido para executar), medido em bytes, vence.