ลดความซับซ้อนเศษส่วนต่อเนื่อง


21

เศษส่วนต่อเนื่องเป็นนิพจน์ที่อธิบายเศษส่วนซ้ำ ๆ พวกเขาสามารถแสดงกราฟิก:

ป้อนคำอธิบายรูปภาพที่นี่

หรือพวกเขาสามารถแสดงเป็นรายการของค่า: [a0; a1, a2, a3, ... an]

ความท้าทาย:

ใช้หมายเลขฐาน: และรายการค่าส่วน: และทำให้เศษส่วนต่อเนื่องเป็นเศษส่วนเชิงเหตุผลที่ทำให้ง่ายขึ้น: ส่งคืนหรือพิมพ์เศษและส่วนที่แยกจากกันa0[a1, a2, a3, ... an]

ตัวอย่าง:

  • √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

ตัวอย่างการนำไปใช้: (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

ชนะ:

โค้ดที่สั้นที่สุดในหน่วยไบต์: - บิวด์อินที่ทำปัญหาทั้งหมดได้รับอนุญาต -


คุณควรทำให้ประโยคนี้ชัดเจนยิ่งขึ้น "และทำให้เศษส่วนต่อเนื่องเป็นเศษส่วนเดียวให้ง่ายขึ้น"; เว้นแต่ว่าคุณตั้งใจถ้อยคำหมายถึงผลมาจากความสามารถแสดงเป็น2.002 2002/1000นั่นเป็นเทคนิค "เศษส่วนเดียว" คุณอาจต้องการพูดว่า "เศษส่วนเดียวในรูปแบบที่ง่ายที่สุด"
Magic Octopus Urn

@carusocomputing point .. .. แม้ว่าฉันจะไม่รู้สึกแย่เกินไปเกี่ยวกับ 2/4 (หรือคล้ายกัน) เนื่องจากมันยังคงทำให้โครงสร้างเศษส่วนหลายส่วนเป็นเศษส่วนเดียวได้ง่ายขึ้น
Aaron

อืม ... ฉันคิดว่ามันมีวิธีที่จะใช้ประโยชน์จากสิ่งนั้น แต่ด้วยคำตอบ 13 byte golfscript ฉันอาจต้องใช้ MATL เพื่อชนะ
Magic Octopus Urn

@carusocomputing ฉันจะบอกว่าไป ... ถ้าคุณสามารถเอาชนะคำตอบที่ 13 byte, นั่นจะน่ากลัว
Aaron

คุณสามารถหยุด pi ก่อนหน้าได้ - 355/113
Thorbjørn Ravn Andersen

คำตอบ:


15

J, 8 5 ไบต์

เช่นนี้แต่ใช้ build-in สำหรับ rationals

อาร์กิวเมนต์คือ {a0, a1, a2, a3, ... } เป็นรายการของ J ที่เพิ่มความแม่นยำของจำนวนตรรกยะ ผลลัพธ์คือส่วนที่เป็นจำนวนตรรกยะที่แม่นยำของ J

(+%)/

(+%) เครื่องหมายบวกซึ่งกันและกัน

/ ลดลงมากกว่า

ลองออนไลน์!

-3 ต้องขอบคุณไมล์


หากคุณรับอินพุตเป็นรายการจำนวนเต็มส่วนขยายคุณสามารถบันทึกได้ 3 ไบต์ นอกจากนี้คุณยังใช้ส่วน APL ในคำอธิบาย
ไมล์

@miles ขอบคุณ ไม่สามารถเข้าใกล้ข้อห้ามในตัวได้มากกว่านี้ เลวร้ายเกินไป J ไม่ได้มีลักษณะองค์ประกอบเช่นเบ็ด Dyalog APL
อดัม

ลองลิงก์ J ออนไลน์เสีย
Chiel ten Brinke

@ChieltenBrinke ขอบคุณ คงที่
Adám

12

Haskell, 37 36 18 ไบต์

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

ฟังก์ชันนี้คาดว่าRatioชนิดของ Haskell เป็นอินพุต ตัวอย่างการใช้งาน:

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

หมายเหตุ: หนึ่งรายการที่ชัดเจนRatioในรายการอินพุต ( 4%1) ก็เพียงพอแล้วระบบพิมพ์จะระบุว่าคนอื่น ๆ ต้องเป็นRatios ด้วยเช่นกัน

แก้ไข: @Lynn บันทึกไบต์ ขอบคุณ!

แก้ไข II: ลบimport(ดูการสนทนาเกี่ยวกับเมตา )


1
Oooh ตัวเรือนขอบดี ฟังก์ชั่นที่ตัวเองเป็น polymorphic importดังนั้นจึงไม่จำเป็นต้อง อย่างไรก็ตามจะเรียกมันว่าคุณมีฟีดของมันซึ่งไม่จำเป็นที่จะต้องRatio importฉันควรจะเพิ่มimportจำนวนไบต์หรือไม่?
nimi

1
ฟังดูเหมือนเป็นคำถามที่ดีสำหรับเมตา
Martin Ender

ฉันไม่เคยใช้ Haskell ดังนั้นแก้ไขให้ถูกต้องถ้าฉันผิด แต่ถ้า python equivelent เท่ากับ: from fractions import FractionการดำเนินการกับFractionวัตถุก็จะนับรวมคำสั่ง import
แอรอน

.. เรามีก่อนที่จะ
nimi

@Aaron: ปัญหาคือ: ความหมายของฟังก์ชั่นไม่จำเป็นต้องมีการนำเข้าเพราะมันเป็น polymorphic เมื่อคุณต้องการโทรหาคุณจะต้องระบุจำนวนประเภทRatioที่สามารถสร้างได้ผ่านทาง%เท่านั้นซึ่งต้องนำเข้า โดยปกติแล้วเราจะไม่นับจำนวนไบต์สำหรับการเรียกค่าใช้จ่าย
nimi

11

GolfScriptขนาด 13 ไบต์

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

ลองออนไลน์!

เย้สำหรับ GolfScript ของrationals ซ่อน :)

