Đơn giản hóa một phần tiếp tục


21

Các phân số tiếp tục là các biểu thức mô tả các phân số lặp đi lặp lại. Chúng có thể được biểu thị bằng đồ họa:

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

Hoặc chúng có thể được biểu diễn dưới dạng danh sách các giá trị: [a0; a1, a2, a3, ... an]

Các thách thức:

lấy một số cơ sở: và một danh sách các giá trị mẫu số: và đơn giản hóa phân số tiếp tục thành một phân số hợp lý đơn giản: trả về hoặc in tử số và mẫu số riêng biệt.a0[a1, a2, a3, ... an]

Ví dụ:

  • √19 : [4;2,1,3,1,2]: 170/39
  • ℯ: [1;0,1,1,2,1,1]: 19/7
  • π: [3;7,15,1,292,1]: 104348/33215
  • ϕ: [1;1,1,1,1,1]: 13/8

Ví dụ thực hiện: (python)

def foo(base, sequence):
    numerator = 1
    denominator = sequence[-1]
    for d in sequence[-2::-1]:
        temp = denominator
        denominator = d * denominator + numerator
        numerator = temp
    return numerator + base * denominator, denominator

Chiến thắng:

mã ngắn nhất tính bằng byte: - không có nội dung nào thực hiện toàn bộ vấn đề được phép--


Bạn nên làm cho câu này rõ ràng hơn, "và đơn giản hóa phân số tiếp tục thành một phân số duy nhất"; trừ khi bạn dự định từ ngữ có nghĩa là kết quả của 2.002có thể được thể hiện là 2002/1000. Về mặt kỹ thuật đó là một "phân số duy nhất", có lẽ bạn muốn nói, "một phân số duy nhất, ở dạng đơn giản nhất của nó."
Bạch tuộc ma thuật Urn

@carusocomputing đã lấy điểm .. mặc dù tôi sẽ không cảm thấy quá tệ về 2/4 (hoặc tương tự) vì nó vẫn đơn giản hóa cấu trúc nhiều phân số thành một phân số duy nhất
Aaron

Hmm ... Tôi nghĩ rằng có một cách để khai thác điều đó, nhưng với câu trả lời golf 13 byte, có lẽ tôi phải sử dụng MATL để giành chiến thắng.
Bạch tuộc ma thuật Urn

@carusocomputing Tôi muốn nói rằng hãy làm điều đó ... Nếu bạn có thể đánh bại câu trả lời 13 byte, điều đó thật tuyệt vời
Aaron

Bạn có thể làm cho pi dừng lại sớm hơn - 355/113.
Thorbjørn Ravn Andersen

Câu trả lời:


15

J, 8 5 byte

Tương tự như thế này , nhưng sử dụng tích hợp cho các lý do.

Đối số là {a0, a1, a2, a3, ...} là một danh sách các số hữu tỷ chính xác mở rộng J. Kết quả là một phần như một số hữu tỷ chính xác mở rộng J.

(+%)/

(+%) cộng-tương ứng-của

/ giảm hơn

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

-3 nhờ dặm .


Nếu bạn lấy đầu vào làm danh sách các số nguyên mở rộng, bạn có thể lưu 3 byte. Ngoài ra, bạn đã sử dụng bộ phận APL trong giải thích.
dặm

@miles Cảm ơn. Không thể đến gần hơn với lệnh cấm tích hợp hơn thế. Quá tệ J không có một nhân vật cấu thành hook như Dyalog APL's .
Adám

Liên kết thử J trực tuyến bị hỏng
Chiel ten Brinke

@ChieltenBrinke Cảm ơn. Đã sửa.
Adám

12

Haskell, 37 36 18 byte

foldr1$(.(1/)).(+)

Hàm này hy vọng Ratioloại của Haskell là đầu vào. Ví dụ sử dụng:

Prelude Data.Ratio> ( foldr1$(.(1/)).(+) )  [4%1,2,1,3,1,2] 
170 % 39

