Determinando as frações contínuas de raízes quadradas

13

A fração contínua de um número né uma fração da seguinte forma:


que converge para n.

A sequência aem uma fração continuada é tipicamente escrita como: [a 0 ; a 1 , a 2 , a 3 , ... a n ].
Escreveremos os nossos da mesma maneira, mas com a parte repetida entre ponto e vírgula.

Seu objetivo é retornar a fração contínua da raiz quadrada de n.
Entrada: um número inteiro n,. nnunca será um quadrado perfeito.
Saída: a fração continuada de sqrt(n).

Casos de teste:
2 -> [1; 2;]
3 -> [1; 1, 2;]
19 -> [4; 2, 1, 3, 1, 2, 8;]

O menor código vence. Boa sorte!

beary605
fonte
1
A saída precisa estar no mesmo formato dos casos de teste?
grc
Não. Contanto que você tenha ponto e vírgula, tudo bem.
beary605
Hm, obtendo as respostas certas, tendo problemas para saber quando a fração é racional parar. É realmente tão simples como quando um <sub> 0 </sub> é o dobro do sqrt da entrada original?
21412 JoeFish
Sim, esse é o limite.
beary605
@ beary605 obrigado. Ando lendo muito mais e agora vejo que a fração contínua de uma raiz quadrada é um caso especial. Coisas fascinantes! Ainda trabalhando em uma versão de ponto não flutuante.
21412 JoeFish

Respostas:

3

GolfScript ( 66 60 caracteres)

~:^,{.*^>}?(:?';'[1?{^1$.*-@/?@+.2$/@@1$%?\- 1$(}do;;]','*1$

Aviso: a maioria das ?variáveis ​​existentes representa a variável floor(sqrt(input))em vez da incorporada. Mas o primeiro é o embutido.

Aceita stdin e gera stdout.

Psuedocode do algoritmo (prova de correção atualmente deixada como um exercício para o leitor):

n := input()
m := floor(sqrt(n))
output(m)
x := 1
y := m
do
  x := (n - y * y) / x
  output((m + y) / x)
  y := m - (m + y) % x
while (x > 1)

Mais uma vez, me pego querendo um único operador que assuma a ba pilha e a deixe a/b a%bna pilha.

Peter Taylor
fonte
1
Eu diria que eu realmente precisa aprender GS ... mas necessidade é uma palavra um pouco forte demais aqui;)
Boothby
1
@ Boothby, não seja louco. Sua vida não será completa sem GS;)
Peter Taylor
3

Python, 95 97 (mas correto ...)

Isso usa apenas aritmética inteira e divisão de piso. Isso produzirá resultados corretos para todas as entradas inteiras positivas, embora se alguém quiser usar um longo, ele precisará adicionar um caractere; por exemplo m=a=0L. E, é claro ... espere um milhão de anos até o térreo do meu pobre homem terminar.

z=x=m=1
while n>m*m:m+=1
m=y=m-1
l=()
while-z<x:x=(n-y*y)/x;y+=m;l+=y/x,;y=m-y%x;z=-1
print c,l

Resultado:

n=139
11 (1, 3, 1, 3, 7, 1, 1, 2, 11, 2, 1, 1, 7, 3, 1, 3, 1, 22)

edit: agora usando o algoritmo de Peter Taylor. Isso do...whilefoi divertido.

boothby
fonte
Qual é o propósito *(c*c-n)?
Peter Taylor
@ Peter Taylor, eu não tinha lido o desafio com atenção suficiente e fiz o código funcionar para quadrados perfeitos.
usar o seguinte comando
2

Python, 87 82 80

x=r=input()**.5
while x<=r:print"%d"%x+",;"[x==r],;x=1/(x%1)
print`int(r)*2`+";"

É necessário um número inteiro e fornece uma saída como:

