fundo
A maioria das pessoas aqui deve estar familiarizada com alguns sistemas básicos inteiros: decimal, binário, hexadecimal, octal. Por exemplo, no sistema hexadecimal, um número abc.de 16 representaria
a*16^2 + b*16^1 + c*16^0 + d*16^-1 + e*16^-2
No entanto, também é possível usar bases não inteiras, como números irracionais. Uma vez que tal base utiliza a razão de ouro φ = (1 + √5) / 2 ... ≈ 1.618 . Estes são definidos analogamente às bases inteiras. Portanto, um número abc.de φ (onde a a e são dígitos inteiros) representaria
a*φ^2 + b*φ^1 + c*φ^0 + d*φ^-1 + e*φ^-2
Observe que, em princípio, qualquer um dos dígitos pode ser negativo (embora não estamos acostumados a isso) - representaremos um dígito negativo com um avanço ~
. Para os fins desta pergunta, restringimos-nos a dígitos de ~9
para 9
, para que possamos escrever inequivocamente um número como uma sequência (com os tons no meio). tão
-2*φ^2 + 9*φ^1 + 0*φ^0 + -4*φ^-1 + 3*φ^-2
seria escrito como ~290.~43
. Chamamos esse número de número finário .
Um número finário sempre pode ser representado no formato padrão , o que significa que a representação usa apenas dígitos 1
e 0
, sem conter 11
nenhum lugar, e com um sinal de menos opcional para indicar que o número inteiro é negativo. (Curiosamente, todo número inteiro tem uma representação finita exclusiva na forma padrão.)
As representações que não estão no formato padrão sempre podem ser convertidas no formato padrão usando as seguintes observações:
- 011 φ = 100 φ (porque φ 2 = φ + 1)
- 0200 φ = 1001 φ (porque φ 2 + 1 / φ = 2φ)
- 0 ~ 10 φ = ~ 101 φ (porque φ - 1 / φ = 1)
Além do que, além do mais:
- Se o dígito mais significativo for
~1
(com o restante do número no formato padrão), o número é negativo e podemos convertê-lo no formato padrão trocando all1
e~1
, acrescentando um sinal de menos, e aplicando as três regras acima novamente até que obtenha o formulário padrão.
Aqui está um exemplo dessa normalização de (estou usando espaços adicionais para dígitos positivos, para manter cada posição de dígito alinhada):
1~3.2~1φ
1~3. 2~1φ Rule:
= 0~2. 3~1φ (3)
= ~1~1. 4~1φ (3)
= ~1 0 0. 4~1φ (3)
= ~1 0 0. 3 0 1φ (3)
= ~1 0 1. 1 0 2φ (2)
= ~1 1 0. 0 0 2φ (1)
= ~1 1 0. 0 1 0 0 1φ (2)
= - 1~1 0. 0~1 0 0~1φ (4)
= - 0 0 1. 0~1 0 0~1φ (3)
= - 0 0 1.~1 0 1 0~1φ (3)
= - 0 0 0. 0 1 1 0~1φ (3)
= - 0 0 0. 0 1 1~1 0 1φ (3)
= - 0 0 0. 0 1 0 0 1 1φ (3)
= - 0 0 0. 0 1 0 1 0 0φ (1)
Produzindo -0.0101φ
.
Para ler mais, a Wikipedia tem um artigo muito informativo sobre o assunto.
O desafio
Portanto, ou de outra forma, escreva um programa ou função que, dada uma sequência que representa um número finário (como descrito acima), produz sua forma padrão, sem zeros à esquerda ou à direita. A entrada não contém necessariamente o ponto finário, mas sempre conterá o dígito restante (portanto, não.123
). A saída deve sempre incluir o ponto finário e pelo menos um dígito à esquerda dele.
Você pode receber entradas via STDIN, ARGV ou argumento de função e retornar o resultado ou imprimi-lo em STDOUT.
Você pode usar um algoritmo diferente do procedimento acima, desde que, em princípio, seja correto e exato para entradas arbitrárias (válidas) - ou seja, os únicos limites que podem potencialmente interromper sua implementação devem ser limitações técnicas, como o tamanho dos componentes internos. tipos de dados ou a RAM disponível. Por exemplo, avaliar a entrada como um número de ponto flutuante e, em seguida, selecionar dígitos com avidez não é permitido, pois é possível encontrar entradas para as quais as imprecisões do ponto flutuante levariam a resultados incorretos.
Este é o código golf, a resposta mais curta (em bytes) vence.
Casos de teste
Input Output
1 1.
9 10010.0101
1.618 10000.0000101
1~3.2~1 -0.0101
0.~1021 0. (or -0.)
105.~2 1010.0101
~31~5.~1 -100000.1001