Lưu ý: một rõ ràng Ratiotrong danh sách đầu vào ( 4%1) là đủ, các hệ thống loại chỉ ra rằng các hệ thống khác cũng phải là Ratios.

Chỉnh sửa: @Lynn đã lưu một byte. Cảm ơn!

Chỉnh sửa II: đã xóa import(xem phần thảo luận này trên meta ).


1
Oooh, trường hợp cạnh đẹp. Hàm này là đa hình, vì vậy nó không cần import. Tuy nhiên, để gọi nó, bạn phải cung cấp Ratios cho nó mà cần import. Tôi có nên thêm importsố byte hay không?
nimi

1
Nghe có vẻ là một câu hỏi hay cho meta.
Martin Ender

Tôi chưa bao giờ sử dụng Haskell, vì vậy hãy sửa cho tôi nếu tôi sai, nhưng nếu công cụ tương tự python sẽ là: from fractions import Fractionthực hiện các thao tác với Fractioncác đối tượng, thì câu lệnh nhập cũng được tính.
Aaron


@Aaron: vấn đề là: định nghĩa của hàm không cần nhập, vì nó đa hình. Khi bạn muốn gọi nó, bạn cần cung cấp số loại Ratiochỉ có thể được xây dựng thông qua %, yêu cầu nhập. Thông thường chúng ta không đếm byte để gọi qua đầu, chỉ cho chính chức năng.
nimi

11

GolfScript , 13 byte

~]-1%{\-1?+}*

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

Yay cho các lý do ẩn của GolfScript . :)

Giải trình

Loại số "chính thức" duy nhất của GolfScript là số nguyên. Nhưng toán tử lũy thừa không đưa kết quả của nó thành số nguyên và thuận tiện là kết quả gốc của phép lũy thừa số nguyên trong Ruby (ngôn ngữ của trình thông dịch của GolfScript) là một số hữu tỷ. Vì vậy, chúng ta có thể dễ dàng nhận được phân số bằng cách nâng thứ gì đó lên lũy thừa -1. Thuận tiện, dù sao chúng tôi cũng muốn có đối ứng ...

~]     # Evaluate input and wrap all a_i in a list.
-1%    # Reverse the list so that a_n is at the start and a_0 at the end.
{      # Fold... (apply this block to each element from a_n-1 down to a_0, with
       # the previous result on the stack)
  \    #   Swap previous result with current a_i.
  -1?  #   Raise previous result to the power of -1, computing its reciprocal
       #   as a rational number.
  +    #   Add a_i.
}*

11

Toán học, 23 22 byte