4; 2, 1, 3, 1, 2, 8;
grc
fonte
x-int(x) -> x%1. Estou impressionado :)
beary605
Dá o resultado errado para √139 acordo com Wolfram Alpha
breadbox
Eu o atualizei para trabalhar para √139. No entanto, se o comprimento da sequência ficar muito maior (√139 tem uma sequência de 18 números), o resultado provavelmente começará a perder precisão.
grc
Acho incrivelmente interessante que sempre termine em 2 * int (sqrt (a)).
beary605
Mais interessante agora é que 3 de nós quebramos o código para o 139 (o meu ainda não foi jogado nem publicado).
21412 JoeFish
2

Mathematica 33 31

c[n_]:=ContinuedFraction@Sqrt@n

A saída está no formato de lista, o que é mais apropriado para o Mathematica. Exemplos:

c[2]
c[3]
c[19]
c[139]
c[1999]

(* out *)
{1, {2}}
{1, {1, 2}}
{4, {2, 1, 3, 1, 2, 8}}
{11, {1, 3, 1, 3, 7, 1, 1, 2, 11, 2, 1, 1, 7, 3, 1, 3, 1, 22}}
{44, {1, 2, 2, 4, 1, 1, 5, 1, 5, 8, 1, 3, 2, 1, 2, 1, 1, 1, 1, 1, 1, 
  1, 14, 3, 1, 1, 29, 4, 4, 2, 5, 1, 1, 17, 2, 1, 12, 9, 1, 5, 1, 43, 
  1, 5, 1, 9, 12, 1, 2, 17, 1, 1, 5, 2, 4, 4, 29, 1, 1, 3, 14, 1, 1, 
  1, 1, 1, 1, 1, 2, 1, 2, 3, 1, 8, 5, 1, 5, 1, 1, 4, 2, 2, 1, 88}}
DavidC
fonte
1
Oh cara, eu esperava totalmente essa resposta. Não a considerarei uma resposta real, a menos que você mesmo gere a fração contínua.
beary605
@ beary605 É justo.
DavidC
2
+1 Melhor ainda (25 caracteres)ContinuedFraction@Sqrt@#&
Dr. belisarius
O que exatamente você está contando aqui? Este é um programa que recebe informações do stdin? Porque a maneira como você a usa parece um corpo de função sem a definição da função.
Peter Taylor
@ Peter Taylor Por favor, veja a alteração.
DavidC
1

Python ( 136133 96)

O método padrão para frações contínuas, extremamente golfe.

a=input()**.5
D=c=int(a);b=[]
while c!=D*2:a=1/(a%1);c=int(a);b+=[c]
print D,";%s;"%str(b)[1:-1]
beary605
fonte
Você pode salvar alguns caracteres usando while 1:. Você também pode colocar a maioria das instruções no loop while em uma única linha.
grc 18/06/12
Quando executo seu script, recebo uma saída de 8 ;1;para 74 e para 75; isso não parece certo. Ele trava em 76.
breadbox
^^ Sim. Corrigido meu código.
beary605
Esta versão dá o resultado errado para 139.
breadbox
@boothby Então eu vou excluir o meu e vamos chamá-lo de empate :) #
3110 JoeFish
1

C, 137

Incluindo a nova linha, supondo que eu não precise rolar minha própria raiz quadrada.

#include<math.h>
main(i,e){double d;scanf("%lf",&d);e=i=d=sqrt(d);while(i^e*2)printf("%d%c",i,e^i?44:59),i=d=1.0/(d-i);printf("%d;",i);}

Ele quebra para o sqrt (139) e contém o ponto-e-vírgula extra ocasional na saída, mas estou cansado demais para continuar trabalhando esta noite :)

5
2; 4;
19
4; 2,1,3,1,2,8;
111
10; 1,1,6,1,1,20;
JoeFish
fonte
1

Perl, 99 caracteres

Será não estragar em 139, 151, etc Testado com número que varia de 1 a 9 dígitos.

