Devam eden bir kesri kolaylaştırın


21

Devam edilen kesirler, kesirleri yinelemeli olarak tanımlayan ifadelerdir. Grafik olarak gösterilebilirler:

görüntü tanımını buraya girin

Veya bir değerler listesi olarak gösterilebilirler: [a0; a1, a2, a3, ... an]

Meydan okuma:

temel sayıyı alın: ve payda değerlerinin bir listesini alın: ve devam eden kesiri basitleştirilmiş rasyonel bir kesirle basitleştirin: pay ve paydayı ayrı ayrı döndürün veya yazdırın.a0[a1, a2, a3, ... an]

Örnekler:

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

Örnek uygulama: (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

Kazanan:

bayt cinsinden en kısa kod: - izin verilen tüm sorunu çözen hiçbir yerleşik olmayan--


Bu cümleyi daha açık hale getirmelisin, "ve devam eden kesimi tek bir kesime indirgemelisin"; ifadesini kastediyorsanız bir sonucu 2.002olarak ifade edilebilir 2002/1000. Bu teknik olarak "tek bir kesir", muhtemelen "en basit haliyle" tek bir kesir "demek istiyorsunuz.
Magic Octopus Urn

@ carusocomputing noktası alındı. Yine de, çok kesirli yapıyı tek bir kesirde sadeleştirdiği için 2/4 (veya benzer) hakkında kendimi kötü hissetmeme rağmen
Aaron,

Hmm ... Sanırım bundan faydalanmanın bir yolu var, ama 13 byte golfscript'in cevabıyla muhtemelen kazanmak için MATL kullanmak zorunda kalacağım.
Magic Octopus Urn

@carusocomputing Bunun için gitmek söyleyebilirim ... Eğer 13 byte cevabı yenebilirseniz, bu harika olurdu
Aaron

Pi'yi daha önce durdurabilirsiniz - 355/113.
Thorbjørn Ravn Andersen

Yanıtlar:


15

J, 8 5 bayt

Aynı bu , ancak bir yap-rationals için kullanır.

Bağımsız değişken, J genişletilmiş hassas rasyonel sayılar listesi olarak {a0, a1, a2, a3, ...} 'dir. Sonuç, J genişletilmiş hassas rasyonel sayı olarak kesirdir.

(+%)/

(+%) artı-karşılıklı

/ üzerinde azalma

Çevrimiçi deneyin!

-3 mil sayesinde .


Girdiyi bir genişletilmiş tam sayı listesi olarak alırsanız, 3 bayt kaydedebilirsiniz. Ayrıca açıklamada APL bölümünü kullandınız.
mil

@miles Teşekkürler. Yerleşik yasağa bundan daha fazla yaklaşamıyor. Çok kötü J, Dyalog APL'ler gibi bir kanca kompozisyon karakterine sahip değil .
Adám

Deneyin J çevrimiçi bağlantı bozuldu
Chiel ten Brinke

@ChieltenBrinke Teşekkürler. Sabit.
Adâm

12

Haskell, 37 36 18 bayt

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

Bu işlev Haskell'in Ratiotürünü girdi olarak bekler . Kullanım örneği:

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

Not: Ratiogiriş listesindeki ( 4%1) bir açık yeterlidir, tür sistemleri diğerlerinin de olması gerektiğini söyler Ratio.

Düzenleme: @Lynn bir bayt kaydetti. Teşekkürler!

Düzenleme II: kaldırıldı import(bu tartışmaya meta üzerinde bakın ).


1
Oooh, iyi kenar davası. Fonksiyonun kendisi polimorfiktir, bu yüzden ihtiyaç duymaz import. Ancak adlandırmak, feed zorunda Ratioler buna ihtiyacı var ki import. importBayt sayımına eklemeli miyim yoksa eklememeli miyim ?
nimi

1
Bu meta için iyi bir soru gibi geliyor.
Martin Ender

Haskell'i hiç kullanmadım, bu yüzden yanlış yaparsam düzeltin, ancak python eşdeğeri olacaksa: nesnelerle from fractions import Fractionişlem yapmak Fractioniçin import ifadesi de sayılır.
Aaron,


@Aaron: sorun şu: işlevin tanımı içe aktarma gerektirmiyor, çünkü bu çok biçimli. Aramak istediğinizde Ratio, yalnızca %içe aktarılmasını gerektiren, ancak oluşturulabilecek türden sayılar sağlamanız gerekir . Genellikle, sadece fonksiyonun kendisi için yükü çağırmak için bayt saymayız.
nimi

11

GolfScript , 13 bayt

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

Çevrimiçi deneyin!

GolfScript'in gizli gerekçeleri için Yay . :)

açıklama

GolfScript'in tek "resmi" sayı tipi tamsayıdır. Ancak üsteleştirme operatörü, sonucunu tamsayıya dökmez ve uygun bir şekilde Ruby'deki bir tamsayı üsteliğinin yerel sonucunu (GolfScript'in tercüman dili) rasyonel bir sayıdır. Böylece -1'in gücüne bir şey yükselterek kolayca kesirler elde edebiliriz. Elverişli olarak, yine de karşılıksızlar istiyoruz ...

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

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

Temelde GolfScript cevabımın bir limanı . İşte bazı alternatifler:

24 bayt için özyinelemeli variadic bir fonksiyon yazabiliriz:

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

21 bayt için, bir "variadic operatörü" bile tanımlayabiliriz, ancak çağrı sözleşmesi o kadar garip olurdu ki, bunu saymak istemiyorum:

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

Bunu giriş değerlerinin bir dizisiyle çağırmanız gerekir , örneğin ±Sequence[3, 7, 15, 1, 292, 1]veya ±##&[3, 7, 15, 1, 292, 1].

Ve ayrıca 21 bayt için, yerleşik (yasak) olacaktır:

FromContinuedFraction

10

LabVIEW, 36 eşdeğer bayt

OP algoritmasını kullanarak oldukça yalındır naif uygulama. Bunu yapmanın daha güzel bir yolu var mı?

görüntü tanımını buraya girin


5
Elektrik mühendisliği dereceniz gösteriyor.
Magic Octopus Urn

1
@ ijustlovemath Dikmeler, ancak ..... alakalı
Aaron

Evet, emin olmak için çekişmeli bir dil. LabVIEW'ı programcılar dünyasının "matematiğinden nefret ediyorum" olarak görüyorum. Sorun matematiğin kendisi değil, nasıl öğretildiğidir (ya da genellikle öğretme eksikliği).
ijustlovemath

6

Dyalog APL , 10 bayt

Mantık için bir yapı bile kullanmaz.

Argüman olarak {a 0 , a 1 , 2 , a 3 , ...} alır, {payda, numerator} döndürür.

1(,÷∨)+∘÷/

1(,÷∨) 1-önceden-1 ve GCD'ye bölünmüş

+∘÷ artı karşılıklı-bölgesinin

/ üzerinde azalma

TryAPL çevrimiçi!


6

Python 2, 62 bayt

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

Maalesef golf gibi değil (bkz. @ Xnor'ın kısa cevabına bakınız ), ancak girişi tersine çevirmeksizin kesri hesaplar. Bu, yakınsamalar için "sihirli tablo" yaklaşımını kullanır - son iki kesir a/cve b/dsonraki kesir (n*b+a)/(n*c+d).

Örneğin, pi için:

          3    7    15     1      292        1

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

Bunu görebiliyorum 15*22 + 3 = 333, 15*7 + 1 = 106, 1*333 + 22 = 355, 1*106 + 7 = 113, vb


4

M, 5 bayt

Ṛİ+¥/

Giriş, değerlerin bir listesidir [a0, a1, ..., aN]ve rasyonel bir sayı çıkarır.

Çevrimiçi deneyin! veya Tüm test durumlarını doğrulayın.

açıklama

Ṛİ+¥/  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
Bu nedir? Bazı yeni Jelly lehçesi?
Adám

@miles aslında 9 bayt özür dilerim :(
Aaron

@ Adám Matematik ve sembolik için kullanılan eski bir Jelly çatalı. İşte Github deposu .
miller

1
@Aaron M, Jelly ile aynı kod sayfasını kullanır ve her karakter için bir bayt kullanılarak kodlanabilir.
mil,

@miles Tamam, eklendi .
Adám

4

Haskell, 30 bayt

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

Recursively her katman, dışa gidiş güncellenmesi ekler n/diçin h+(1/(n/d))eşit olan h+d/nveya (h*n+d)/n. Kesir, bir demet olarak depolanır (num,denom). İlk fraksiyon (1,0)çevirir için 0/1hangi 0.


3

Python, 50 bayt

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

Listenin ucundan sürekli kesir defalarca kısmını güncellenmesi, geriye gidiş oluşturur n/dgeçen elemana xolarak n/d -> 1+1/(n/d) == (x*n+d)/n.


3

 Common Lisp, 54

Biraz ayrıntılı bir kat-sağ:

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

Testler

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 Bayt)

Bu benim ilk defa Julia'yı kullanıyorum, eğer daha fazla byte kaybedebileceğim bir yineleyiciyi gözden kaçırırsam, bana haber ver. İşte bu özel zorluk için hangi dili seçeceğini bilen hiç kimseye bir ipucu: 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;)
  • Giriş dizisini ters çevirin.
  • Rasyonel bölünme ile bunun üzerinden yineleyin.
  • Ondalık sonuç için c ekleyin.

Eğer (örneğin bir operatör tanımlayarak iki bayt kaydedebilir bir işlevi yerine)
Tasos Papastylianou

ayrıca, bir süre için for döngüsünü değiştirin ve pop:x∘c=(a=0;while x!=[];a=1//(pop!(x)+a);end;a+c;)
Tasos Papastylianou 15:16 '

1
25: x->foldr((x,y)->x+1//y,x)(Haskell çözümü ile aynı). kullanım:(x->foldr((x,y)->x+1//y,x))([4//1,2,1,3,1,2])
Fengyang Wang

Ooo ... Ters katlama fonksiyonu? Bu çok güzel! Haha olsa bunun için kredi almayı hak etmiyorum.
Magic Octopus Urn

2

Javascript (ES6), 55 bayt

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

Test durumları

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 bayt

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

Çevrimiçi tercüman .

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 bayt

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

açıklama

Sayı listesi olarak alınan giriş

                     # 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

Çevrimiçi deneyin!


2

JavaScript (ES6), 44 bayt

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

1

Javascript (ES6), 50 bayt

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

Arnauld'un cevabı sayesinde, görmeden önce 66 bayta şaşırdım:

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]

Örnek:
Çağrı: f([1, 0, 1, 1, 2, 1, 1])
Çıkış:Array [ 19, 7 ]


1

Perl 6 , 24 bayt

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

Açıklama:

  • 1 / * + *birincinin tersini alan *ve ikincisini ekleyen iki parametreli ( ) bir lambdadır . (bir Rat döndürür )

  • R[&(…)]bunu bir infix operatörüymüş gibi kullanır ve tersine çevirir.
    (onu doğru ilişkilendirme yapmak dahil)

  • […](@_) Bunu alır ve girişi azaltmak için kullanır.

  • … .nudedöner nu merator ve de bir tayin eden Rat .

  • { … }üstü kapalı parametreli bir çıplak blok lambda yapın @_.

Kullanımı:

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 bayt

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, şimdiye kadar yarattığım ilk programlama dilidir. Sezgisel olacak şekilde ve temiz bir sözdizimine sahip olacak şekilde tasarlandı; Neden onunla golf oynuyorum soruyorsun? Çünkü, o zamandan beri yazdığım herhangi bir dilin aksine, yerleşik bir Fractiontüre sahiptir. Bölme operatörünü bile kullanabilirsiniz/ "ters" (Pip için ödünç aldığım bir özellik) için tek bir olarak .

Şimdi, önemli sınırlamalar var. Bu zorluğun en büyük problemi, dizilerin sabit boyutla tanımlanması gerektiğidir, yani program kullanıcının dizinin boyutunu okuyarak başlar. (Umarım bu uygun; alternatif boyutu kodluyor.) Ayrıca, operatör önceliğinin olmadığı küçük bir sorun var, yani çok operatörlü ifadelerin parantez içinde olması gerekiyor.

İşte bir örnek çalışma:

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

1

Ruby, 34 bayt

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

Bu, bir toplam katlama (geri çevirme ve sonra sola katlama yoluyla) gerçekleştirerek, her bir elemanı toplam koşu değerinin üzerine 1 ekler (sağdaki elemanlar). Ruby, gerçekten güzel olan Rational tipine sahip. Ve kelimenin tam anlamıyla rasyonel olan bir sayı vardır r.


1

Stax , 4 bayt

╣╩┼►

Koş ve hata ayıkla

Olduğu kadar küçük, yerleşik değil. Yerleşik gerekçeler olsa da, biraz yardımcı olur. Ascii'ye açılmış programdır rksu+.

  1. Diziyi ters çevir.
  2. Diziyi kullanarak katlayın (a, b) => (a + 1/b).

1

APL (NARS), 15 + 1 karakter, 30 + 2 bayt

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

Adam J çözümünden Apl'de (Nars) çeviri ... bu işleve izin verilen girdi, ilk öğenin rasyonel olacağı tam sayıların listesi olacaktır. Ölçek:

  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 

bu yüzden fonksiyon uzunluğu olarak 15 karakter ve istediğim giriş türünü girip çıkmak istediğim türden "x" için 1 karakter olacaktı ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.