Fold[#2+1/#&]@*Reverse

Về cơ bản là một cổng của câu trả lời GolfScript của tôi . Đây là một số lựa chọn:

Đối với 24 byte, chúng ta có thể viết một hàm matrixdic đệ quy:

f@n_=n
n_~f~m__:=n+1/f@m

Đối với 21 byte, chúng ta thậm chí có thể định nghĩa một "toán tử dao động", nhưng quy ước gọi của nó sẽ rất kỳ lạ, đến nỗi tôi không muốn đếm cái này:

±n_=n
n_ ±m__:=n+1/±m

Bạn sẽ phải gọi điều này với một chuỗi các giá trị đầu vào, ví dụ ±Sequence[3, 7, 15, 1, 292, 1]hoặc ±##&[3, 7, 15, 1, 292, 1].

Và cũng với 21 byte, sẽ có (cấm) tích hợp:

FromContinuedFraction

10

LabVIEW, 36 byte tương đương

Khá đơn giản thực hiện chuyển tiếp ngây thơ bằng thuật toán của OP. Có cách nào đẹp hơn để làm điều này?

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


5
Bằng kỹ sư điện của bạn đang hiển thị.
Bạch tuộc ma thuật Urn

1
@ijustlovemath Đạo cụ, nhưng ..... có liên quan
Aaron

Vâng, đó là một ngôn ngữ gây tranh cãi để chắc chắn. Tôi thấy LabVIEW là "Tôi ghét toán học" của thế giới lập trình viên. Vấn đề không phải là toán học, mà là nó được dạy như thế nào (hay thường là thiếu giảng dạy).
ijustlovemath

6

APL Dyalog , 10 byte

Thậm chí không sử dụng tích hợp cho hợp lý.

Lấy {a 0 , a 1 , a 2 , 3 , ...} làm đối số, trả về {mẫu số, tử số}.

1(,÷∨)+∘÷/

1(,÷∨) 1 - dự kiến ​​chia cho GCD của 1 và

+∘÷ cộng-đối ứng-của

/ giảm hơn

Dùng thử trực tuyến!


6

Python 2, 62 byte

a=d=0
b=c=1
for n in input():a,b=b,n*b+a;c,d=d,n*d+c
print b,d

Thật không may, không phải là golf (xem câu trả lời của @ xnor ngắn hơn), nhưng nó tính toán phân số mà không cần phải đảo ngược đầu vào. Điều này sử dụng phương pháp "bảng ma thuật" cho các điểm hội tụ - được đưa ra hai phân số cuối cùng a/cb/d, phân số tiếp theo là (n*b+a)/(n*c+d).

Ví dụ: đối với pi:

          3    7    15     1      292        1

  0   1   3   22   333   355   103993   104348
  1   0   1    7   106   113    33102    33215

Chúng ta có thể thấy rằng 15*22 + 3 = 333, 15*7 + 1 = 106, 1*333 + 22 = 355, 1*106 + 7 = 113vv


4

M, 5 byte

Ṛİ+¥/

Đầu vào là một danh sách các giá trị [a0, a1, ..., aN]và nó đưa ra một số hữu tỷ.

Hãy thử trực tuyến! hoặc Xác minh tất cả các trường hợp thử nghiệm.

Giải trình

Ṛİ+¥/  Input: list A
Ṛ      Reverse A
    /  Reduce A from left to right using
   ¥     A dyadic chain
 İ         Take the reciprocal of the left value
  +        Add the reciprocal to the right value
       Return and print implicitly

1
Cái gì thế này? Một số phương ngữ Jelly mới?
Adám

@miles thực sự 9 byte xin lỗi :(
Aaron

@ Adám Đó là một ngã ba cũ của Jelly có nghĩa là toán học và tượng trưng. Đây là repo Github của nó .
dặm

1
@Aaron M sử dụng cùng một trang mã với Jelly và nó có thể được mã hóa bằng một byte cho mỗi ký tự.
dặm

@miles OK, đã thêm .
Adám

4

Haskell, 30 byte

foldr(\h(n,d)->(h*n+d,n))(1,0)

Đệ quy cho biết thêm mỗi lớp đi ra ngoài, cập nhật n/dtới h+(1/(n/d)), bằng h+d/nhoặc (h*n+d)/n. Các phần được lưu trữ như là một tuple của (num,denom). Các phần ban đầu của (1,0)flips đến 0/1đó là 0.


3

Python, 50 byte

f=lambda l,n=1,d=0:l and f(l,l.pop()*n+d,n)or(n,d)

Xây dựng phân số tiếp tục từ cuối danh sách trở về sau, liên tục cập nhật phân số n/dtrên phần tử cuối cùng xn/d -> 1+1/(n/d) == (x*n+d)/n.


3

 Lisp thường gặp, 54

Một phần gấp đôi bên phải:

(lambda(s)(reduce(lambda(a r)(+(/ r)a))s :from-end t))

Xét nghiệm

PASS  NAME  ACTUAL               EXPECTED
===============================================
T     √19   170/39               170/39              
T     ℯ     19/7                 19/7                
T     π     104348/33215         104348/33215        
T     ϕ     13/8                 13/8                

2

Julia (53 byte)

Đây là lần đầu tiên tôi sử dụng Julia, nếu tôi bỏ qua một trình vòng lặp, tôi có thể đã sử dụng để mất thêm một số byte, hãy cho tôi biết. Đây là một gợi ý cho bất cứ ai không biết nên chọn ngôn ngữ nào cho thử thách cụ thể này: https://en.wikipedia.org/wiki/Rational_data_type

f(x,c)=(a=0;for b in x[end:-1:1];a=1//(b+a);end;a+c;)
  • Đảo ngược mảng đầu vào.
  • Lặp lại thông qua nó với sự phân chia hợp lý.
  • Thêm c vào kết quả thập phân.

bạn có thể lưu hai byte bằng cách xác định một toán tử (ví dụ ) thay vì một hàm
Tasos Papastylianou

đồng thời, thay đổi vòng lặp for trong một thời gian và bật:x∘c=(a=0;while x!=[];a=1//(pop!(x)+a);end;a+c;)
Tasos Papastylianou

1
25: x->foldr((x,y)->x+1//y,x)(giống như giải pháp Haskell). cách sử dụng:(x->foldr((x,y)->x+1//y,x))([4//1,2,1,3,1,2])
Fengyang Wang

Ooo ... Một chức năng gấp ngược? Thật là đẹp! Tôi không xứng đáng nhận được tín dụng cho điều đó mặc dù haha.
Bạch tuộc ma thuật Urn

2

Javascript (ES6), 55 byte

s=>eval('for(F=[1,0];s+"";)F=[s.pop()*F[0]+F[1],F[0]]')

Các trường hợp thử nghiệm

var f =
s=>eval('for(F=[1,0];s+"";)F=[s.pop()*F[0]+F[1],F[0]]')

console.log(f([4, 2, 1, 3, 1, 2]));
console.log(f([1, 0, 1, 1, 2, 1, 1]));
console.log(f([3, 7, 15, 1, 292, 1]));
console.log(f([1, 1, 1, 1, 1, 1]));


2

CJam , 18 16 byte

XUq~W%{2$*+\}/]p

Phiên dịch trực tuyến .

XU                  Push 1 and 0 to the stack
  q~W%              Push input, eval and reverse it
      {     }/      For each n in the reversed input...
       2$             Copy numerator
         *+           Calculate n*denominator + numerator
           \          Swap numerator and denominator
              ]p   Wrap in array and output

2

05AB1E , 19 17 byte

R¬V¦vyY*X+YUV}YX)

Giải trình

Đầu vào được lấy làm danh sách các số

                     # variable X is initialized as 1
R¬V¦                 # reverse the list, remove the first item and store it in variable Y
    v        }       # for each item N left in list
     yY*X+  V        # store N*Y+X in Y
          YU         # store Y in X
              YX)    # wrap X and Y in a list

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