$"=",";$%=1;$==$-=($n=<>)**.5;
push@f,$==(($s=$=*$%-$s)+$-)/($%=($n-$s*$s)/$%)until$=>$-;
say"$-;@f;"

Nota: $%, $=, e $-são todas as variáveis-forçando inteiros.

caixa de pão
fonte
1

APL (NARS), 111 caracteres, 222 bytes

r←f w;A;a;P;Q;m
m←⎕ct⋄Q←1⋄⎕ct←P←0⋄r←,a←A←⌊√w⋄→Z×⍳w=0
L: →Z×⍳0=Q←Q÷⍨w-P×P←P-⍨a×Q⋄r←r,a←⌊Q÷⍨A+P⋄→L×⍳Q>1
Z: ⎕ct←m

A função f é baseada no algo encontrado na página http://mathworld.wolfram.com/PellEquation.html para resolver a equação de Pell. Essa função f tem sua entrada com número não negativo (tipo fração também). Possível que algo dê errado, lembro que √ tem, na minha opinião, problema para grandes números de fração, como

  √13999999999999999999999999999999999999999999999x
1.183215957E23 

então haveria uma função sqrti (). Por esse motivo, a entrada da fração (e a entrada inteira) deve ser <10 ^ 15. teste:

 ⎕fmt (0..8),¨⊂¨f¨0..8
┌9───────────────────────────────────────────────────────────────────────────────────────────────────────┐
│┌2─────┐ ┌2─────┐ ┌2───────┐ ┌2─────────┐ ┌2─────┐ ┌2───────┐ ┌2─────────┐ ┌2─────────────┐ ┌2─────────┐│
││  ┌1─┐│ │  ┌1─┐│ │  ┌2───┐│ │  ┌3─────┐│ │  ┌1─┐│ │  ┌2───┐│ │  ┌3─────┐│ │  ┌5─────────┐│ │  ┌3─────┐││
││0 │ 0││ │1 │ 1││ │2 │ 1 2││ │3 │ 1 1 2││ │4 │ 2││ │5 │ 2 4││ │6 │ 2 2 4││ │7 │ 2 1 1 1 4││ │8 │ 2 1 4│││
││~ └~─┘2 │~ └~─┘2 │~ └~───┘2 │~ └~─────┘2 │~ └~─┘2 │~ └~───┘2 │~ └~─────┘2 │~ └~─────────┘2 │~ └~─────┘2│
│└∊─────┘ └∊─────┘ └∊───────┘ └∊─────────┘ └∊─────┘ └∊───────┘ └∊─────────┘ └∊─────────────┘ └∊─────────┘3
└∊───────────────────────────────────────────────────────────────────────────────────────────────────────┘
  f 19
4 2 1 3 1 2 8 
  f 54321x
233 14 1 1 3 2 1 2 1 1 1 1 3 4 6 6 1 1 2 7 1 13 4 11 8 11 4 13 1 7 2 1 1 6 6 4 3 1 1 1 1 2 1 2 3 1 1 14 466 
  f 139
11 1 3 1 3 7 1 1 2 11 2 1 1 7 3 1 3 1 22 
  +∘÷/f 139
11.78982612
  √139
11.78982612

se o argumento é um quadrado de um número, ele retornaria uma lista de 1 único elemento, o sqrt desse número

  f 4
2 

Se dependesse de mim, em um exercício sem "codegolf" eu preferiria a edição anterior que usa a função sqrti () ...

RosLuP
fonte
1
certamente você pode usar nomes de letra única em vez de fqe a0. Também: (a×Q)-P->P-⍨a×Q
ngn
Q←Q÷⍨- os nars suportam Q÷⍨←?
ngn 28/07/19
@ngn: Eu não gosto de usar "Q ÷ ⍨ ←" em uma cadeia de fórmula atribuição múltipla ... para o permanecem concordar ... Possível Digo isso porque eu vi C Undefined Comportamento
RosLuP