I numeri iniziali più bassi in una sequenza simile a Fibonacci


22

Dato un ingresso intero positivo N , in uscita i due numeri non negativi, un e b , dove a <b , con il valore medio possibile che porterà il numero N essendo parte della sequenza relazione periodico:

f(0) = a
f(1) = b
f(n) = f(n-2)+f(n-1)

Nel caso in cui ci sono più di una soluzione in cui la media di un e b sono minime, allora si dovrebbe uscita quello con il più basso b .

Puoi presumere che N sia all'interno dell'intervallo rappresentativo di numeri interi nella tua lingua / sistema.

Casi test

N = 1
a = 0, b = 1

N = 15
a = 0, b = 3

N = 21
a = 0, b = 1

N = 27
a = 0, b = 9   <- Tricky test case. [3, 7] is not optimal and [4, 3] is not valid

N = 100
a = 4, b = 10

N = 101
a = 1, b = 12

N = 102
a = 0, b = 3

N = 1000
a = 2, b = 10

Se a>=0e a<bci sono mai più soluzioni?
Jonathan Allan,

Non posso garantire che ci siano o meno soluzioni multiple. Entrambi 1,4e 2,3darebbero 5, e hanno la stessa media. Immagino sia possibile trovare casi simili a quello, in cui questi sono i valori medi più bassi. Se riesci a mostrare / dimostrare che non ci sono più soluzioni, non è necessario verificare tale condizione.
Stewie Griffin,


3
La sequenza OEIS corrispondente per la media più bassa possibile, A249783 , presenta un grafico dall'aspetto selvaggio .
Peter Kagey,

1
@ ØrjanJohansen Ho aggiunto una prova alla mia risposta che non ci sono soluzioni duplicate (poiché la mia risposta dipendeva da essa).
cardboard_box

Risposte:


8

Buccia , 19 18 16 14 13 15 byte

Grazie Zgarb per aver salvato 1 byte.

ḟö£⁰ƒẊ++ÖΣṖ2Θḣ⁰

Provalo online!

Spiegazione:

Disclaimer: davvero non capisco la ȯƒẊ++sezione del codice.

