Semplifica una frazione continua


21

Le frazioni continue sono espressioni che descrivono le frazioni in modo iterativo. Possono essere rappresentati graficamente:

inserisci qui la descrizione dell'immagine

Oppure possono essere rappresentati come un elenco di valori: [a0; a1, a2, a3, ... an]

La sfida:

prendere un numero di base: e un elenco di valori di denominatore: e semplificare la frazione continua in una frazione razionale semplificata: restituire o stampare numeratore e denominatore separatamente.a0[a1, a2, a3, ... an]

Esempi:

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

Esempio di implementazione: (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

Vincente:

il codice più breve in byte: --no nessun builtin che permetta l'intero problema--


Dovresti rendere più chiara questa frase "e semplificare la frazione continua ad una singola frazione"; a meno che non si intendesse che la formulazione significa che un risultato di 2.002può essere espresso come 2002/1000. Questa è tecnicamente una "singola frazione", probabilmente vorrai dire "una singola frazione, nella sua forma più semplice".
Magic Octopus Urn

@carusocomputing point preso .. anche se non mi sentirei troppo male per 2/4 (o simili) in quanto ha ancora semplificato la struttura delle frazioni multiple in una singola frazione
Aaron

Hmm ... Penso che ci sia un modo per sfruttarlo, ma con la risposta del golfscript a 13 byte, dovrei probabilmente usare MATL per vincere.
Magic Octopus Urn,

@carusocomputing Direi che provaci ... Se riesci a battere la risposta a 13 byte, sarebbe fantastico
Aaron

Puoi fermare il pi prima - 355/113.
Thorbjørn Ravn Andersen,

Risposte:


15

J, 8 5 byte

Lo stesso di questo , ma utilizza un build-in per razionali.

L'argomento è {a0, a1, a2, a3, ...} come un elenco di numeri razionali di precisione estesa J. Il risultato è la frazione come numero razionale di precisione estesa J.

(+%)/

(+%) il plus del reciproco di

/ riduzione sopra

Provalo online!

-3 grazie alle miglia .


Se si prende l'input come un elenco di numeri interi estesi, è possibile salvare 3 byte. Inoltre hai usato la divisione APL nella spiegazione.
miglia

@miles Grazie. Non posso avvicinarmi al divieto incorporato di quello. Peccato che J non abbia un personaggio di composizione hook come Dyalog APL .
Adám,

Il collegamento online di prova J è interrotto
Chiel ten Brinke,

@ChieltenBrinke Grazie. Fisso.
Adám,

12

Haskell, 37 36 18 byte

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

Questa funzione prevede il Ratiotipo di Haskell come input. Esempio di utilizzo:

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

Nota: uno esplicito Rationella lista di input ( 4%1) è sufficiente, i sistemi di tipo scoprono che anche gli altri devono essere Ratios.

Modifica: @Lynn ha salvato un byte. Grazie!

Modifica II: rimosso il import(vedi questa discussione su meta ).


1
Oooh, bella custodia per bordi. La stessa funzione è polimorfica, quindi non ha bisogno di import. Comunque per chiamarlo, devi dargli da mangiare Ratioche ha bisogno di import. Devo aggiungere il importconteggio dei byte o no?
nimi,

1
Sembra una buona domanda per meta.
Martin Ender,

Non ho mai usato Haskell, quindi correggimi se sbaglio, ma se Python equivelent fosse: from fractions import Fractionper fare operazioni con Fractionoggetti, viene conteggiata anche l'istruzione import.
Aaron,

.. ce l' avevamo prima .
nimi,

@Aaron: il problema è: la definizione della funzione non ha bisogno dell'importazione, perché è polimorfica. Quando si desidera chiamarlo, è necessario fornire numeri di tipo Ratioche possono essere costruiti solo tramite %, che richiede l'importazione. Di solito non contiamo i byte per chiamare l'overhead, solo per la funzione stessa.
nimi,

11

GolfScript , 13 byte

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

Provalo online!

Sì per le razionali nascoste di GolfScript . :)

