Generar el más corto De Bruijn

22

Una secuencia de De Bruijn es interesante: es la secuencia cíclica más corta que contiene todas las secuencias posibles de un alfabeto dado de una longitud dada. Por ejemplo, si consideramos el alfabeto A, B, C y una longitud de 3, una salida posible es:

AAABBBCCCABCACCBBAACBCBABAC

Usted se dará cuenta de que cada posible secuencia de 3 caracteres usando las letras A, By Cestá ahí.

Su desafío es generar una secuencia de De Bruijn en la menor cantidad de personajes posible. Su función debe tomar dos parámetros, un número entero que representa la longitud de las secuencias y una lista que contiene el alfabeto. Su salida debe ser la secuencia en forma de lista.

Puede suponer que cada elemento del alfabeto es distinto.

Un generador de ejemplo se puede encontrar aquí

Se aplican lagunas estándar

Nathan Merrill
fuente
¿Puede el entero que representa la longitud de las secuencias ser mayor que el número de letras únicas?
kukac67
Sí. Una secuencia binaria de longitud 4 sería 0000111101100101
Nathan Merrill el
"Su desafío es generar una secuencia de De Bruijn en la menor cantidad de caracteres posible". ¿Significa esto "código de golf" u "obtener la longitud de secuencia de De Bruijn más corta posible"?
FryAmTheEggman
2
Ambos. Para calificar, su programa debe generar la secuencia más corta posible, pero para ganar, su programa debe ser el más corto.
Nathan Merrill
2
@xem: por lo general, las secuencias de De Bruijn incluyen envoltura, que es donde aparecen esas secuencias faltantes.
Keith Randall

Respuestas:

6

Pyth, 31 bytes

Esta es la conversión directa del algoritmo utilizado en mi respuesta CJam . Consejos para el golf de bienvenida!

Mu?G}H+GG+G>Hefq<HT>G-lGTUH^GHk

Este código define una función gque toma dos argumentos, la cadena de la lista de caracteres y el número.

Ejemplo de uso:

Mu?G}H+GG+G>Hefq<HT>G-lGTUH^GHkg"ABC"3

Salida:

AAABAACABBABCACBACCBBBCBCCC

Expansión de código:

M                 # def g(G,H):
 u                #   return reduce(lambda G, H:
  ?G              #     (G if
    }H            #       (H in
      +GG         #          add(G,G)) else
    +G            #       add(G,
      >H          #         slice_end(H,
        e         #           last_element(
         f        #             Pfilter(lambda T:
          q       #               equal(
           <HT    #                 slice_start(H,T),
           >G     #                 slice_end(G,
             -lGT #                   minus(Plen(G),T))),
          UH      #               urange(H)))))),
  ^GH             #     cartesian_product(G,H),
  k               #     "")

Pruébalo aquí

Optimizador
fuente
4

CJam, 52 49 48 bytes

Esto es sorprendentemente largo. Esto se puede jugar mucho, tomando consejos de la traducción de Pyth.