Modifica: sembra tradurre in Haskell fix.(mapad2(+).).(++), dove si mapad2trova la funzione di applicazione a tutte le coppie adiacenti in un elenco. (Anche se, conoscendo Husk, nel contesto di questo programma potrebbe significare qualcos'altro)

            Θḣ⁰    Create the list [0..input]
          Ṗ2       Generate all possible sublists of length 2
        ÖΣ         Sort them on their sums
ḟ                  Find the first element that satisfies the following predicate.
    ƒẊ++             Given [a,b], magically generate the infinite Fibonacci-like
                     sequence from [a,b] without [a,b] at the start.
 ö£⁰                 Is the input in that list (given that it is in sorted order)?


Sono sicuro di averlo provato ...
H.Piz,

8

JavaScript (Node.js) , 92 90 89 91 83 82 byte

-3 byte -1 byte grazie a ThePirateBay

-8 -9 byte grazie a Neil.

f=(n,a=1,b=0,c=(a,b)=>b<n?c(a+b,a):b>n)=>c(a,b)?b+2<a?f(n,a-1,b+1):f(n,b-~a):[b,a]

Provalo online!

Nota: questa soluzione si basa sul fatto che non esistono mai più soluzioni minime.

Prova che non ci sono mai più soluzioni:

Lascia che FIB(a,b,k)sia la sequenza simile a Fibonacci che inizia con a,b:

FIB(a,b,0) = a
FIB(a,b,1) = b
FIB(a,b,k) = FIB(a,b,k-1) + FIB(a,b,k-2)

Lemma 1

La differenza tra sequenze simili a Fibonacci è di per sé simile a Fibonacci, cioè FIB(a1,b1,k) - FIB(a0,b0,k) = FIB(a1-a0,b1-b0,k). La prova è lasciata al lettore.

Lemma 2

Perché esiste n >= 5una soluzione a,bsoddisfacente a+b < n:

se nè pari,FIB(0,n/2,3) = n

se nè dispari,FIB(1,(n-1)/2,3) = n

Prova

Casi in cui n < 5può essere verificato in modo esauriente.

Supponiamo di avere due soluzioni minime per n >= 5, a0,b0e a1,b1con a0 + b0 = a1 + b1e a0 != a1.

Quindi esiste k0,k1tale FIB(a0,b0,k0) = FIB(a1,b1,k1) = n.

  • Caso 1: k0 = k1

    WLOG assume b0 < b1(e quindi a0 > a1)

    Lascia che DIFF(k)sia la differenza tra le sequenze simili a Fibonnaci che iniziano con a1,b1e a0,b0:

    DIFF(k) = FIB(a1,b1,k) - FIB(a0,b0,k) = FIB(a1-a0,b1-b0,k) (Lemma 1)

    DIFF(0) = a1 - a0 < 0

    DIFF(1) = b1 - b0 > 0

    DIFF(2) = (a1+b1) - (a0+b0) = 0

    DIFF(3) = DIFF(1) + DIFF(2) = DIFF(1) > 0

    DIFF(4) = DIFF(2) + DIFF(3) = DIFF(3) > 0

    Una volta che una sequenza simile a Fibonnaci ha 2 termini positivi, tutti i termini successivi sono positivi.

    Pertanto, l'unica volta DIFF(k) = 0è quando k = 2, quindi l'unica scelta k0 = k1è 2.

    Perciò n = FIB(a0,b0,2) = a0 + b0 = a1 + b1

    La minimalità di queste soluzioni contraddice Lemma 2.

  • Caso 2 k0 != k1::

    WLOG assume k0 < k1.

    abbiamo FIB(a1,b1,k1) = n

    Permettere a2 = FIB(a1,b1,k1-k0)

    Permettere b2 = FIB(a1,b1,k1-k0+1)

    Quindi FIB(a2,b2,k0) = FIB(a1,b1,k1) = FIB(a0,b0,k0)(esercizio per il lettore)

    Poiché FIB(a1,b1,k)non è negativo per k >= 0, è anche non decrescente.

    Questo ci dà a2 >= b1 > a0e b2 >= a1+b1 = a0+b0.

    Quindi lascia DIFF(k) = FIB(a2,b2,k) - FIB(a0,b0,k) = FIB(a2-a0,b2-b0,k)(Lemma 1)

    DIFF(0) = a2 - a0 > 0

    DIFF(1) = b2 - b0 >= (a0 + b0) - b0 = a0 >= 0

    DIFF(2) = DIFF(0) + DIFF(1) >= DIFF(0) > 0

    DIFF(3) = DIFF(1) + DIFF(2) >= DIFF(2) > 0

    Ancora una volta, DIFFha 2 termini positivi e quindi tutti i termini successivi sono positivi.

    Così, l'unico momento in cui è possibile che DIFF(k) = 0è k = 1, così l'unica scelta per k0è 1.

    FIB(a0,b0,1) = n

    b0 = n

    Questo contraddice Lemma 2.




@Neil Questo minimizza binvece di minimizzare a+b, e quindi la tua soluzione offre f(27) = [3,7]ma la soluzione ottimale è f(27)=[0,9]. Dopo aver ripristinato le modifiche di rottura siamo scesi a 83 byte.
cardboard_box

1
Penso che puoi salvare un altro byte usando b-~ainvece di a+b+1.
Neil,

1
C'è un piccolo errore nel secondo caso: a2 >= a1 + b1non è corretto quando k1-k0=1. Invece puoi usare a2 >= b1 > a0e b2 >= a1+b1 = a0+b0, e poi il resto segue.
Ørjan Johansen,

8

Haskell , 76 72 74 byte

MODIFICARE:

  • -4 byte: @ H.Piz ha suggerito di utilizzare / invece di div, sebbene ciò richieda l'utilizzo di un tipo di numero frazionario.
  • +2 byte: risolto un bug con Enum intervalli aggiungendo -1.

faccetta un valore Doubleo un Rationaltipo e restituisce una tupla uguale. Doubledovrebbe essere sufficiente per tutti i valori che non sono abbastanza grandi da causare errori di arrotondamento, mentreRational teoricamente è illimitato.

f n|let a?b=b==n||b<n&&b?(a+b)=[(a,s-a)|s<-[1..],a<-[0..s/2-1],a?(s-a)]!!0

Provalo online!(con le regolazioni dell'intestazione di H.PWiz per input / output Rationalin formato intero)

Come funziona

  • ?è un operatore annidato localmente nell'ambito di f. a?battraversa ricorsivamente la sequenza simil-Fibonacci a partire da a,bfino a b>=n, ritornandoTrue iff colpisce nesattamente.
  • Nella comprensione dell'elenco:
    • sscorre attraverso tutti i numeri dall'alto 1verso l'alto, rappresentando la somma di aeb .
    • ascorre tra i numeri da 0as/2-1 . (Se sè dispari, la fine dell'intervallo viene arrotondata per eccesso.)
    • a?(s-a)verifica se la sequenza inizia con i a,s-arisultati n. In tal caso, la comprensione dell'elenco include la tupla(a,s-a) . (Cioè b=s-a, anche se era troppo breve per essere degno di essere nominato.)
    • !!0 seleziona il primo elemento (hit) nella comprensione.

8

APL (Dyalog) , 75 71 64 59 53 48 44 43 byte

2 byte salvati grazie a @ Adám

12 byte salvati grazie a @ngn

o/⍨k∊¨+\∘⌽⍣{k≤⊃⍺}¨oa/⍨</¨a←,⍉|-21+k←⎕

Provalo online!

usi ⎕IO←0 .

Come? Questo era impazzito.

k←⎕ - assegnare input a k

⍳2⍴1+k←⎕- prodotto cartesiano della gamma 0di kcon sé

|-\¨ - sottrai ogni elemento della coppia destra da sinistra e ottiene valori assoluti

a←,⍉ - trasporre, appiattire e assegnare a a

o←a/⍨</¨a - mantenere solo le coppie in cui l'elemento sinistro è più piccolo di quello destro e assegnare a o

oora contiene un elenco di tutte le coppie con a < b, ordinate in base alla loro media matematica

+\∘⌽⍣{k≤⊃⍺}¨o- per ogni coppia in o, applicare fibonacci (invertire la coppia e il cumulo) fino al kraggiungimento del termine o più alto

k∊¨- quindi decidere se kè questo ultimo termine (nel senso che è contenuto nella sequenza)

o/⍨- e mantenere le coppie in ocui si applica il controllo precedente

- restituisce il primo risultato.


5

Python 2 , 127 109 107 byte

-2 byte grazie agli ovs (passando anda *)

g=lambda x,a,b:a<=b<x and g(x,b,a+b)or b==x
f=lambda n,s=1,a=0:g(n,a,s-a)*(a,s-a)or f(n,s+(a==s),a%s+(a<s))

Provalo online!

Qualche punto bonus per n,a,s-a?

Spiegazione:

  • La prima riga dichiara un lambda ricorsivo g, che verifica se raggiungerà l' a, bespansione come sequenza di Fibonacci x. Verifica inoltre che a <= b, uno dei criteri della domanda. (Ciò consentirebbe casi in cui a == b, ma in tal caso 0, asarebbe già stato scoperto e restituito).
    • La disuguaglianza incatenata a<=b<xsvolge due utili compiti contemporaneamente: la verifica a <= be quello b < x.
    • Se b < xcede True, la funzione si richiama di nuovo con i successivi due numeri nella sequenza di Fibonacci:b, a+b . Ciò significa che la funzione continuerà a elaborare nuovi termini fino a ...
    • Se i b < xrendimenti False, abbiamo raggiunto il punto in cui dobbiamo verificare se b==x. In tal caso, questo tornerà True, indicando che alla fine la coppia iniziale a, braggiungerà x. Altrimenti, se b > xla coppia non è valida.
  • La seconda riga dichiara un'altra lambda ricorsiva f, che trova la soluzione per un dato valore n. Prova in modo ricorsivo nuove coppie iniziali a, b, fino a quando non g(n, a, b)cedeTrue . Questa soluzione viene quindi restituita.
    • La funzione conta ricorsivamente le coppie iniziali di Fibonacci usando due variabili, s(inizialmente 1) e a(inizialmente 0). Ad ogni iterazione, aviene incrementato e a, s-aviene utilizzato come prima coppia. Tuttavia, quando acolpisce s, viene ripristinato a 0 e sviene incrementato. Ciò significa che le coppie vengono conteggiate nel seguente schema:
      s = 1 (0, 1) (1, 0)
      s = 2 (0, 2) (1, 1) (2, 0)
      s = 3 (0, 3) (1, 2), (2, 1), (3, 0)
      
      Ovviamente, questo contiene alcune coppie non valide, tuttavia queste vengono eliminate immediatamente quando passate a g(vedi primo punto elenco).
    • Quando i valori ae svengono trovati tali g(n, a, s-a) == True, allora questo valore viene restituito. Poiché le possibili soluzioni vengono conteggiate in ordine di "dimensione" (ordinate per media, quindi valore minimo), la prima soluzione trovata sarà sempre la più piccola, come richiesto dalla sfida.

3

R , 183 byte 160 byte

n=scan();e=expand.grid(n:0,n:0);e=e[e[,2]>e[,1],];r=e[mapply(h<-function(n,a,b,r=a+b)switch(sign(n-r)+2,F,T,h(n,b,r)),n,e[,1],e[,2]),];r[which.min(rowSums(r)),]

Provalo online!

Grazie a Giuseppe per il golf di 23 byte

Spiegazione del codice

n=scan()                        #STDIO input
e=expand.grid(n:0,n:0)          #full outer join of integer vector n to 0
e=e[e[,2]>e[,1],]               #filter so b > a
r=e[mapply(
  h<-function(n,a,b,r=a+b)switch(sign(n-r)+2,F,T,h(n,b,r)),
                                #create a named recursive function mid-call 
                                #(requires using <- vs = to denote local variable creation 
                                #rather than argument assignment
  n,e[,1],e[,2]),]              #map n, a and b to h() which returns a logical
                                #which is used to filter the possibilities
r[which.min(rowSums(r)),]       #calculate sum for each possibility, 
                                #get index of the minimum and return
                                #because each possibility has 2 values, the mean and 
                                #sum will sort identically.

1
160 byte - in generale, dovresti salvare i byte ovunque tu sia, quindi salvare 4 byte rimuovendo un bel nome non è solo accettabile o incoraggiato, ma in un certo senso richiesto da code-golf . Anche così, bella risposta, +1.
Giuseppe,

1

Mathematica, 117 byte

If[#==1,{0,1},#&@@SortBy[(S=Select)[S[Range[0,s=#]~Tuples~2,Less@@#&],!FreeQ[LinearRecurrence[{1,1},#,s],s]&],Mean]]&


Provalo online!


1

Gelatina , 19 byte

ṫ-Sṭµ¡³e
0rŒcÇÐfSÐṂ

Provalo online!

-1 byte grazie alla prova da cardboard_box . Nel caso in cui sia smentito, puoi aggiungere UṂṚalla fine della seconda riga per 22 byte in totale.


... un incremento iniziale dovrebbe risolvere l'osservazione di @ StewieGriffin.
Jonathan Allan,

Ho la sensazione che tu possa far cadere il
Jonathan Allan il

1
Dobbiamo solo trovare il seme che rende l'input x, apparire più recente. Se x fossero stati trovati nel terzo indice per multiplo, allora funziona per 0,xe quindi funzionerebbe anche in 1,(x-1)/2( xdispari) o 2,x/2-1( xpari), in seguito xapparirebbero nel risultato, in modo che ciò non accada. Per una collisione successiva la media può essere la stessa solo se anche i terzi termini sono uguali, ma allora si deve avere una differenza inferiore tra i termini iniziali (altrimenti sarebbero gli stessi) e quindi si xtroverà in un indice successivo . Come tale possiamo fare il ṫ-Sṭµ¡i³¶ḶŒcÇÐṀsalvataggio di quattro byte.
Jonathan Allan,


@StewieGriffin Quel test-case non esisteva quando ho risposto: p
Erik the Outgolfer,

1

GolfScript - 88 77 byte

~:N[,{1+:a,{[.;a]}/}/][{[.~{.N<}{.@+}while\;N=]}/]{)1=\;},{(\;~+}$(\;);~~' '\

Non ho verificato più soluzioni, grazie abox_box!

Spiegazione

~:N                           # Reads input
[,{1+:a,{[.;a]}/}/]           # Creates an array of pairs [a b]
[{[.~{.N<}{.@+}while\;N=]}/]  # Compute solutions
{)1=\;},         # Pairs that are not solutions are discarded
{(\;~+}$         # Sorts by mean
(\;);~~' '\      # Formats output


0

Lotto, 160 158 byte

@set/aa=b=0
:g
@if %a% geq %b% set/ab-=~a,a=0
@set/ac=a,d=b
:l
@if %c% lss %1 set/ad+=c,c=d-c&goto l
@if %c% gtr %1 set/aa+=1,b-=1&goto g
@echo %a% %b%

Questo (anche) dà 3 7input 27. La soluzione corretta è 0 9.
cardboard_box

@cardboard_box Non vedo ancora dove la domanda richiede che ...
Neil,

Nella prima frase: "con il valore medio più basso possibile".
cardboard_box

@cardboard_box Ah, scusa, era troppo facile da trascurare.
Neil,

1
@cardboard_box OK ora dovrebbe essere risolto.
Neil,
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.