Continue decodificando este número!

8

Esse desafio colocou um algoritmo para codificar um número inteiro ncomo outro número inteiro r. A seguir, é apresentada uma explicação sucinta desse algoritmo, usando n=60como exemplo.

O algoritmo original

  • Primeiro, codificamos o número como uma sequência de colchetes.

    • Se n = 1, retorne uma string vazia.
    • Caso contrário, tomamos na decomposição principal de ordem ordenada ascendente e substituímos cada elemento pelo seu índice principal (indexado 1) entre colchetes.60 = 2*2*3*5 => [1][1][2][3]
    • Faça isso recursivamente até tudo o que temos são colchetes. [1][1][2][3] => [][][[1]][[2]] => [][][[]][[[1]]] => [][][[]][[[]]]
  • Depois de termos nossa cadeia de colchetes, convertemos isso em um número inteiro com o seguinte processo.

    • Converta cada suporte de abertura em a 1e cada suporte de fechamento em a 0.[][][[]][[[]]] => 10101100111000
    • Remova todos os seixos finais 0e o final 1.10101100111000 => 1010110011
    • Converter a seqüência final do 0s e 1s de binário para um número inteiro.1010110011 => 691

Decodificando esta codificação

Uma propriedade interessante desse algoritmo é que ele não é subjetivo. Nem todo número inteiro pode ser o resultado dessa codificação.

  • Em primeiro lugar, a representação binária do resultado rdeve estar balance-ableem que o número de 0s nunca deve exceder o número de 1s. É um caso de teste curto de Falsey 4, que é 100binário.
  • Em segundo lugar, os colchetes na representação binária devem estar sorted ascendingquando o final 1e o final 0são anexados mais uma vez. Um breve caso de teste de falsey é 12 <= 1100 <= 110010 <= (())().

No entanto, apenas determinar se um número é decodificável dessa maneira seria um pequeno desafio. Em vez disso, o desafio é decodificar repetidamente uma determinada entrada até que um número não decodificável ou um ciclo seja alcançado e retorne a sequência resultante de números.

O desafio

  • Dado um número 1 <= r <= 2**20 = 1048576, retorne a sequência de números quer decodifica sucessivamente , começando por rsi mesmo e terminando com um número ou um ciclo não decodificável.
  • Se um não decodificável for fornecido como entrada, como 4ou 12, retornará uma lista contendo apenas a entrada.
  • Uma sequência que termina em um ciclo deve ser indicada de alguma forma, anexando ou anexando um marcador (escolha qualquer número inteiro não positivo, sequência, lista etc. como marcador, mas mantenha-o consistente) ou repetindo o ciclo em de alguma maneira (repetir o primeiro elemento, repetir todo o ciclo, repetir infinitamente, etc.).
  • Com a chance de que qualquer uma das seqüências seja infinita (aumentando para sempre, por exemplo), considere esse comportamento indefinido.
  • Isso é código de golfe. O menor número de bytes vence.

Um exemplo trabalhado de decodificação

   1 -> 1 -> 1100 -> [[]] -> [2] -> 3
-> 3 -> 11 -> 111000 -> [[[]]] -> [[2]] -> [3] -> 5
-> 5 -> 101 -> 101100 -> [][[]] -> 2*[2] -> 2*3 -> 6
-> 6 -> 110 -> 110100 -> [[][]] -> [2*2] -> [4] -> 7
-> 7 -> 111 -> 11110000 -> [[[[]]]] -> [[[2]]] -> [[3]] -> [5] -> 11
-> 11 -> 1011 -> 10111000 -> [][[[]]] -> 2*[[2]] -> 2*[3] -> 2*5 -> 10
-> 10 -> 1010 -> 101010 -> [][][] -> 2*2*2 -> 8
-> 8 -> 1000  ERROR: Unbalanced string

Casos de teste

