Se uma string T de comprimento K aparecer K ou mais vezes em uma string S , é potencialmente comunista . Por exemplo, 10
in 10/10
é potencialmente comunista, pois aparece 2 vezes e tem comprimento 2 . Observe que essas substrings não podem se sobrepor.
A transformação comunista é aquele que leva esta cadeia T e move cada personagem t i de T ao i ocorrência de T em S . Assim, no exemplo anterior, a transformação comunista renderia 1/0
; o primeiro caractere de 10
substitui 10
a primeira vez que 10
é encontrada e 0
a segunda vez.
Uma normalização comunista é uma função que pega todas essas cordas T com K ≥ 2 e executa uma transformação comunista nelas.
Algumas especificidades do algoritmo:
- Executar transformações comunistas na maior cadeias válidas T primeiros . Favorecer as primeiras ocorrências de t .
- Em seguida, execute transformações comunistas nas próximas seqüências mais longas, depois na próxima sequência mais longa ... etc.
- Repita até que essas cadeias não existam na cadeia.
Observe que algumas seqüências de caracteres, como o exemplo "Olá, Olá" nos casos de teste, podem ser interpretadas de duas maneiras diferentes. Você pode usar ell
para T , mas também pode usar llo
. Nesse caso, seu código pode escolher uma das opções. O caso de teste mostrado usa llo
, mas você pode obter uma saída diferente e igualmente válida.
Sua tarefa é implementar a normalização comunista. A entrada será sempre composta apenas por caracteres ASCII imprimíveis (0x20 a 0x7E, espaço para til). Você pode escrever um programa ou função para resolver esta tarefa; a entrada pode ser tomada como uma linha de STDIN, argumento de cadeia de caracteres / caracteres, argumento de ARGV, etc.
Casos de teste
'123' -> '123'
'111' -> '111'
'1111' -> '11'
'ABAB' -> 'AB'
'111111111' -> '111'
'asdasdasd' -> 'asd'
'10/10' -> '1/0'
'100/100+100' -> '1/0+0'
' + + ' -> ' + '
'Hello, hello, dear fellow!' -> 'Hel he, dear feow!' OR 'Heo hl, dear flow!'
'11122333/11122333/11122333' -> '112/13' OR '132/23'
'ababab1ababab' -> 'a1bab'
'1ab2ab3ab4ab5ab6' -> '1a2b3a4b5ab6'
Caso de teste elaborado
O formato é 'string', 'substring'
, em cada etapa da substituição. Os bits substituídos estão entre colchetes.
'11[122]333/11[122]333/11[122]333', '122'
'111[333]/112[333]/112[333]', '333'
'1113/11[23]/11[23]', '23'
'11[13]/112/1[13]', '13'
'1[11]/[11]2/13', '11'
'1[/1]12[/1]3', '/1'
'112/13', ''
Outro caso de teste:
'Hello, hello, dear fellow!', 'llo'
'Hel, hel, dear feow!', 'l,'
'Hel he, dear feow!', ''
Código de referência (Python)
Você pode achar isso útil para visualizar o algoritmo.
#!/usr/bin/env python
import re
def repeater(string):
def repeating_substring(substring):
return (string.count(substring) == len(substring)) and string.count(substring) > 1
return repeating_substring
def get_substrings(string):
j = 1
a = set()
while True:
for i in range(len(string) - j+1):
a.add(string[i:i+j])
if j == len(string):
break
j += 1
return list(a)
def replace_each_instance(string, substring):
assert `string`+',', `substring`
for i in substring:
string = re.sub(re.escape(substring), i, string, 1)
return string
def main(s):
repeats = repeater(s)
repeating_substr = filter(repeater(s), get_substrings(s))
while repeating_substr:
repeating_substr.sort(lambda x,y: cmp(len(y), len(x)))
s = replace_each_instance(s, repeating_substr[0])
repeating_substr = filter(repeater(s), get_substrings(s))
return s
assert main('123') == '123'
assert main('111') == '111'
assert main('1111') == '11'
assert main('ABAB') == 'AB'
assert main('111111111') == '111'
assert main('asdasdasd') == 'asd'
assert main('10/10') == '1/0'
assert main('100/100+100') == '1/0+0'
assert main(' + + ') == ' + '
assert main('Hello, hello, dear fellow!') == 'Hel he, dear feow!'
assert main('11122333/11122333/11122333') == '112/13'
Agradecemos a @ ConorO'Brien por postar a ideia original deste desafio.
ababab1ababab
,1ab2ab3ab4ab5ab6
ab
ocorre pelo menos duas vezes nas duas cadeias.Respostas:
Pitão, 22 bytes
Suíte de teste
Para realmente ver o que o programa está fazendo, confira o seguinte:
Internals
Em particular, o programa sempre usa a substituição final das substituições mais longas.
Explicação:
fonte
JavaScript (ES6), 121 bytes
Corresponde recursivamente ao padrão:
... até que o padrão não seja encontrado. (Isso garante que a cadeia mais longa seja tratada primeiro.)
Em seguida, ele realiza as "transformações comunistas" no último padrão encontrado, dividindo a partida e juntando-se a cada um dos personagens da partida. (
map
é usado para essa finalidade. Penajoin
que não recebe retorno de chamada.)Finalmente, ele se repete nessa nova sequência até que não seja mais comunista .
Casos de teste:
Mostrar snippet de código
fonte
Limpo ,
420... 368 bytesExperimente online!
fonte