Spiegazione

L'unico tipo di numero "ufficiale" di GolfScript è numeri interi. Ma l'operatore esponenziale non converte il suo risultato in numero intero e convenientemente il risultato nativo di una esponenziazione intera in Ruby (il linguaggio dell'interprete di GolfScript) è un numero razionale. Quindi possiamo facilmente ottenere frazioni elevando qualcosa alla potenza di -1. Convenientemente, desideriamo comunque dei reciproci ...

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

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

Essenzialmente una porta della mia risposta GolfScript . Ecco alcune alternative:

Per 24 byte, possiamo scrivere una funzione variadica ricorsiva:

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

Per 21 byte, possiamo persino definire un "operatore variadico", ma la sua convenzione di chiamata sarebbe così strana, che sono riluttante a contare questo:

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

Si dovrebbe chiamare questo con una successione di valori di input, ad esempio ±Sequence[3, 7, 15, 1, 292, 1]o ±##&[3, 7, 15, 1, 292, 1].

E anche per 21 byte, ci sarebbe il (proibito) incorporato:

FromContinuedFraction

10

LabVIEW, 36 byte equivalenti

Implementazione ingenua abbastanza semplice usando l'algoritmo di OP. C'è un modo migliore per farlo?

inserisci qui la descrizione dell'immagine


5
La tua laurea in ingegneria elettrica sta mostrando.
Magic Octopus Urn,

1
@Justlovemath Props, ma ..... rilevante
Aaron,

Sì, è un linguaggio controverso per essere sicuro. Vedo LabVIEW come "odio la matematica" del mondo dei programmatori. Il problema non è la matematica stessa, ma come viene insegnata (o spesso la mancanza di insegnamento).
ijustlovemath,

6

Dyalog APL , 10 byte

Non usa nemmeno un build-in per razionali.

Prende {a 0 , a 1 , a 2 , a 3 , ...} come argomento, restituisce {denominatore, numeratore}.

1(,÷∨)+∘÷/

1(,÷∨) 1-anteposto-diviso per il GCD di 1 e

+∘÷ plus-la-reciproca-of

/ riduzione sopra

ProvaAPL online!


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

Sfortunatamente non è così da golf (vedi la risposta di @ xnor per i più brevi), ma calcola la frazione senza dover invertire l'input. Questo utilizza l' approccio della "tabella magica" per i convergenti - date le ultime due frazioni a/ce b/dla frazione successiva è (n*b+a)/(n*c+d).

Ad esempio, per pi:

          3    7    15     1      292        1

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

Possiamo vedere che 15*22 + 3 = 333, 15*7 + 1 = 106, 1*333 + 22 = 355, 1*106 + 7 = 113, etc.


4

M, 5 byte

Ṛİ+¥/

L'input è un elenco di valori [a0, a1, ..., aN]e genera un numero razionale.

Provalo online! oppure Verifica tutti i casi di test.

Spiegazione

Ṛİ+¥/  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
Cos'è questo? Qualche nuovo dialetto Jelly?
Adám,

@miles in realtà 9 byte mi dispiace :(
Aaron

@Adám È una vecchia forchetta di Jelly pensata per la matematica e la simbolica. Ecco il suo repository Github .
miglia

1
@Aaron M utilizza la stessa tabella codici di Jelly e può essere codificato utilizzando un byte per ogni carattere.
miglia

@miles OK, aggiunto .
Adám,

4

Haskell, 30 byte

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

Aggiunge ricorsivamente ogni livello andando verso l'esterno, aggiornando n/da h+(1/(n/d)), che equivale a h+d/no (h*n+d)/n. La frazione viene memorizzata come tupla di (num,denom). La frazione iniziale di (1,0)lanci a 0/1cui è 0.


3

Python, 50 byte

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

Crea la frazione continua dalla fine dell'elenco procedendo all'indietro, aggiornando ripetutamente la frazione n/dsull'ultimo elemento xcome n/d -> 1+1/(n/d) == (x*n+d)/n.


3

 Lisp comune, 54

Una piega un po 'prolissa:

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

test

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)

Questa è la prima volta che uso Julia, se trascurassi un iteratore avrei potuto perdere qualche byte in più, fammi sapere. Ecco un suggerimento per chiunque non sappia quale lingua scegliere per questa specifica sfida: 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;)
  • Invertire l'array di input.
  • Scorrilo con divisione razionale.
  • Aggiungi c al risultato decimale.