q~a*{m*:s}*{:H\:G_+\#)GGHH,,{_H<G,@-G>=},W=>+?}*

La entrada va como

3 "ABC"

es decir: cadena de la lista de caracteres y la longitud.

y la salida es la cadena De Bruijn

AAABAACABBABCACBACCBBBCBCCC

Pruébalo en línea aquí

Optimizador
fuente
1
Gosh Cjam debe ser prohibido, no se acaba de hacer para una tarea de golf pero parece que para cada tarea posible jugar al golf ...
flawr
2
@flawr deberías esperar una respuesta de Pyth y luego: P
Optimizer
3

CJam, 52 49 bytes

Aquí hay un enfoque diferente en CJam:

l~:N;:L,(:Ma{_N*N<0{;)_!}g(+_0a=!}g]{,N\%!},:~Lf=

Toma una entrada como esta:

"ABC" 3

y produce un trabajo de Lyndon como

CCCBCCACBBCBACABCAABBBABAAA

Pruébalo aquí

Esto hace uso de la relación con las palabras de Lyndon . Genera todas las palabras de Lyndon de longitud n en orden lexicográfico (como se describe en ese artículo de Wikipedia), luego elimina aquellas cuya longitud no divide n . Esto ya produce la secuencia de De Bruijn, pero como estoy generando las palabras de Lyndon como cadenas de dígitos, también necesito reemplazarlas con las letras correspondientes al final.

Por razones de golf, considero que las letras posteriores del alfabeto tienen un orden lexicográfico más bajo.

Martin Ender
fuente
1

JavaScript (ES6) 143

Usando palabras de Lyndon, como la respuesta de Martin, solo 3 veces más ...

F=(a,n)=>{
  for(w=[-a[l='length']],r='';w[0];)
  {
    n%w[l]||w.map(x=>r+=a[~x]);
    for(;w.push(...w)<=n;);
    for(w[l]=n;!~(z=w.pop()););
    w.push(z+1)
  }
  return r
}

Prueba en la consola FireFox / FireBug

console.log(F("ABC",3),F("10",4))

Salida

CCCBCCACBBCBACABCAABBBABAAA 0000100110101111
edc65
fuente
1

Python 2, 114 bytes

No estoy realmente seguro de cómo jugarlo más, debido a mi enfoque.

def f(a,n):
 s=a[-1]*n
 while 1:
    for c in a:
     if((s+c)[len(s+c)-n:]in s)<1:s+=c;break
    else:break
 print s[:1-n]

Pruébalo en línea

Sin golf:

Este código es una modificación trivial de mi solución al desafío más reciente.

def f(a,n):
    s=a[-1]*n
    while 1:
        for c in a:
            p=s+c
            if p[len(p)-n:]in s:
                continue
            else:
                s=p
                break
        else:
            break
    print s[:1-n]

La única razón que [:1-n]se necesita es porque la secuencia incluye la envoltura.

mbomb007
fuente
1

Powershell, 164 96 bytes

-68 bytes con -match en O($n*2^n)lugar de generador recursivoO(n*log(n))

param($s,$n)for(;$z=$s|% t*y|?{"$($s[-1])"*($n-1)+$x-notmatch-join"$x$_"[-$n..-1]}){$x+=$z[0]}$x

Ungolfed y script de prueba:

$f = {

param($s,$n)                    # $s is a alphabet, $n is a subsequence length
for(;                           # repeat until...
    $z=$s|% t*y|?{              # at least a character from the alphabet returns $true for expression:
        "$($s[-1])"*($n-1)+$x-notmatch  # the old sequence that follows two characters (the last letter from the alphabet) not contains
        -join"$x$_"[-$n..-1]    # n last characters from the new sequence
}){
    $x+=$z[0]                   # replace old sequence with new sequence
}
$x                              # return the sequence

}

@(
    ,("ABC",  2, "AABACBBCC")
    ,("ABC",  3, "AAABAACABBABCACBACCBBBCBCCC")
    ,("ABC",  4, "AAAABAAACAABBAABCAACBAACCABABACABBBABBCABCBABCCACACBBACBCACCBACCCBBBBCBBCCBCBCCCC")
    ,("ABC",  5, "AAAAABAAAACAAABBAAABCAAACBAAACCAABABAABACAABBBAABBCAABCBAABCCAACABAACACAACBBAACBCAACCBAACCCABABBABABCABACBABACCABBACABBBBABBBCABBCBABBCCABCACABCBBABCBCABCCBABCCCACACBACACCACBBBACBBCACBCBACBCCACCBBACCBCACCCBACCCCBBBBBCBBBCCBBCBCBBCCCBCBCCBCCCCC")
    ,("ABC",  6, "AAAAAABAAAAACAAAABBAAAABCAAAACBAAAACCAAABABAAABACAAABBBAAABBCAAABCBAAABCCAAACABAAACACAAACBBAAACBCAAACCBAAACCCAABAABAACAABABBAABABCAABACBAABACCAABBABAABBACAABBBBAABBBCAABBCBAABBCCAABCABAABCACAABCBBAABCBCAABCCBAABCCCAACAACABBAACABCAACACBAACACCAACBABAACBACAACBBBAACBBCAACBCBAACBCCAACCABAACCACAACCBBAACCBCAACCCBAACCCCABABABACABABBBABABBCABABCBABABCCABACACABACBBABACBCABACCBABACCCABBABBABCABBACBABBACCABBBACABBBBBABBBBCABBBCBABBBCCABBCACABBCBBABBCBCABBCCBABBCCCABCABCACBABCACCABCBACABCBBBABCBBCABCBCBABCBCCABCCACABCCBBABCCBCABCCCBABCCCCACACACBBACACBCACACCBACACCCACBACBACCACBBBBACBBBCACBBCBACBBCCACBCBBACBCBCACBCCBACBCCCACCACCBBBACCBBCACCBCBACCBCCACCCBBACCCBCACCCCBACCCCCBBBBBBCBBBBCCBBBCBCBBBCCCBBCBBCBCCBBCCBCBBCCCCBCBCBCCCBCCBCCCCCC")
    ,("01",   3, "00010111")
    ,("01",   4, "0000100110101111")
    ,("abcd", 2, "aabacadbbcbdccdd")
    ,("0123456789", 3, "0001002003004005006007008009011012013014015016017018019021022023024025026027028029031032033034035036037038039041042043044045046047048049051052053054055056057058059061062063064065066067068069071072073074075076077078079081082083084085086087088089091092093094095096097098099111211311411511611711811912212312412512612712812913213313413513613713813914214314414514614714814915215315415515615715815916216316416516616716816917217317417517617717817918218318418518618718818919219319419519619719819922232242252262272282292332342352362372382392432442452462472482492532542552562572582592632642652662672682692732742752762772782792832842852862872882892932942952962972982993334335336337338339344345346347348349354355356357358359364365366367368369374375376377378379384385386387388389394395396397398399444544644744844945545645745845946546646746846947547647747847948548648748848949549649749849955565575585595665675685695765775785795865875885895965975985996667668669677678679687688689697698699777877978878979879988898999")
    ,("9876543210", 3, "9998997996995994993992991990988987986985984983982981980978977976975974973972971970968967966965964963962961960958957956955954953952951950948947946945944943942941940938937936935934933932931930928927926925924923922921920918917916915914913912911910908907906905904903902901900888788688588488388288188087787687587487387287187086786686586486386286186085785685585485385285185084784684584484384284184083783683583483383283183082782682582482382282182081781681581481381281181080780680580480380280180077767757747737727717707667657647637627617607567557547537527517507467457447437427417407367357347337327317307267257247237227217207167157147137127117107067057047037027017006665664663662661660655654653652651650645644643642641640635634633632631630625624623622621620615614613612611610605604603602601600555455355255155054454354254154053453353253153052452352252152051451351251151050450350250150044434424414404334324314304234224214204134124114104034024014003332331330322321320312311310302301300222122021121020120011101000")
) |% {
    $s,$n,$e = $_
    $r = &$f $s $n
    "$($r-eq$e): $r"
}

Salida:

True: AABACBBCC
True: AAABAACABBABCACBACCBBBCBCCC
True: AAAABAAACAABBAABCAACBAACCABABACABBBABBCABCBABCCACACBBACBCACCBACCCBBBBCBBCCBCBCCCC
True: AAAAABAAAACAAABBAAABCAAACBAAACCAABABAABACAABBBAABBCAABCBAABCCAACABAACACAACBBAACBCAACCBAACCCABABBABABCABACBABACCABBACABBBBABBBCABBCBABBCCABCACABCBBABCBCABCCBABCCCACACBACACCACBBBACBBCACBCBACBCCACCBBACCBCACCCBACCCCBBBBBCBBBCCBBCBCBBCCCBCBCCBCCCCC
True: AAAAAABAAAAACAAAABBAAAABCAAAACBAAAACCAAABABAAABACAAABBBAAABBCAAABCBAAABCCAAACABAAACACAAACBBAAACBCAAACCBAAACCCAABAABAACAABABBAABABCAABACBAABACCAABBABAABBACAABBBBAABBBCAABBCBAABBCCAABCABAABCACAABCBBAABCBCAABCCBAABCCCAACAACABBAACABCAACACBAACACCAACBABAACBACAACBBBAACBBCAACBCBAACBCCAACCABAACCACAACCBBAACCBCAACCCBAACCCCABABABACABABBBABABBCABABCBABABCCABACACABACBBABACBCABACCBABACCCABBABBABCABBACBABBACCABBBACABBBBBABBBBCABBBCBABBBCCABBCACABBCBBABBCBCABBCCBABBCCCABCABCACBABCACCABCBACABCBBBABCBBCABCBCBABCBCCABCCACABCCBBABCCBCABCCCBABCCCCACACACBBACACBCACACCBACACCCACBACBACCACBBBBACBBBCACBBCBACBBCCACBCBBACBCBCACBCCBACBCCCACCACCBBBACCBBCACCBCBACCBCCACCCBBACCCBCACCCCBACCCCCBBBBBBCBBBBCCBBBCBCBBBCCCBBCBBCBCCBBCCBCBBCCCCBCBCBCCCBCCBCCCCCC
True: 00010111
True: 0000100110101111
True: aabacadbbcbdccdd
True: 0001002003004005006007008009011012013014015016017018019021022023024025026027028029031032033034035036037038039041042043044045046047048049051052053054055056057058059061062063064065066067068069071072073074075076077078079081082083084085086087088089091092093094095096097098099111211311411511611711811912212312412512612712812913213313413513613713813914214314414514614714814915215315415515615715815916216316416516616716816917217317417517617717817918218318418518618718818919219319419519619719819922232242252262272282292332342352362372382392432442452462472482492532542552562572582592632642652662672682692732742752762772782792832842852862872882892932942952962972982993334335336337338339344345346347348349354355356357358359364365366367368369374375376377378379384385386387388389394395396397398399444544644744844945545645745845946546646746846947547647747847948548648748848949549649749849955565575585595665675685695765775785795865875885895965975985996667668669677678679687688689697698699777877978878979879988898999
True: 9998997996995994993992991990988987986985984983982981980978977976975974973972971970968967966965964963962961960958957956955954953952951950948947946945944943942941940938937936935934933932931930928927926925924923922921920918917916915914913912911910908907906905904903902901900888788688588488388288188087787687587487387287187086786686586486386286186085785685585485385285185084784684584484384284184083783683583483383283183082782682582482382282182081781681581481381281181080780680580480380280180077767757747737727717707667657647637627617607567557547537527517507467457447437427417407367357347337327317307267257247237227217207167157147137127117107067057047037027017006665664663662661660655654653652651650645644643642641640635634633632631630625624623622621620615614613612611610605604603602601600555455355255155054454354254154053453353253153052452352252152051451351251151050450350250150044434424414404334324314304234224214204134124114104034024014003332331330322321320312311310302301300222122021121020120011101000

Ver también: Un anillo para gobernarlos a todos. Una cadena para contenerlos a todos

mazzy
fuente