Escreva uma função que use um único número inteiro positivo n e retorne o período da representação decimal de 1 / n .
Casos de teste:
1 -> 1 # 1/1 = 1.0000...... = 1._0
2 -> 1 # 1/2 = 0.5000...... = 0.5_0
3 -> 1 # 1/3 = 0.3333...... = 0._3
7 -> 6 # 1/7 = 0.14285714.. = 0._142857
13 -> 6
14 -> 6
123 -> 5
345 -> 22
654 -> 108
12345 -> 822
67890 -> 120
Isso é código-golfe . Built-ins ou bibliotecas que retornam o período diretamente não são permitidos. Números de até pelo menos 100000 devem funcionar dentro de um prazo razoável (no máximo vários minutos).
code-golf
number-theory
Howard
fonte
fonte
1.00000000000000000000000000000000000
Respostas:
APL, 19 caracteres / bytes *
Nars2000 . A versão anterior estava errada em alguns números, isso deveria estar certo. Eu verifiquei manualmente em todos os números até 50.
Mais uma vez, Ben Reich dá crédito à idéia de observar o período de
10^i (mod x)
Vista expandida
Exemplos
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
*: APL pode ser escrito na sua própria (legado) de conjunto de caracteres de byte único que mapeia símbolos APL para os 128 valores de bytes superiores. Portanto, para fins de pontuação, um programa de N caracteres que usa apenas caracteres ASCII e símbolos APL pode ser considerado como N bytes.
fonte
20
. Você pode verificar?4
parece que daria a resposta errada também, porque10 != 100 (mod 4)
.GolfScript (
4227)Tempo de referência: 5 segundos. Código de benchmarking:
Agradecemos a Ben Reich pela idéia central de observar o período de
10^i (mod x)
.Explicação
O período
p
é definido como o menor inteiro positivo tal que para todo suficientemente grandei
que temosfrac(10^i * 1/x) = frac(10^(i+p) * 1/x)
. Podemos simplificar isso levementefrac(10^i / x) = frac(10^(i+p) / x)
. Agora,frac(a / x) = frac(b / x)
se e somente sea == b (mod x)
, por isso estamos procurando o menor inteiro positivo tal que para todo suficientemente grandei
:10^i == 10^(i+p) (mod x)
.Suponha
10^i == 10^(i+p) (mod x)
. Então10^(i+1) == 10 * 10^i == 10 * 10^(i+p) == 10^(i+p+1) (mod x)
; então, quando temos uma repetição, estamos em um ciclo inquebrável.Tem apenas
x
valores distintos(mod x)
, portanto, pelo princípio do buraco de pombo, devemos obter uma repetição nos primeirosx + 1
valores de10^i (mod x)
.Então, o que o código acima faz é calcular
x + 2
valores de10^i (mod x)
*. Então, o último é garantido como uma repetição e, revertendo a lista e pesquisando, posso encontrar a ocorrência mais recente. Além disso, como só estou fazendo a pesquisa, é hora de pseudo-tempo.* O único extra é para lidar com o caso especial
x = 1
, porque eu não reduzem10^0 (mod x)
e assim eu estaria à procura de um0
em[1]
.fonte
Golfscript - 26 bytes
Editar: atualizado para a saída
1
se o decimal terminar, em vez do comprimento da representação decimal.Uma versão bastante eficiente. O valor 67890 é executado em aproximadamente 10 segundos e 99991 em cerca de 20 segundos. É um pouco mais lento do que era antes (aproximadamente metade da velocidade), porque o intervalo iterado foi duplicado, a primeira metade do qual é ignorada.
Alternativa, também 26 bytes
Este funciona iterando sobre a string
"\n"*(2*i+1)
, ondei
é o valor passado para a função. O valor passado para o bloco de cada vez é o valor ordinal de"\n"
, que é 10 .O
)^^
é um pouco de uma solução alternativa. Quando você desmarca um caractere de uma sequência, o resultado é o valor ordinal do caractere removido, conforme mencionado acima. No entanto, anexar esse valor novamente anexará a representação de string desse número, em vez do caractere - comportamento bastante não simétrico e, na minha opinião, uma falha de design. Se você realmente quisesse fazer isso, a string primeiro custaria apenas um byte.Uma cópia extra do valor final já está na pilha, portanto, removo o valor final novamente
)
, xou-o com a string e, em seguida, xor novamente, para que todos os caracteres adicionados ou removidos pelo primeiro xor sejam restaurados. Seint op string
fosse tratado como um caractere, em vez de sua representação em cadeia,)^^
poderia ser substituído por|
.Observe que, enquanto as strings (que no Golfscript são armazenadas como uma matriz de ints) exibem o valor de cada caractere mod 256 , os valores de cada caractere podem estar fora desse intervalo. Ao testar a exclusividade (via operações definidas) ou a contenção (via
?
), é o valor real que é comparado, em vez do valor de exibição.Um arquivo de correção para o atual intérprete Golfscript :
O exemplo acima afetará apenas o comportamento de
string op int
(e vice-versa), ondeop
é um dos+-|&^
. Todo o resto permanece inalterado, incluindo o comportamento deGint`
.A seguinte solução de 24 bytes se tornaria válida:
E isso também corrige muitas outras soluções realmente feias .
Python - 48 bytes
Não é a solução mais eficiente, mas é razoável para valores inferiores a 100000 .
FWIW, o elemento principal é idêntico à minha solução para Gerar números cíclicos em decimal .
Uma versão mais eficiente do mesmo código ( 70 bytes ):
O valor 99991 leva menos de um segundo.
fonte
or
é o array em uma string vazia. Por ser uma operação em conjunto, todas as duplicatas são removidas previamente..|
.string int +
quebraria muitos programas. Não sei com que frequência as outras operações são usadas nesse par de tipos.[]+''+
vs''+
. Anexar int, como char, a string:[]++
vs+
. Apend int, como representação de cadeia, a cadeia:+
vs`+
. Na sua implementação atual,int''+
é sinônimo deint`
, o que parece um desperdício, considerando a verbosidade de ter que coagir à matriz e, em seguida, coagir a uma string, se você quiser o caractere ascii.GolfScript,
484746Graças a @ PeterTaylor por cortar dois caracteres.
Eu tentei usar J, mas ele me deu todos os tipos de resultados estranhos.
Teste on-line
Isso basicamente divide 2 e 5 do número (2 e 5 são os fatores primos de 10, e seus recíprocos terminam e enchem o algoritmo), então o número inteiro mais baixo n, de modo que o número resultante divida 10 ^ n - 1 é o período.
fonte
{...}:d;...d
você salvar 1 caractere com #...{...}:d~
f
a pilha, percebo que você também está fazendo isso. Você realmente deve adicionar um;
para exibir a função para uma comparação justa com outros idiomas.int array ,)\;
pode ser reduzida paraint array +,
.Perl, 52 caracteres
Esta é uma implementação descomplicada da abordagem direta. (Felizmente, a abordagem direta também é bastante eficiente: graças à aritmética do módulo, a matemática nunca precisa lidar com um número superior a 10 vezes o valor de entrada.)
Como o desafio especificou uma função, senti-me compelido a (re) inicializar minhas variáveis, algo que não me incomodaria em fazer por um programa completo. Da mesma forma, a
~~
declaração final é desnecessária se a função puder ter certeza de que será invocada em um contexto escalar.fonte
20
onde ela produz o resultado errado.Clojure,
102, 117, 115106não formatado:
formatado:
O tempo de execução é escalado com o período. Quase instantâneo no meu computador para os valores da amostra.
Basicamente, isso calcula o resultado da subtração após cada etapa na divisão longa. Um ciclo é detectado se, a qualquer momento, esse número for o mesmo que foi calculado antes dele.
fonte
20
. Você pode verificar?(não concorrente) Pyth
Usa o algoritmo tartaruga-e-lebre ( mais informações ).
Veja passar todos os testes.
fonte