Contando ciclos em um processo de dobragem e esmagamento

8

Em teoria do caos , o mapa de ferradura é um exemplo de como caos surge num simples processo de dobragem e esmagamento. É assim: pegue uma massa imaginária, dobre-a e, finalmente, amasse-a no tamanho original. O caos surge no padrão de como os pedaços de massa terminam no arranjo final após n iterações.

Exemplo de uma medida invariável

No nosso caso, veremos como um padrão binário simples se comporta quando dobramos e esmagamos . Aqui estão as etapas com um exemplo de 8 bits (a representação binária de 201 ou 11001001).

  1. Corte os bits em dois pedaços de igual comprimento (adicione um '0' no início, se houver um número ímpar de bits).

    1100 | 1001

  2. Dobre a primeira metade sobre a segunda metade. Observe que a ordem da primeira metade é invertida, à medida que a giramos enquanto dobra.

    0011
    1001

  3. Squash para sua forma original. Enquanto esmagam, os bits superiores são deslocados para a esquerda para os bits sob sua posição original.

    01001011

Se repetirmos este exemplo, podemos ver que, após 4 iterações, voltamos à cadeia de bits original:

Start  bits: 11001001
Iteration 1: 01001011
Iteration 2: 01001101
Iteration 3: 01011001
Iteration 4: 11001001

Portanto, para o valor decimal de 201, o número de ciclos é 4.

O desafio

  • Escreva um programa completo que use um número decimal como entrada e produza o número de ciclos necessários para repetir no processo bifurcado e dobrado binário descrito acima.
  • A entrada (decimal) deve ser obtida de stdin (intervalo: de 1 a Googol ou 10 ^ 100).
  • A saída (decimal) deve ser gravada em stdout.
  • Sua pontuação é o número de bytes do seu código.
  • Sua resposta deve começar com [Linguagem de programação] - [Pontuação em bytes]
  • As brechas padrão não são permitidas.

Exemplos

7 --> 3
43 --> 5
178 --> 4
255 --> 1
65534 --> 1
65537 --> 12
1915195950546866338219593388801304344938837974777392666909760090332935537657862595345445466245217915 --> 329

Nota final

O interessante é que o número de ciclos está relacionado ao comprimento da representação binária, exceto por algumas exceções em que o número de ciclos é mais curto devido ao padrão na cadeia de bits (por exemplo, 111110ciclos após 1 iteração). Isso cria uma oportunidade interessante para otimizar o comprimento do código usando o padrão subjacente em vez de calcular o número de ciclos.

de qualquer maneira
fonte
Se o tamanho do bit diminuir durante a iteração, recortamos e dobramos usando o comprimento original ou o atual?
Xnor
2
@xnor Eu assumiria o original, caso contrário você nunca completaria o ciclo, certo?
Martin Ender

Respostas:

4

CJam, 34 bytes

q~2b_,2%,\+{__,2//~\W%.\_W$=!}g;],

Nada extravagante, apenas aplica o mapa até retornarmos à entrada e imprimir o número de iterações realizadas.

Teste aqui.

Martin Ender
fonte
Primeiro em! Olhe para você, gravando código mais rápido que a sua sombra!
agtoever
3

Python 2, 175 154 149 bytes

i=bin(input())[2:]
i=o='0'+i if len(i)%2 else i
c=0
j=len(i)/2
while i!=o or c==0:
 a=''
 for x,y in zip(i[:j][::-1],i[j:]):a+=x+y
 i,c=a,c+1
print c

Link Ideone

Graças a agtoever por 27 bytes!

Celeo
fonte
1
Não há necessidade do lambda. Uma vez que o comprimento é uniforme, permanece uniforme.
agtoever
Excelente ponto, obrigado!
Celeo # 13/15
Altere `while 1` com while i!=o|c==0e solte o if i==o:break. Salva 5. Talvez (note com certeza) que você também não precisa a. Apenas use i. Salva uma atribuição (4 bytes). Além disso, a atribuição de j pode ser colocada fora do loop.
agtoever
Obrigado pelas poupanças adicionais, @agtoever. Eu obtive um TypeError ao tentar implementar a while i!=c|c==0substituição, mas ainda consegui salvar alguns bytes com um padrão `ou`.
Celeo
2

Pitão, 21 bytes

Como estou digitando isso no meu telefone, notifique-me de quaisquer erros.

fqu.i_hc2Gec2GTJ.BQJ1

Experimente online.

PurkkaKoodari
fonte