2

JavaScript (ES6), 44 byte

a=>a.reduceRight(([n,d],v)=>[v*n+d,n],[1,0])

1

Javascript (ES6), 50 byte

f=(s,n=1,d=s.pop())=>s+""?f(s,d,s.pop()*d+n):[d,n]

Đó là nhờ câu trả lời của Arnauld, trước khi nhìn thấy nó, tôi đã bị mắc kẹt với 66 byte:

f=(b,s,i=s.length-1,n=1,d=s[i])=>i?f(b,s,--i,d,s[i]*d+n):[n+b*d,d]

Ví dụ:
Gọi: f([1, 0, 1, 1, 2, 1, 1])
Đầu ra:Array [ 19, 7 ]


1

Perl 6 , 24 byte

{[R[&(1/*+*)]](@_).nude}

Giải trình:

  • 1 / * + *là một lambda có hai tham số ( *) lấy đối ứng của cái đầu tiên và thêm cái thứ hai. (trả lại một con chuột )

  • R[&(…)]sử dụng nó như thể nó là một toán tử infix và đảo ngược nó.
    (bao gồm làm cho nó đúng liên kết)

  • […](@_) lấy đó và sử dụng nó để giảm đầu vào.

  • … .nudetrả lại nu merator và de nomator of the Rat .

  • { … }làm cho nó một lambda khối trần với tham số ngầm @_.

Sử dụng:

say {[R[&(1/*+*)]](@_).nude}(3,7,15,1,292,1) #*/# (104348 33215)

my &code = {[R[&(1/*+*)]](@_).nude}; # stupid highlighter */

say code 4,2,1,3,1,2;    # (170 39)
say code 1,0,1,1,2,1,1;  # (19 7)
say code 1,1,1,1,1,1;    # (13 8)

1

Zephyr , 145 byte

input n as Integer
set a to Array(n)
for i from 1to n
input a[i]as Integer
next
set r to a[n]
for i from 1to n-1
set r to(/r)+a[n-i]
next
print r

Zephyr là ngôn ngữ lập trình đầu tiên tôi từng tạo ra. Nó được thiết kế trực quan và có cú pháp rõ ràng - thay vì tốn kém. Tại sao tôi chơi golf với nó, bạn hỏi? Bởi vì, không giống như bất kỳ ngôn ngữ nào tôi đã viết từ đó, nó có loại tích hợp sẵn Fraction. Bạn thậm chí có thể sử dụng toán tử chia /làm toán tử đơn nguyên cho "nghịch đảo" (một tính năng tôi đã mượn cho Pip).

Bây giờ, có những hạn chế đáng kể. Vấn đề lớn nhất đối với thách thức này là các mảng phải được xác định với kích thước cố định, có nghĩa là chương trình bắt đầu bằng cách đọc kích thước của mảng từ người dùng. (Tôi hy vọng điều này là ổn; giải pháp thay thế là mã hóa kích thước.) Ngoài ra còn có một vấn đề nhỏ mà ưu tiên toán tử không tồn tại, có nghĩa là các biểu thức đa toán tử phải có dấu ngoặc đơn.

Đây là một ví dụ chạy:

C:\Zephyr> python zephyr.py contfrac.zeph
6
1
1
1
1
1
1
13/8

1

Ruby, 34 byte

->a{a.reverse.inject{|b,i|i+1r/b}}

Điều này thực hiện một nếp gấp bên phải (bằng cách đảo ngược và sau đó gập trái), thêm mỗi phần tử thành 1 trên tổng số đang chạy (các phần tử ở bên phải). Ruby có kiểu Rational, rất hay. Và hợp lý theo nghĩa đen là một số có hậu tố r.


1

Stax , 4 byte

╣╩┼►

Chạy và gỡ lỗi nó

Nhỏ như nó là, nó không phải là một tích hợp. Các hợp lý tích hợp giúp khá nhiều mặc dù. Giải nén vào ascii, chương trình là rksu+.

  1. Đảo ngược mảng.
  2. Gấp mảng bằng cách sử dụng (a, b) => (a + 1/b).

1

APL (NARS), ký tự 15 + 1, 30 + 2 byte

{1=≢⍵:↑⍵⋄+∘÷/⍵}

Dịch trong Apl (Nars) từ giải pháp Adam J ... đầu vào được phép cho hàm đó sẽ là tất cả danh sách các số nguyên, trong đó phần tử đầu tiên sẽ có kiểu hợp lý. Kiểm tra:

  f←{1=≢⍵:↑⍵⋄+∘÷/⍵}      
  f 4x 2 1 3 1 2
170r39 
  f 1x 0 1 1 2 1 1
19r7 
  f 3x 7 15 1 292 1
104348r33215 
  f 1x 1 1 1 1 1
13r8 
  f 3x 89 888 999 11 222 373 7282 9272 3839 2828 
158824716824887954093160207727r52744031585005490644982548907 
  f ,0x
0 
  f ,9x
9 

vì vậy nó sẽ là 15 ký tự theo độ dài của hàm và 1 char cho "x" để nhập loại đầu vào tôi muốn và thoát khỏi loại tôi muốn ...

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.