4 -> [4]
12 -> [12]
1 -> [1, 3, 5, 6, 7, 11, 10, 8]
2 -> [2, 4]
13 -> [13, 13]    # cycle is repeated once
23 -> [23, 22, 14, 17]
51 -> [51, 15, 31, 127, 5381]
691 -> [691, 60]
126 -> [126, 1787, 90907]
1019 -> [1019, 506683, 359087867, 560390368728]

Sugestões e comentários para esse desafio são bem-vindos. Boa sorte e bom golfe!

Sherlock9
fonte
Sandbox .
user202729
Como 13?
Leaky Nun
@LeakyNun 1- (adicione um 1e zeros à direita) -> 1100-> [[]]-> [[1]]-> [2]->3
Colera Su
6-> 110-> 110100que não é válido, certo? Então, a entrada deve 1dar [1,3,5,6]?
dylnan
E para 7: 7-> 111-> 11110000-> [[[[]]]]-> 4º primo = 7? Talvez eu não entendo o algoritmo
dylnan

Respostas:

4

Python 3 , 379 358 339 337 327 310 304 bytes

Conjectura: é 13o único número que levará a um ciclo? (Não há exceções menores que 10 6 ).

Corrigido um bug e -7 bytes graças a Sherlock9 .
-3 bytes graças a Jonathan Frech .
-16 bytes graças a ovs .
-6 bytes graças ao Sr. Xcoder .

Se houver um ciclo, ele repetirá todo o ciclo.

def p(a,x=0,n=1):
 while a:x+=1;a-=n%x;n*=x*x
 return x
def g(a):
 c=i=0
 for v in a:
  c+=int(v)*2-1
  if c<0:return 0,0
  if c<1:break
  i+=1
 if a:x=p(g(a[1:i])[0]);b,c=g(a[i+1:]);return(x>c>0)*(0,0)or(x*b,x)
 return 1,0
def f(a):
 x=a,
 while(x.count(a)<3)*a:a,t=g(bin(a-~a)[2:]);x+=a,
 return x[:-1]

Experimente online!

Explicação:

def p(a,x=0,n=1):     # return the a-th prime
 while a:             # magical way to enumerate primes
  x+=1
  a-=n%x
  n*=x*x
 return x

def g(a):             # decode a 0/1 string
 c=i=0
 for v in a:
  c+=int(v)*2-1       # +1 if 1, -1 if 0
  if c<0: return(0,0) # c<0: unbalanced parentheses
  if c<1: break       # first outermost parentheses
  i+=1
 if a:
   x=p(g(a[1:i])[0])  # recursive solve those inside the parentheses ...
   b,c=g(a[i+1:])     # and the remaining
   if x>c and c:      # if not ascending
    return (0,0)
   return (x*b,x)     # return (result, value of first closed parentheses)
 return (1,0)         # empty string

def f(a):
 x=a,
 while a and x.count(a)<3: # detect non-decodable or cycle
  a,t=g(bin(a-~a)[2:])     # a-~a is a*2+1
  x+=a,
 return x[:-1]
Colera Su
fonte
1

Pitão, 62 bytes

L?b**FKme.fP_Zyd)bSIK1fTseB.u.xyvs@L,"],"\[++JjN2 1m0h-/J1/J00

Suíte de teste

Indica um ciclo repetindo o número final.

L?b**FKme.fP_Zyd)bSIK1    Define y to decode from list format. 0 if invalid.

fTseB.u.xyvs@L,"],"\[++JjN2 1m0h-/J1/J00
     .u                                     Repeat the following until it cycles
                                            Collecting the values in a list.
                     ++JjN2 1m0h-/J1/J0     Convert the number to expanded binary
            @L,"],"\[                       Map 0 to "],", 1 to "["
           s                                Flatten to a string.
          v                                 Evaluate as a Python object.
       .x                              0    If evaluation fails, return 0.
         y                                  Otherwise decode.
  seB                                       Duplicate the final number
fT                                          Remove all 0s.
isaacg
fonte