Normalizzazione del sottostring comunistico


13

Se una stringa T di lunghezza K appare K o più volte in una stringa S , allora è potenzialmente comunista . Ad esempio, 10in 10/10è potenzialmente comunista, poiché appare 2 volte ed è di lunghezza 2 . Si noti che queste sottostringhe non possono sovrapporsi.

Una trasformazione communistic è uno che richiede questa stringa T e sposta ogni carattere t i del T alla i presenza di T in S . Quindi, per l'esempio precedente, la trasformazione comunista avrebbe ceduto 1/0; viene trovato il primo carattere di 10sostituisce 10la prima volta 10e 0la seconda volta.

Una normalizzazione comunista è una funzione che prende tutte queste stringhe T con K ≥ 2 ed esegue una trasformazione comunista su di esse.

Alcuni dettagli sull'algoritmo:

  1. Eseguire trasformazioni comunisti sulla più lunga stringhe valide T prime . Favorire le prime occorrenze di T .
  2. Quindi, esegui trasformazioni comuniste sulle stringhe successive più lunghe, quindi sulla successiva successiva più lunga ... ecc.
  3. Ripetere fino a quando tali stringhe non esistono nella stringa.

Si noti che alcune stringhe, come l'esempio "Hello, Hello" nei casi di test, possono essere interpretate in due modi diversi. Puoi usare ellper T , ma puoi anche usare llo. In questo caso, il tuo codice può scegliere entrambe le opzioni. Viene utilizzato il caso di test mostrato llo, ma è possibile ottenere un output diverso e ugualmente valido.


Il tuo compito è implementare la normalizzazione comunista. L'input sarà sempre e solo composto da caratteri ASCII stampabili (da 0x20 a 0x7E, da spazio a tilde). È possibile scrivere un programma o una funzione per risolvere questo compito; l'input può essere preso come una riga da STDIN, argomento array stringa / carattere, argomento da ARGV, ecc.

Casi test

'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 di prova risolto

Il formato è 'string', 'substring', ad ogni passaggio della sostituzione. I bit sostituiti sono tra parentesi.

'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', ''

Un altro caso di test:

'Hello, hello, dear fellow!', 'llo'
'Hel, hel, dear feow!', 'l,'
'Hel he, dear feow!', ''

Codice di riferimento (Python)

Potrebbe essere utile per visualizzare l'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'

Grazie a @ ConorO'Brien per aver pubblicato l'idea originale di questa sfida.


Casi di test: ababab1ababab,1ab2ab3ab4ab5ab6
Zgarb

Perché non ci sono cambiamenti? absi verifica almeno due volte in entrambe le stringhe.
Zgarb,

@Zgarb sembra che il mio tester sia difettoso, lo riparerò più tardi. Risolvere manualmente i casi di test.
Rɪᴋᴇʀ

Risposte:


2

Pyth, 22 byte

u.xse.iLcGdf>cGTlTt#.:

Suite di test

Per vedere effettivamente cosa sta facendo il programma, dai un'occhiata a questo:

Interni

In particolare, il programma utilizza sempre la sostituzione finale delle sostituzioni più lunghe.

Spiegazione:

u.xse.iLcGdf>cGTlTt#.:
u.xse.iLcGdf>cGTlTt#.:G)GQ    Implicit
u                        Q    Starting with the input, repeat the following
                              until a fixed point is reached.
                    .:G)      Construct all substrings of the current value
                              ordered smallest to largest, front to back.
                  t#          Filter on having more than 1 element.
                              These are the eligible substrings.
           f                  Filter these substrings on
             cGT              Chop the current value on the substring,
            >   lT            Then remove the first len(substring) pieces.
                              The result is nonempty if the substring is
                              one we're looking for. 
                              Chopping gives nonoverlapping occurrences.
     .iL                      Interlace the substrings with
        cGd                   Chop the current value on that substring
   se                         Take the final result, make it a string.
 .x                     G     If there weren't any, the above throws an error,
                              So keep the current value to halt.

4

JavaScript (ES6), 121 byte

f=(s,j=2,o,m=s.match(`(.{${j}})(.*\\1){${(j-1)}}`))=>m?f(s,j+1,s.split(m[1]).map((e,i)=>e+(m[1][i]||'')).join``):o?f(o):s

Corrisponde in modo ricorsivo al modello:

(.{2})(.*\1){1}  //2 characters, repeated 1 time 
(.{3})(.*\1){2}  //3 characters, repeated 2 times 
(.{4})(.*\1){3}  //4 characters, repeated 3 times 
etc.

... fino a quando il modello non viene trovato. (Ciò garantisce che venga gestita per prima la stringa più lunga.)

Esegue quindi le "trasformazioni comuniste" sull'ultimo modello trovato, dividendosi sulla partita e unendosi a ciascuno dei personaggi della partita. ( mapviene utilizzato per questo scopo. Peccato che joinnon venga richiamato.)

Alla fine ricorre su questa nuova stringa fino a quando non è più comunista .

Casi test:


1

Pulito , 420 ... 368 byte

import StdEnv,StdLib
l=length
%q=any((==)q)
?_[]=[]
?a[(y,x):b]|isPrefixOf a[x:map snd b]=[y: ?a(drop(l a-1)b)]= ?a b
$s=sortBy(\a b=l a>l b)(flatten[[b: $a]\\(a,b)<-map((flip splitAt)s)[0..l s-1]])
f s#i=zip2[0..]s
#r=filter(\b=l(?b i)>=l b&&l b>1)($s)
|r>[]#h=hd r
#t=take(l h)(?h i)
=f[if(%n t)(h!!hd(elemIndices n t))c\\(n,c)<-i|not(%n[u+v\\u<-t,v<-[1..l h-1]])]=s

Provalo online!


Questa risposta non è valida Vedere qui. Questo dovrebbe essere cambiato, vedere i casi di test.
Rɪᴋᴇʀ

@Riker interessante, dal momento che è una porta diretta della soluzione di riferimento. Eliminerò fino a quando non verrà risolto.
Οuroso

@Riker risolto ora.
Οuroso
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.