คำอธิบาย

GolfScript มีเฉพาะหมายเลข "เป็นทางการ" เท่านั้น แต่ตัวดำเนินการยกกำลังไม่ได้แสดงผลลัพธ์เป็นจำนวนเต็มและผลลัพธ์ดั้งเดิมของการยกกำลังเลขชี้กำลังใน Ruby (ภาษาของล่ามของ GolfScript) เป็นตัวเลขที่มีเหตุผล ดังนั้นเราสามารถหาเศษส่วนได้ง่าย ๆ โดยการเพิ่มบางสิ่งให้เป็นพลังของ -1 เราต้องการความสะดวกซึ่งกันและกัน ...

~]     # 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

Mathematica, 23 22 ไบต์

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

หลักพอร์ตของคำตอบ GolfScript ของฉัน นี่คือทางเลือก:

สำหรับ 24 ไบต์เราสามารถเขียนฟังก์ชัน variadic แบบเรียกซ้ำได้:

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

สำหรับ 21 ไบต์เราสามารถกำหนด "โอเปอเรเตอร์ผันแปร" ได้ แต่การเรียกใช้มันจะแปลกมากจนฉันลังเลที่จะนับสิ่งนี้:

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

คุณจะต้องเรียกสิ่งนี้กับลำดับของค่าการป้อนข้อมูลเช่นหรือ±Sequence[3, 7, 15, 1, 292, 1]±##&[3, 7, 15, 1, 292, 1]

และสำหรับ 21 ไบต์ก็จะมีตัว (ต้องห้าม) ในตัว:

FromContinuedFraction

10

LabVIEW ขนาดเทียบเท่า 36 ไบต์

การปฏิบัติที่ไร้เดียงสาตรงไปตรงมาอย่างยุติธรรมโดยใช้อัลกอริทึมของ OP มีวิธีที่ดีกว่าในการทำเช่นนี้?

ป้อนคำอธิบายรูปภาพที่นี่


5
ปริญญาวิศวกรรมไฟฟ้าของคุณกำลังแสดง
Magic Octopus Urn

1
@ijustlovemath อุปกรณ์ประกอบฉาก แต่ ..... เกี่ยวข้อง
Aaron

ใช่มันเป็นภาษาที่ถกเถียงกันเพื่อให้แน่ใจ ฉันเห็น LabVIEW ว่า "ฉันเกลียดคณิตศาสตร์" ของโปรแกรมเมอร์โลก ปัญหาไม่ใช่คณิตศาสตร์ แต่เป็นวิธีการสอน (หรือบ่อยครั้งที่ขาดการสอนเลย)
ijustlovemath

6

Dyalog APL ขนาด 10 ไบต์

ไม่ได้ใช้ build-in สำหรับ rationals

รับ {a 0 , a 1 , a 2 , 3 , ... } เป็นอาร์กิวเมนต์ส่งคืน {denominator ตัวเศษ}

1(,÷∨)+∘÷/

