Hằng số Fibre đối ứng


8

Thấy rằng đã có rất nhiều thách thức Fibonacci bình thường, tôi quyết định rằng sẽ rất thú vị khi tính hằng số Fibroc đối ứng - cụ thể là tổng các nghịch đảo của chuỗi Fibonacci.

Thách thức là tính toán hằng số Fibre đối ứng với số chuỗi Fibonacci để sử dụng chữ số được đưa ra làm đầu vào, tức là đầu vào 10 có nghĩa là tính toán dựa trên các nghịch đảo của 10 số Fibonacci đầu tiên. Trong trường hợp có khả năng hòa, mã ngắn nhất sẽ thắng.

Người chiến thắng sẽ được chọn trong ba tuần qua các quy tắc chơi gôn tiêu chuẩn.


2
Điều này bằng (nếu tôi hiểu đúng) với 1 / (đối ứng tỷ lệ vàng). Nếu bạn muốn chúng tôi thực sự sử dụng các số Fibonacci trong phép tính, bạn nên chỉ định. Nếu không, chắc chắn có ngôn ngữ φlà một nội dung. (không phải APL cho một sự thay đổi)
bến du thuyền

@marinus Thay đổi.

1
@marinus, nó không bằng 1 / phi. Nó có dạng kín, nhưng nó khá phức tạp . Mathematica có thể có tích hợp sẵn, nhưng tôi nghi ngờ nhiều ngôn ngữ khác làm được.
Peter Taylor

@OP, "độ chính xác cao nhất có thể" là một tiêu chí chiến thắng vô dụng. Bất cứ ai có ngôn ngữ hỗ trợ độ chính xác thập phân tùy ý hoặc có thể bị làm phiền khi viết hỗ trợ cho ngôn ngữ đó, có thể thực hiện với một tham số chính xác và sau đó tham gia vào một cuộc chiến chỉnh sửa để tăng tham số đó. Sẽ có ý nghĩa hơn khi yêu cầu một hàm lấy độ chính xác làm tham số. Đánh giá về tốc độ cũng khó khăn, bởi vì nó phụ thuộc vào nhiều yếu tố (kiểu CPU, RAM có sẵn, tải hệ thống, ...).
Peter Taylor

@PeterTaylor Điều này có tốt hơn không?

Câu trả lời:


5

K (19)

(hoặc 17 nếu bạn bỏ qua việc xác định nó là một hàm)