puoi salvare due byte definendo un operatore (ad es. ) anziché una funzione
Tasos Papastylianou,

inoltre, cambia il ciclo for per un po 'e x∘c=(a=0;while x!=[];a=1//(pop!(x)+a);end;a+c;)
fai

1
25: x->foldr((x,y)->x+1//y,x)(uguale alla soluzione Haskell). utilizzo:(x->foldr((x,y)->x+1//y,x))([4//1,2,1,3,1,2])
Fengyang Wang,

Ooo ... Una funzione di piegatura inversa? Questo è bello! Non merito di prendermi il merito, però, ahah.
Magic Octopus Urn,

2

Javascript (ES6), 55 byte

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

Casi test

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

Interprete online .

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)

Spiegazione

Input preso come un elenco di numeri

                     # 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

Provalo online!


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]

È grazie alla risposta di Arnauld, prima di vederlo ero bloccato a 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]

Esempio:
Call: f([1, 0, 1, 1, 2, 1, 1])
Output:Array [ 19, 7 ]


1

Perl 6 , 24 byte

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

Spiegazione:

  • 1 / * + *è una lambda con due parametri ( *) che prende il reciproco del primo e aggiunge il secondo. (restituisce un ratto )

  • R[&(…)]lo usa come se fosse un operatore infix e lo inverte.
    (incluso renderlo associativo)

  • […](@_) lo prende e lo usa per ridurre l'input.

  • … .nuderestituisce il nu merator e il de nominator del Rat .

  • { … }rendilo un blocco nudo lambda con parametro implicito @_.

Uso:

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

Zefiro , 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 è il primo linguaggio di programmazione che abbia mai creato. È stato progettato per essere intuitivo e avere una sintassi pulita, piuttosto a scapito della brevità. Perché ci sto giocando a golf, mi chiedi? Perché, a differenza di qualsiasi lingua che ho scritto da allora, ha un tipo incorporato Fraction. Puoi anche usare l'operatore di divisione /come operatore unario per "inverso" (una caratteristica che ho preso in prestito per Pip).

Ora ci sono limiti significativi. Il problema più grande di questa sfida è che gli array devono essere definiti con dimensioni fisse, il che significa che il programma si avvia leggendo le dimensioni dell'array dall'utente. (Spero che vada bene; l'alternativa è la codifica delle dimensioni.) C'è anche il piccolo problema che la precedenza dell'operatore non esiste, il che significa che le espressioni multi-operatore devono avere parentesi.

Ecco un esempio:

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

1

Rubino, 34 byte

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

Ciò esegue una piega a destra (invertendo e poi piegando a sinistra), aggiungendo ogni elemento a 1 sul totale corrente (gli elementi a destra). Ruby ha il tipo Rational, che è davvero bello. E le razionali letterali sono un numero con suffisso r.


1

Stax , 4 byte

╣╩┼►

Esegui ed esegui il debug

Per quanto piccolo, non è un built-in. I razionali integrati aiutano piuttosto un po 'però. Disimballato su ascii, il programma è rksu+.

  1. Invertire l'array.
  2. Piegare l'array usando (a, b) => (a + 1/b).

1

APL (NARS), 15 + 1 caratteri, 30 + 2 byte

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

Traduzione in Apl (Nars) dalla soluzione Adam J ... l'input consentito per quella funzione sarà tutto l'elenco di numeri interi, in cui il primo elemento sarà di tipo razionale. Test:

  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 

quindi sarebbe 15 caratteri come lunghezza della funzione e 1 carattere per "x" per inserire il tipo di input che voglio ed uscire dal tipo che voglio ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.