1(,÷∨) 1- เตรียมการเพื่อหารด้วย GCD ของ 1 และ

+∘÷ บวก-the-ซึ่งกันและกันของ

/ ลดลงมากกว่า

ลองใช้ออนไลน์!


6

Python 2, 62 ไบต์

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

มันน่าเสียดายที่ไม่เหมือนกอล์ฟ (ดูคำตอบที่ @ xnorสำหรับคำย่อที่สั้นกว่า) แต่มันจะคำนวณเศษส่วนโดยไม่จำเป็นต้องย้อนกลับอินพุต นี้ใช้ตาราง "มายากล"แนวทางในการ convergents - รับทั้งสองเศษส่วนที่ผ่านมาa/cและเศษต่อไปคือb/d(n*b+a)/(n*c+d)

ตัวอย่างเช่นสำหรับ pi:

          3    7    15     1      292        1

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

เราจะเห็นว่า15*22 + 3 = 333, 15*7 + 1 = 106, 1*333 + 22 = 355, 1*106 + 7 = 113ฯลฯ


4

M, 5 ไบต์

Ṛİ+¥/

อินพุตเป็นรายการของค่า[a0, a1, ..., aN]และส่งออกจำนวนตรรกยะ

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย

Ṛİ+¥/  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
นี่คืออะไร? ภาษาถิ่นของ Jelly ใหม่หรือไม่
อดัม

@miles จริงๆแล้ว9 ไบต์ขออภัย :(
แอรอน

@ Adámมันเป็นทางแยกเก่าแก่ของ Jelly สำหรับคณิตศาสตร์และสัญลักษณ์ นี่คือมัน repo Github
ไมล์

1
@Aaron M ใช้หน้ารหัสเดียวกันกับเยลลี่และสามารถเข้ารหัสได้โดยใช้ไบต์สำหรับอักขระแต่ละตัว
ไมล์

@miles ตกลงเพิ่มแล้ว
อดัม

4

Haskell ขนาด 30 ไบต์

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

เพิ่มแต่ละเลเยอร์ออกไปข้างนอกซ้ำ ๆn/dเพื่ออัพเดตh+(1/(n/d))ซึ่งเท่ากับh+d/n(h*n+d)/nหรือ ส่วนที่ถูกเก็บไว้เป็น tuple (num,denom)ของ ส่วนเริ่มต้นของการ(1,0)พลิกไปซึ่งเป็น0/10


3

Python ขนาด 50 ไบต์

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

สร้างส่วนต่อจากจุดสิ้นสุดของรายการที่เกิดขึ้นหลังการปรับปรุงซ้ำ ๆ เศษn/dในองค์ประกอบสุดท้ายเป็นxn/d -> 1+1/(n/d) == (x*n+d)/n


3

 เสียงกระเพื่อมสามัญ, 54

พับค่อนข้างขวา verbose:

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

การทดสอบ

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

จูเลีย (53 ไบต์)

นี่เป็นครั้งแรกที่ฉันใช้จูเลียถ้าฉันมองข้ามตัววนซ้ำฉันอาจเคยสูญเสียจำนวนไบต์ที่เพิ่มขึ้นบ้างบอกให้ฉันรู้ นี่คือคำใบ้สำหรับทุกคนที่ไม่ทราบว่าจะเลือกภาษาใดสำหรับความท้าทายเฉพาะนี้: 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;)
  • ย้อนกลับอาร์เรย์ใส่
  • วนซ้ำโดยใช้เหตุผลแบ่ง
  • เพิ่ม c ไปยังผลลัพธ์ทศนิยม

คุณสามารถบันทึกสองไบต์ด้วยการกำหนดโอเปอเรเตอร์ (เช่น) แทนฟังก์ชั่น
Tasos Papastylianou