f:{+/*+%x(|+\)\|!2}

Đã thử nghiệm trên Kona.

Về cơ bản, nó tạo ra các giá trị x đầu tiên của chuỗi Wikipedia thành một mảng (không sử dụng nội dung), chia 1 cho mỗi giá trị của toàn bộ mảng, hoán đổi và tính tổng.

(cảm ơn @tmartin về phương pháp tổng hợp tốt hơn)


Một biến thể nhỏ của bạn trong 17 ký tự -{+/*+%x(|+\)\|!2}
tmartin

@tmartin Cảm ơn, vâng, đó là một phương pháp tổng hợp ít phức tạp hơn :)
Joachim Isaksson

9

Perl - 35 byte

print!map$\-=1/($%+=$.=$%-$.),0..<>

Sử dụng mẫu:

$ echo 10 | perl inv-fib-sum.pl
3.34170499581934

Phân tích sâu hơn

Thật thú vị khi lưu ý rằng tổng

là hội tụ. Giả sử chúng tôi muốn tính toán vài nghìn chữ số hoặc hơn, cách tiếp cận ngây thơ là gần như đủ. Sự hội tụ ban đầu khá chậm, nhưng tăng tốc nhanh, do đó 1000 chữ số chỉ mất khoảng 4800 thuật ngữ. Một triển khai Python mẫu có thể là:

a=[1,1]
for i in range(4800):a=[a[0]+a[1]]+a
z=10**1000
print sum(map(lambda i:z/i,a))

mà sau một giây xuất ra:

33598856662431775531720113029189271796889051337319684864955538153251303189966833836154162164567900872970453429288539133041367890171008836795913517330771190785803335503325077531875998504871797778970060395645092153758927752656733540240331694417992939346109926262579646476518686594497102165589843608814726932495910794738736733785233268774997627277579468536769185419814676687429987673820969139012177220244052081510942649349513745416672789553444707777758478025963407690748474155579104200675015203410705335285129792635242062267537568055761955669720848843854407983324292851368070827522662579751188646464096737461572387236295562053612203024635409252678424224347036310363201466298040249015578724456176000319551987905969942029178866949174808096746523682654086938399069873211752166957063859411814553647364268782462926166650100098903804823359519893146150108288726392887669917149304053057745574321561167298985617729731395370735291966884327898022165047585028091806291002444277017460241040417786069190065037142832933

(Bốn chữ số cuối không hoàn toàn hội tụ, nhưng chúng ta sẽ bỏ qua điều đó ngay bây giờ.)

Hãy cố gắng tăng tốc độ hội tụ một chút. Một mẹo tiêu chuẩn là sử dụng Biến đổi của Euler's . Sau khi mở rộng và đơn giản hóa, điều này tạo ra một kết quả đẹp hơn:

Nó khá rõ ràng tại sao điều này hội tụ nhanh hơn; mỗi thuật ngữ có 3 thuật ngữ trong mẫu số thay vì chỉ một. Tính 1000 chữ số chỉ mất 1600 (một phần ba số thuật ngữ):

a=[1,1]
for i in range(1601):a=[a[0]+a[1]]+a
z=10**1000
print sum(map(lambda i:(-1)**i*z/(a[i]*a[i+1]*a[i+2]),range(1601)))

Đầu ra:

3598856662431775531720113029189271796889051337319684864955538153251303189966833836154162164567900872970453429288539133041367890171008836795913517330771190785803335503325077531875998504871797778970060395645092153758927752656733540240331694417992939346109926262579646476518686594497102165589843608814726932495910794738736733785233268774997627277579468536769185419814676687429987673820969139012177220244052081510942649349513745416672789553444707777758478025963407690748474155579104200675015203410705335285129792635242062267537568055761955669720848843854407983324292851368070827522662579751188646464096737461572387236295562053612203024635409252678424224347036310363201466298040249015578724456176000319551987905969942029178866949174808096746523682654086938399069873211752166957063859411814553647364268782462926166650100098903804823359519893146150108288726392887669917149304053057745574321561167298985617729731395370735291966884327898022165047585028091806291002444277017460241040417786069190065037142834500

(Ở đây một lần nữa, 4 chữ số cuối cùng không hội tụ.)

Chúng ta vẫn chưa hoàn thành. Nếu chúng tôi kết hợp các thuật ngữ liền kề, chúng tôi sẽ kết thúc bằng các điều sau:

Bao thanh toán cho mỗi thuật ngữ từ phần còn lại của tổng kết cho biểu thức lồng nhau:

Bây giờ chúng tôi đang nhận được ở đâu đó. Lưu ý rằng các tử số theo OEIS A206351 (ngoại trừ thuật ngữ đầu tiên, được nhân đôi):

và mẫu số theo OEIS A081016 (được thay đổi bởi một thuật ngữ):

Mỗi trong số này có quan hệ tái phát rất đơn giản, cụ thể là:

tương ứng. Đặt tất cả lại với nhau, chúng tôi thấy rằng chúng tôi chỉ cần 800 lần lặp cho 1000 chữ số:

b,c=[16,3,1],[273,40,3]
for i in range(800):b,c=[7*b[0]-b[1]-4]+b,[7*c[0]-c[1]-1]+c
s=z=10**1000
for x,y in zip(b,c):s=(z+s)*x/y
print s

đầu ra nào:

3598856662431775531720113029189271796889051337319684864955538153251303189966833836154162164567900872970453429288539133041367890171008836795913517330771190785803335503325077531875998504871797778970060395645092153758927752656733540240331694417992939346109926262579646476518686594497102165589843608814726932495910794738736733785233268774997627277579468536769185419814676687429987673820969139012177220244052081510942649349513745416672789553444707777758478025963407690748474155579104200675015203410705335285129792635242062267537568055761955669720848843854407983324292851368070827522662579751188646464096737461572387236295562053612203024635409252678424224347036310363201466298040249015578724456176000319551987905969942029178866949174808096746523682654086938399069873211752166957063859411814553647364268782462926166650100098903804823359519893146150108288726392887669917149304053057745574321561167298985617729731395370735291966884327898022165047585028091806291002444277017460241040417786069190065037142835294

(Ở đây, cuối cùng, 4 chữ số cuối cùng hội tụ chính xác.)

Nhưng đó vẫn chưa phải là tất cả. Nếu chúng ta quan sát các giá trị trung gian cho s , chúng ta thấy rằng nó hội tụ đến một giá trị khác hoàn toàn trước khi hội tụ vào điểm hội tụ thực tế. Lý do cho điều này là như sau:

Giải quyết cho một s ổn định , chúng tôi thấy rằng:

Bởi vì đây là một gốc đơn giản, chúng ta có thể sử dụng Phương pháp của Newton để đưa chúng ta đến gần đó, và sau đó nhảy vào một điểm sau đó trong vòng lặp. Chỉ cần khoảng 400 chữ số chính xác (vì giá trị bc không lớn hơn giá trị nào), có thể đạt được chỉ với 7 lần lặp, trong khi lưu 320 lần lặp của vòng lặp chính:

b,c=[16,3,1],[273,40,3]
for i in range(480):b,c=[7*b[0]-b[1]-4]+b,[7*c[0]-c[1]-1]+c
z=10**1000;s=z/17
for i in range(7):s-=(s*s+s*z-z*z/16)/(2*s+z)
for x,y in zip(b,c):s=(z+s)*x/y
print s

Đầu ra giống hệt với lần trước, thời gian chạy khoảng 0,02 giây trên hệ thống của tôi bằng PyPy v2.1. Mặc dù nó cần 1/10 số lần lặp như ban đầu, nhưng nó nhanh hơn đáng kể so với 10 lần do nhân và chia cho các số hạng nhỏ hơn nhiều. Tôi không nghĩ nhiều hơn có thể được điều chỉnh từ nó, mặc dù tôi rất vui khi được hiển thị sai.


6

Mathematica (32 ký tự không có Fibonacci tích hợp)

Tr[1/⌈(.5+√5/2)^Range@#/√5-.5⌉]&

nhập mô tả hình ảnh ở đây

Ở đây tôi đã sử dụng công thức làm tròn cho các số Fibonacci

nhập mô tả hình ảnh ở đây

nơi φlà tỷ lệ vàng.


5

Kona ( 25 21)

{+/%(x(|+\)\1 1)[;1]}

Có lẽ có thể được làm nhỏ hơn bởi các chuyên gia, nhưng tôi vẫn đang học ngôn ngữ.

  f 10
3.341705
  f 3
2.8333
  f 25
3.359872
  f 400
3.359886

Người cuối cùng thực sự không mất nhiều thời gian hơn những người khác.


Tôi đang học một số ngôn ngữ bằng cách hoàn thành những thách thức trong đó. Rất vui khi thấy tôi không phải là người duy nhất.

Lưu cho mình hai ký tự bằng cách chỉ gọi hàm là lambda chứ không phải là hàm được đặt tên. Sau đó, tiết kiệm thêm hai bằng cách sử dụng %chức năng đối ứng thay vì thực hiện 1.%- {+/%(x(|+\)\1 1)[;1]}trong 21 ký tự
tmartin

@tmartin: Lạ ... Tôi nghĩ tôi đã thử làm đối ứng và nhận được 0 vì phân chia số nguyên, nhưng nó hiện đang làm việc cho tôi. Tôi đang cập nhật câu trả lời, cảm ơn rất nhiều!
Kyle Kanos

Bạn có chắc là bạn đang tính đúng? Tôi nhận được 2.833333333 cho n = 4, ví dụ, thay vì 3. Một trong số chúng tôi sai!
Tobia

@Tobia: Sự khác biệt giữa lập chỉ mục 0 và 1. f 0kết quả 1.0, f 1 -> 2.0và như vậy.
Kyle Kanos

4

Toán học 30 24

Với 6 ký tự được lưu nhờ vào ybeltukov.

 Tr[1/Fibonacci@Range@#]&

Trước khi thêm các điều khoản:

1/Fibonacci@Range@#&[20]

hình ảnh1


Ngoài ra bao gồm:

 Tr[1/Fibonacci@Range@#]&[20]

hình ảnh 2


FibonacciListable:) Nó có thể được giảm xuốngTr[1/Fibonacci@Range@#]&
ybeltukov

4

APL, 21 ký tự / byte *

{+/÷{↑+\∘⌽⍣⍵⊢0 1}¨⍳⍵}

Thí dụ

      {+/÷{↑+\∘⌽⍣⍵⊢0 1}¨⍳⍵} 10
3.330469041
      ⍪{+/÷{↑+\∘⌽⍣⍵⊢0 1}¨⍳⍵}¨⍳10
1          
2          
2.5        
2.833333333
3.033333333
3.158333333
3.23525641 
3.282875458
3.312287223
3.330469041
      {+/÷{↑+\∘⌽⍣⍵⊢0 1}¨⍳⍵} 100
3.359885666

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
*: APL có thể được viết bằng bộ ký tự byte đơn (di sản) riêng để ánh xạ các ký hiệu APL đến các giá trị 128 byte trên. Do đó, với mục đích ghi điểm, một chương trình gồm các ký tự N chỉ sử dụng các ký tự ASCII và các ký hiệu APL có thể được coi là dài N byte.


3

Javascript, 33

Đầu vào: n = 10

s=f=t=1;for(;n--;)t+=1/(s+=f=s-f)

Dựa trên bài đăng đầu tiên của tôi ở Perl, đây là kết quả trực tiếp từ Bảng điều khiển Google Chrome .

nhập mô tả hình ảnh ở đây



2

GTB , 35

Chạy trên máy tính TI-84

1→Y:0→X`N4;N,1,N~1/X:Y→Z:X+Y→Y:Z→X&
  • Lưu trữ 1trong Y0trongX
  • Lấy Nlàm đầu vào
  • Khởi tạo một Forvòng lặp
  • Trưng bày X
  • Lưu trữ Ytrong ZX+YtrongY
  • Lưu trữ ZtrongX
  • Kết thúc Forvòng lặp

Tôi cho rằng nó hoạt động, nhưng bạn có thể cung cấp một lời giải thích?

Tôi đã thêm một.
TimTech

2

BC - 116

define f(n){if(n < 2){return n;}else{return f(n-1)+f(n-2);}}
define r(n){for(i=1;i<n;++i){m=m+(1/f(i));};return m;}

gọi r (n) với n để giải. Độ chính xác có thể được đặt tùy ý, vì vậy đây là giải pháp chính xác nhất.


2

PERL, 62 43

$s=$t=1;$t+=1/($a=$f+$s),$f=$s,$s=$a,for 0..<>;say $t

Biên tập:

Sau một thời gian xem mã của tôi, tôi đã có thể lưu 19 ký tự:

$s=1;$t+=1/($s+=$f=$s-$f)for 0..<>;say $t+2

đầu vào: 10
> 3.35294128575734


2

Viết tắt, 64

: r 1 1 rot 1e 0 do 2dup - nip tuck + dup s>f 1/f f+ swap loop ;

sử dụng:

10 r f. 3.34170499581934  ok
100 r f. 3.35988566624318  ok
1000 r f. 3.35988566624318  ok

2

Con trăn ( 55 51)

i,r=p=1,1
while i<n+1:r+=1./p[-1];p=p[1],sum(p);i+=1
r

i,r,a,b=[1]*4
while i<n+1:r+=1./b;a,b=b,b+a;i+=1
r

Trong chế độ tương tác:

n=10
3.341704995819338

n=100

3.3598856429940778

3.359885666243178

n=400

3.3598855578800064

3.359885666243178



1

C # (.NET Core) , 66 byte

a=>{double r=1,x=1,y=1,i=0;for(;++i<a;y+=x,x=y-x)r+=1/y;return r;}

Hãy thử trực tuyến!

Không thể sử dụng phao vì không chính xác.

Ví dụ trong đó input = 8:

  • gấp đôi: 3,28287545787546 (làm tròn thành 3,282875)
  • số float: 3.282876 (giảm 0,000001)

Ung dung:

a => {
    double r = 1,                       // initialize r (sum of reciprocals) - start at 1 to save one byte in for loop
            x = 1, y = 1,                   // initialize x (2nd largest Fibonacci) and y (largest Fibonacci)
            i = 0;                          // initialize i (loop counter)
    for(; ++i < a; y += x, x = y - x)   // from 1 to a, while incrementing the Fibonacci numbers
        r += 1 / y;                         // increment the reciprocal Fibonacci
    return r;                           // return the reciprocal Fibonacci
}

1

RPL (HP 49G / G + / 50g), 50 byte

« 0. 1. DUP2 5. ROLL
  START SWAP OVER + ROT OVER INV + UNROT
  NEXT DROP2
»

Ví dụ:

10 -> 3.33046904076

11 -> 3.34170499582

30 -> 3.35988372158

55 -> 3.35988566622

Về lý thuyết, tổng của 55 chữ số đầu tiên sẽ cho 12 chữ số chính xác. Chữ số cuối cùng phải là '4' thay vì '2'. Điều này cần được khắc phục bằng cách thêm các điều khoản ngược lại, nhưng mã sẽ dài hơn một chút.

Nếu hằng số được tính đến 1000 vị trí thập phân bằng cách sử dụng định nghĩa, thì tổng số phải được thực hiện theo ít nhất 4790 thuật ngữ đầu tiên, điều này sẽ mất quá nhiều thời gian trên HP 50g, nếu có thể. Đối với tác vụ này, cần có một phương thức hiệu quả hơn, như phương thức được sử dụng trong chương trình RPL sau (464 byte, tổng kiểm tra # 207Eh) có đối số là số thập phân mong muốn:

%%HP: T(3)A(R)F(.);
\<< PUSH RAD -105 CF -3 CF R\->I DUP 1 + 2 INV SWAP 100 LN * 5 LN + OVER ASINH / \v/ * CEIL DUP 2 MOD + DUP 0 ROT
[[ 1 1 ]
 [ 1 0 ]] SWAP DUP2 ^ 3 GETI UNROT GET 4 ROLLD 4 ROLLD DUP + ^ 1 GETI UNROT GET 1 + 0 1 8 ROLL 2 /
  START PICK3 + DUP PICK3 * NEG 6 PICK SQ + / 4 PICK SQ * EXPAND ROT PICK3 - ROT OVER - ROT 6 ROLL 6 ROLL 6 ROLL + LASTARG * LASTARG 5 ROLLD 5 ROLLD / + ROT PICK3 - ROT OVER - 6 ROLL 6 ROLL 6 ROLL
  NEXT ROT + INV 5 ROLL + EXPAND 4 ROLLD 3 DROPN FXND PICK3 ALOG OVER - PICK3 * SWAP IQUOT + \->STR DUP HEAD -51 FC? { "." } { "," } IFTE + SWAP TAIL + 1 ROT 2 + SUB POP
\>>

'RFC' STO

1000 RFC ->

3.3598856662431775531720113029189271796889051337319684864955538153251303189966833836154162164567900872970453429288539133041367890171008836795913517330771190785803335503325077531875998504871797778970060395645092153758927752656733540240331694417992939346109926262579646476518686594497102165589843608814726932495910794738736733785233268774997627277579468536769185419814676687429987673820969139012177220244052081510942649349513745416672789553444707777758478025963407690748474155579104200675015203410705335285129792635242062267537568055761955669720848843854407983324292851368070827522662579751188646464096737461572387236295562053612203024635409252678424224347036310363201466298040249015578724456176000319551987905969942029178866949174808096746523682654086938399069873211752166957063859411814553647364268782462926166650100098903804823359519893146150108288726392887669917149304053057745574321561167298985617729731395370735291966884327898022165047585028091806291002444277017460241040417786069190065037142835294294

(22 phút 23 giây, trên HP 50g thực)


Đối với một nghìn chữ số, 50 số hạng đầu tiên của chuỗi cộng với 50 số hạng khác của phân số tiếp tục được ước tính, hai số chỉ trong 25 lần lặp lại (mặc dù 48 thuật ngữ của mỗi số sẽ có hiệu lực). Một chương trình DECIMAL BASIC tương đương chỉ mất 10 mili giây trên máy tính của tôi (Intel (R) Core (TM) Duo CPU E4700 @ 2.6 GHz).


1

JAEL, 9 7 byte

Thay đổi dấu phụ từ ký tự này sang ký tự khác cho tôi 1 byte

Vẫn đang làm việc trên mã hóa SBCS.

#`&@uȦ

Giải thích (được tạo tự động):

./jael -u explain '#`&@uȦ'

ORIGINAL CODE:
#`&@uȦ

EXPANDING EXPLANATION:
Ȧ => .a!

EXPANDED CODE:
#`&@u.a!

COMPLETED CODE:
#`&@u.a!,


#       ,               repeat (p1) times:
 `                              stack 1
  &                             push number of iterations of this loop
   @                            push nth fibonacci number
    u                           push p2 / p1
     .                          push the value under the tape head
      a                         push p1 + p2
       !                        write p1 to the tapehead
         ␄              print machine state

Vâng bạn đã đúng. Tôi đã nhầm lẫn nó.
Eduardo Hoefel

Tôi biết ngôn ngữ được tối ưu hóa cho các ký tự, nhưng trang web này ghi điểm theo byte, do đó, việc bao gồm số lượng ký tự
Jo King

Bạn có thể nhận được 8 byte nếu bạn không nén u.. Về chủ đề SBCS, bạn có thể gặp rắc rối vì tài liệu của bạn liệt kê hơn 600 lệnh hoặc tổ hợp lệnh và ngôn ngữ SBCS chỉ có thể có 256 lệnh byte đơn. Mặt khác, có một số lượng lớn các bản dịch từ một đến vô dụng ...
Jo King

Có @JoKing, bạn đúng. Tôi đã bắt đầu toàn bộ ý tưởng một lúc trước và không nghĩ rằng nó sẽ ảnh hưởng đến kích thước byte. Bây giờ tôi đang viết luận án đại học của mình trên JAEL và đã quá muộn để xem xét lại một số quyết định (tôi sẽ trình bày nó vào cuối tháng 11). Về danh sách lệnh: có, nó được tạo tự động và tôi không chú ý đủ. Vì đây là dự án đầu tiên của tôi trong lĩnh vực này, tôi sẽ thu thập kinh nghiệm và cố gắng học hỏi từ những quyết định tồi tệ. Cảm ơn bạn đã chia sẻ suy nghĩ của bạn!
Eduardo Hoefel


1

cQuents , 13 11 byte

;/b$
=1:Z+Y

Hãy thử trực tuyến!

Giải trình

;          The sum of the first n terms of the sequence
 /         which are 1 divided by
  b$       the nth term in the sequence on the second line

=1:Z+Y     Fibonacci with starting indexes 1,1
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.