และเปลี่ยนการวนซ้ำเป็นระยะเวลาหนึ่งและป๊อป: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)(เหมือนกับ Haskell solution) การใช้งาน:(x->foldr((x,y)->x+1//y,x))([4//1,2,1,3,1,2])
Fengyang Wang

Ooo ... ฟังก์ชั่นพับกลับได้ไหม? นั่นสวยมาก! ฉันไม่สมควรได้รับเครดิตสำหรับเรื่องนี้แม้ว่าฮ่าฮ่า
Magic Octopus Urn

2

Javascript (ES6), 55 ไบต์

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

กรณีทดสอบ

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 ไบต์

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

ล่ามออนไลน์

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 ไบต์

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

คำอธิบาย

อินพุตถูกใช้เป็นรายการของตัวเลข

                     # 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

ลองออนไลน์!



1

Javascript (ES6), 50 ไบต์

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

ขอบคุณคำตอบของ Arnauld ก่อนเห็นฉันติดอยู่ที่ 66 ไบท์:

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]

ตัวอย่าง: การ
โทร: f([1, 0, 1, 1, 2, 1, 1])
เอาท์พุท:Array [ 19, 7 ]


1

Perl 6 , 24 ไบต์

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

คำอธิบาย:

  • 1 / * + *เป็นแลมบ์ดาที่มีพารามิเตอร์สองตัว ( *) ซึ่งรับค่าส่วนกลับของค่าแรกและเพิ่มค่าที่สอง (ส่งคืนหนู )

  • R[&(…)]ใช้สิ่งนั้นราวกับว่ามันเป็นตัวดำเนินการมัดและย้อนกลับ
    (รวมถึงทำให้การเชื่อมโยงถูกต้อง)

  • […](@_) ใช้เวลานั้นและใช้มันเพื่อลดอินพุต

  • … .nudeส่งกลับnu merator และเด nominator ของหนู

  • { … }@_ทำให้มันเป็นแลมบ์ดาบล็อกเปลือยกับพารามิเตอร์โดยปริยาย

การใช้งาน:

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 ไบต์

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 เป็นภาษาโปรแกรมแรกที่ฉันสร้างขึ้น มันถูกออกแบบมาให้ใช้งานง่ายและมีไวยากรณ์ที่สะอาด - แทนที่จะเสียเวลาสั้น ๆ ทำไมฉันถึงเล่นกอล์ฟกับมันคุณถาม? เพราะไม่เหมือนกับภาษาใด ๆ ที่ฉันเขียนตั้งแต่มันมีFractionประเภทในตัว คุณสามารถใช้โอเปอเรเตอร์แผนก/เป็นโอเปอเรเตอร์unary สำหรับ "inverse" (ฟีเจอร์ที่ฉันยืมเพื่อ Pip)

ตอนนี้มีข้อ จำกัด ที่สำคัญ ปัญหาที่ใหญ่ที่สุดสำหรับความท้าทายนี้คือต้องกำหนดอาร์เรย์ด้วยขนาดคงที่ซึ่งหมายความว่าโปรแกรมเริ่มต้นด้วยการอ่านขนาดของอาร์เรย์จากผู้ใช้ (ฉันหวังว่านี่จะโอเค; ทางเลือกคือขนาดฮาร์ดโค้ด) นอกจากนี้ยังมีปัญหาเล็กน้อยที่ไม่มีตัวดำเนินการลำดับความสำคัญหมายถึงนิพจน์ของตัวดำเนินการแบบหลายตัวต้องมีวงเล็บ

นี่คือตัวอย่างการเรียกใช้:

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

1

Ruby, 34 ไบต์

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

สิ่งนี้จะทำการพับด้านขวา (โดยการย้อนกลับและจากนั้นการพับด้านซ้าย) เพิ่มแต่ละองค์ประกอบเป็น 1 ในผลรวมการรัน (องค์ประกอบทางด้านขวา) Ruby มีประเภท Rational ซึ่งเป็นสิ่งที่ดีจริงๆ และการปันส่วนตัวอักษรเป็นตัวเลขที่rต่อท้ายด้วย


1

Stax , 4 ไบต์

╣╩┼►

เรียกใช้และแก้ไขข้อบกพร่อง

มีขนาดเล็กเท่าที่เป็นอยู่ไม่ใช่ในตัว ปันส่วนในตัวช่วยค่อนข้างน้อย จำนวนมากเพื่อ ASCII rksu+โปรแกรมเป็น

  1. ย้อนกลับอาร์เรย์
  2. (a, b) => (a + 1/b)พับอาร์เรย์ใช้

1

APL (NARS), 15 + 1 ตัวอักษร, 30 + 2 ไบต์

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

Translation in Apl (Nars) จากโซลูชั่น Adam J ... อินพุตที่ได้รับอนุญาตสำหรับฟังก์ชั่นนั้นจะเป็นรายการทั้งหมดของจำนวนเต็มที่องค์ประกอบแรกจะเป็นประเภทเหตุผล ทดสอบ:

  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 

ดังนั้นมันจะเป็น 15 chars ตามความยาวของฟังก์ชั่นและ 1 char สำหรับ "x" สำหรับป้อนประเภทของอินพุตที่ฉันต้องการและออกจากประเภทที่ฉันต้องการ ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.