फाइबोनैचि फैक्टराइजेशन


21

फाइबोनैचि संख्या

फाइबोनैचि संख्या के साथ शुरू f(1) = 1और f(2) = 1(कुछ शामिल है f(0) = 0, लेकिन यह इस चुनौती के लिए अप्रासंगिक है। फिर, के लिए n > 2, f(n) = f(n-1) + f(n-2)

चुनौती

आपका कार्य nउस सकारात्मक संख्या को खोजना और आउटपुट करना है जिसे फाइबोनैचि संख्याओं के उत्पादों के रूप में व्यक्त किया जा सकता है। आप इसे 0-अनुक्रमित या 1-अनुक्रमित बनाने के लिए चुन सकते हैं, जो भी आपको बेहतर लगता है, लेकिन आपको अपने उत्तर में इसे निर्दिष्ट करना होगा।

साथ ही, आपका उत्तर उचित समय में 100 वें कार्यकाल की गणना करना चाहिए।

परीक्षण के मामलों

n   result corresponding product (for reference)
1   1      1
2   2      2
3   3      3
4   4      2*2
5   5      5
6   6      2*3
7   8      2*2*2 or 8
8   9      3*3
9   10     2*5
10  12     2*2*3
11  13     13
12  15     3*5
13  16     2*2*2*2 or 2*8
14  18     2*3*3
15  20     2*2*5
16  21     21
17  24     2*2*2*3 or 3*8
18  25     5*5
19  26     2*13
20  27     3*3*3
100 315    3*5*21

संदर्भ


परीक्षण के मामले में उनमें से कुछ एन = परिणाम क्यों हैं, जबकि 7 और ऊपर के लिए वे समान नहीं हैं। शायद मैं इस सवाल को नहीं समझता। लेकिन मैं सिर्फ चेक करना चाहता हूं
जॉर्ज

1
7फिबोनाची संख्याओं के उत्पाद के रूप में व्यक्त नहीं किया जा सकता है। इसलिए, 1सेंट की आवश्यक संख्या है 1, 2nd है 2, ..., 6th है 6, लेकिन 7th है 8
लीक नून

आह, यह समझ में आता है
जॉर्ज

क्या आपको नंबर बनाने के सभी तरीकों को प्रिंट करना चाहिए। उदाहरण के लिए 16 के दो तरीके हैं, या आप सिर्फ एक आउटपुट कर सकते हैं?
जॉर्ज

3
@george मेरा मानना ​​है कि " corresponding product" स्पष्टीकरण के लिए ही है। आपके कोड को केवल " result" आउटपुट करने की आवश्यकता है ।
ट्राइकोप्लाक्स

जवाबों:


6

जेली , २६ २४ २३ २१ बाइट्स

ÆDf÷߀FðḊ¡
1ç#2+С1¤Ṫ

इसे ऑनलाइन आज़माएं!

यह काम किस प्रकार करता है

1ç#2+С1¤Ṫ  Main link. Argument: n (integer)

        ¤   Combine the three links to the left into a niladic chain.
   2          Set the left argument and the return value to 2 (third positive
              Fibonacci number).
       1      Yield 1 (second positive Fibonacci number).
    +С       Compute the sum of the return value and right argument, replacing the
              return value with the sum and the right argument with the previous
              return value.
              Do this n times, collecting all return values in a list.
              This returns A, the first n Fibonacci numbers greater than 1.
1             Set the return value to 1.
 ç#           Call the helper link with left argument k = 1, 2, 3... and right
              argument A = [2, 3, 5...] until n of them return a truthy value.
              Collect the matches in a list.
           Ṫ  Tail; extract the last (n-th) match.


ÆDf÷߀FðḊ¡    Helper link. Left argument: k. Right argument: A

        Ḋ     Dequeue; yield r := [2, ..., k].
       ð ¡    If r in non-empty, execute the chain to the left. Return k otherwise.
ÆD              Yield the positive divisors of k.
   ÷            Divide k by all Fibonacci numbers in A.
  f             Filter; keep divisors that belong to k÷A, i.e., all divisors
                d for which k÷d belongs to A.
    ߀          Recursively call the helper link for each kept divisor d, with left
                argument d and right argument A.
      F         Flatten the result, yielding a non-empty array iff any of the
                recursive calls yielded a non-empty array or a number.
                If the left argument is 1, the helper link returns 1, so the
                array will be non-empty if the consecutive divisions by Fibonacci
                numbers eventually produced a 1.

2
इनपुट के संदर्भ में, इस एल्गोरिथ्म की जटिलता क्या है?
लीक नून

किसी भी मामले में, यह बहुत तेज़ है! 100-वें कार्यकाल के लिए 2 सेकंड से भी कम
लुइस मेंडो

@LeakyNun मुझे पता नहीं है कि कैसे गणना की जाए, लेकिन इनपुट 400 की तुलना में इनपुट 400 को 32 गुना अधिक समय लगता है, मैं कहूंगा कि यह घातीय है। 100 आसानी के साथ संभालती है।
डेनिस

1
ठीक है, केवल आप जानते हैं कि आपका एल्गोरिथ्म क्या है ...
लीक नून

मैं हर परीक्षित संख्या के लिए फाइबोनैचि अनुक्रम को पुन: अंकित न करके इसे बहुत तेज़ बनाने में कामयाब रहा। जैसे ही मैं गोल्फ कर रहा हूँ, मैं एक स्पष्टीकरण जोड़ दूँगा।
डेनिस

5

जूलिया, 79 बाइट्स

!k=any(i->√(5i^2+[4,-4])%1k%i<!(k÷i),2:k)^~-k
<|(n,k=1)=n>0?n-!k<|-~k:~-k

इसे ऑनलाइन आज़माएं!

पृष्ठभूमि

में उन्नत समस्याएं और समाधान, एच 187: फाइबोनैचि एक वर्ग है , प्रस्तावक से पता चलता है कि

फाइबोनैचि / लुकास पहचान

जहां L n n वें लुकास संख्या को दर्शाता है , और वह - इसके विपरीत - यदि

फाइबोनैचि / लुकास की पहचान

तब n एक फाइबोनैचि संख्या है और m एक लुकास संख्या है।

यह काम किस प्रकार करता है

हम <|अपने उद्देश्यों के लिए बाइनरी ऑपरेटर को परिभाषित करते हैं। यह जूलिया के हाल के संस्करणों में अपरिभाषित है, लेकिन अभी भी पार्सर द्वारा एक ऑपरेटर के रूप में मान्यता प्राप्त है।

जब केवल एक तर्क ( n ) के साथ बुलाया जाता है , तो k को 1 के रूप में <|प्रारंभ करता है । जबकि एन सकारात्मक है, यह घटा देती है ! कश्मीर ( 1 अगर कश्मीर फाइबोनैचि संख्या, का एक उत्पाद है 0 से नहीं तो) n और रिकर्सिवली ही कहता है, वेतन वृद्धि कश्मीर से 1 । एक बार n 0 तक पहुंचने के बाद , उत्पादों की वांछित मात्रा मिल गई है, इसलिए k का पिछला मान , यानी ~ -k = k - 1 लौटाता है ।<|

यूनिबरी ऑपरेटर !, फाइबोनैचि संख्या उत्पादों के लिए परीक्षण के रूप में पुनर्परिभाषित किया गया, निम्नानुसार अपने कार्य को प्राप्त करता है।

  • यदि k = 1 , k फिबोनाची संख्याओं का एक उत्पाद है। इस मामले में, हम any(...)शक्ति का रिटर्न मान बढ़ाते हैं ~ -k = k - 1 = 0 , इसलिए परिणाम 1 होगा ।

  • अगर कश्मीर> 1 , परिणाम का मूल्य हो जाएगा any(....), जो वापस आ जाएगी सच यदि और केवल यदि विधेय √(5i^2+[4,-4])%1∋k%i<!(k÷i)रिटर्न सच कुछ पूर्णांक के लिए मैं ऐसा है कि 2 ≤ मैं k ≤

    विधेय में जंजीर की स्थिति से k%iसंबंधित है √(5i^2+[4,-4])%1और k%iसे कम है !(k÷i)

    • √(5i^2+[4,-4])%15i 2 + 4 और 5i 2 - 4 का वर्गमूल लेता है और उनके अवशेषों modulo 1 की गणना करता है । प्रत्येक मापांक 0 है यदि संबंधित संख्या एक पूर्ण वर्ग है, और एक सकारात्मक संख्या 1 से कम है अन्यथा।

      के बाद से k%iरिटर्न एक पूर्णांक है, यह केवल moduli की सरणी के हैं कर सकते हैं कश्मीर% i = 0 (यानी, कश्मीर से विभाज्य है मैं कम से कम एक के बीच में और) 5i 2 4 और 5i 2 - 4 एक पूर्ण वर्ग है (यानी, मैं एक फाइबोनैचि संख्या है)।

    • !(k÷i)पुनरावर्ती रूप से 1 को तर्क k with i (पूर्णांक विभाजन) के साथ कॉल करता है , जो 0 से अधिक होगा यदि और केवल यदि k of i , फाइबोनैचि संख्याओं का उत्पाद है।

प्रेरण द्वारा ,! वांछित संपत्ति है।


5

पायथन, 90 बाइट्स

f=lambda n,a=2,b=3:n<2or n%a<f(n/a)or n-a>0<f(n,b,a+b)
g=lambda k,n=1:k and-~g(k-f(n),n+1)

मुख्य कार्य 1-अनुक्रमित वें फाइबोनैचि उत्पाद का gउत्पादन करता kहै। यह लगभग तुरंत के g(100)रूप में गणना करता है 315। यह संख्या की गिनती की एक सामान्य पुनरावर्ती नुस्खा के साथ ऐसा हो जाता है nकी तलाश में kउदाहरणों कि समारोह को संतुष्ट f। इस तरह के प्रत्येक उदाहरण kतक पहुंचने तक आवश्यक गिनती कम होती है 0

सहायक फ़ंक्शन fएक फाइबोनैचि उत्पाद होने के लिए एक संख्या का परीक्षण करता है। यह अपने वैकल्पिक तर्कों में aऔर फिर से फाइबोनैचि संख्या उत्पन्न करता है b। यह "हाँ" आउटपुट करता है यदि निम्न में से कोई भी सत्य है:

  • n<2। इसका मतलब है n==1, तुच्छ उत्पाद)
  • n%a<f(n/a)। इसके लिए आवश्यकता है n%a==0और f(n/a)==Trueवह nहै , जो कि फाइबोनैचि संख्या का एक गुण है a, और aअभी भी इस कारक को हटाने से एक फाइबोनैचि उत्पाद प्राप्त होता है।
  • n-a>0<f(n,b,a+b), के बराबर है n>a and f(n,b,a+b)। जाँचता है कि वर्तमान में दिखाए जाने वाले फाइबोनैचि संख्या कम से कम नहीं है n, और कुछ अधिक फाइबोनैचि संख्या काम करती है। इसके बजाय असमानता शॉर्ट-सर्किट का उपयोग करके 2 बचत बाइट के लिए डेनिस के लिए धन्यवाद and

फ़ंक्शन gएक बाइट के रूप में छोटा हो सकता है

lambda k:filter(f,range(k*k+1))[k]

अगर g(k)हमेशा सबसे अधिक होता है k*k, जो मुझे यकीन नहीं है कि asymptotically सच है। एक सीमा होती 2**kहै, लेकिन फिर g(100)बहुत लंबा समय लगता है। शायद इसके बजाय पुनरावर्ती में किया gजा सकता है f


के अनुसार इस तालिका OEIS में, g(k)से अधिक है k*kजब k = 47000और इसके बाद के संस्करण।
इसहाक

2

पर्ल 6 ,  95  93 बाइट्स

{(1..*).grep({$/=$_;map {->{$/%$_||($//=$_);$/}...*!%%$_;0},reverse 2,3,&[+]...*>$_;2>$/})[$_]}
{(1..*).grep({$/=$_;map {->{$/%$_||($//=$_);$/}...*%$_;0},reverse 2,3,&[+]...*>$_;2>$/})[$_]}

(0 आधारित सूचकांक)

परीक्षा:

my &fib-prod = {(1..*).grep({$/=$_;map {->{$/%$_||($//=$_);$/}...*%$_;0},reverse 2,3,&[+]...*>$_;2>$/})[$_]}

say fib-prod 0 ..^ 20;
# (1 2 3 4 5 6 8 9 10 12 13 15 16 18 20 21 24 25 26 27)
say time-this { say fib-prod 100 -1; };
# 315
# 1.05135779

sub time-this (&code) {
  my $start = now;
  code();
  now - $start;
}

स्पष्टीकरण:

{
  (1..*).grep(
    {
      $/ = $_; # copy the input ($_) to $/
      map { # map used just for side effect
        ->{
          $/ % $_    # if $/ is divisible by the current fib factor
        ||
          ($/ /= $_) # divide it out once
        ;
          # return the current value in $/
          $/
        }
        ... # repeat until that returns:
        * !%% $_ # something that is not divisible by the current fib factor
        ;0
      },
      # the possible fibonacci factors plus one, reversed
      # ( the extra is to save one byte )
      reverse 2,3,&[+] ... *>$_;

      # is the end result of factoring equal to 1
      # ( for the grep above )
      2 > $/
    }
  )[ $_ ] # get the value at 0-based index
}

2

पायथन 3, 175 170 148 बाइट्स

@ डेनिस -22 बाइट्स के लिए धन्यवाद

j=x=int(input())
y=1,1
exec('y+=y[-2]+y[-1],;'*x)
i=c=0
while c<x:
    if j>=x:j=0;i+=1;t=i
    if t%y[~j]<1:t/=y[~j];j-=1
    if t<2:c+=1;j=x
    j+=1
print(i)

STDIN से इनपुट लेता है और STDOUT पर प्रिंट करता है। यह एक-अनुक्रमित है। 100 वें कार्यकाल की गणना करने में लगभग एक सेकंड का दसवां हिस्सा लगता है।

यह काम किस प्रकार करता है

j=x=int(input())                Get term number x from STDIN and set Fibonacci number index
                                j to x to force initialisation of j later 
y=1,1                           Initialise tuple y with start values for Fibonacci sequence
exec('y+=y[-2]+y[-1],;'*x)      Compute the Fibonacci sequence to x terms and store in y
i=c=0                           Initialise test number i and term counter c
while c<x:                      Loop until x th term is calculated
    if j>=x:j=0;i+=1;t=i        Initialise Fibonacci number index j, increment i and
                                initialise temp variable t for looping through all j for
                                some i. Executes during the first pass of the loop since
                                at this point, j=x
    if t%y[~j]<1:t/=y[~j];j-=1  Find t mod the j th largest Fibonacci number in y and if no
                                remainder, update t by dividing by this number.
                                Decrementing j means that after a later increment, no
                                change to j occurs, allowing for numbers that are 
                                divisible by the same Fibonacci number more than once by
                                testing again with the same j
    if t<2:c+=1;j=x             If repeated division by ever-smaller Fibonacci numbers
                                leaves 1, i must be a Fibonacci product and c is
                                incremented. Setting j equal to x causes j to be reset
                                to 0 during the next loop execution
    j+=1                        Increment j
print(i)                        i must now be the x th Fibonacci product. Print i to STDOUT

Ideone पर इसे आज़माएं


2

पायथन 2, 120 107 बाइट्स

g=lambda k:1/k+any(k%i==0<g(k/i)for i in F)
F=2,3;k=0;n=input()
while n:F+=F[k]+F[-1],;k+=1;n-=g(k)
print k

Ideone पर इसका परीक्षण करें ।

यह काम किस प्रकार करता है

हम F को टुपल (2, 3) (पहले दो फाइबोनैचि संख्या 1 से अधिक ), k को 0 और n को STDIN से पढ़े गए पूर्णांक के रूप में आरंभीकृत करते हैं।

जबकि n सकारात्मक है, हम निम्नलिखित करते हैं:

  • F [k] + F [-1] के रूप में गणना की गई अगले फाइबोनैचि संख्या को जोड़ दें, अर्थात, F के अंतिम दो तत्वों का योग F टुपल F तक

  • वृद्धि k

  • N से g (k) घटाएँ ।

जी रिटर्न 1 यदि और केवल यदि k फाइबोनैचि संख्या का एक उत्पाद है, तो एक बार है n तक पहुँच जाता है 0 , कश्मीर है n वें फिबोनैकी संख्या और हम STDOUT करने के लिए इसे प्रिंट।

g अपने उद्देश्य को इस प्रकार प्राप्त करता है।

  • अगर कश्मीर है 1 , यह फाइबोनैचि संख्या का एक उत्पाद है, और 1/kहै कि हम वापसी बनाता है 1

  • यदि k 1 से अधिक है , तो हम g(k/i)सभी Fibnote संख्याओं के लिए पुनरावर्ती रूप से I को F कहते हैं

    g(k/i)पुनरावर्ती परीक्षण यदि k / i एक फाइबोनैचि संख्या उत्पाद है। अगर g(k/i)रिटर्न 1 और मैं बांटता k समान रूप से कश्मीर% i = 0 और शर्त k%i<g(k/i)रखती है, तो जी वापस आ जाएगी 1 यदि और केवल यदि वहाँ एक फाइबोनैचि संख्या है ऐसी है कि कश्मीर के उत्पाद है कि फिबोनैकी संख्या और फाइबोनैचि संख्या के एक अन्य उत्पाद के।


1

जावास्क्रिप्ट (ईएस 6), 136

मेरे पीसी में लगभग 8 सेकंड में 100 शब्द गणना करते हुए, इस तरह से धीमा गोल्फ हुआ।

(n,F=i=>i>1?F(i-1)+F(i-2):i+1,K=(n,i=1,d,x)=>eval('for(;(d=F(i++))<=n&&!(x=!(n%d)&&K(n/d)););x||n<2'))=>eval('for(a=0;n;)K(++a)&&--n;a')

कम गोल्फ और तेज भी (परहेज eval)

n=>{
  F=i=> i>1 ? F(i-1)+F(i-2) : i+1; // recursive calc Fibonacci number
  K=(n,i=1,d,x)=>{ // recursive check divisibility
    for(; (d=F(i++))<=n && !(x=!(n%d)&&K(n/d)); );
    return x||n<2
  };
  for(a=0; n; )
    K(++a) && --n;
  return a
}

परीक्षा

X=(n,F=i=>i>1?F(i-1)+F(i-2):i+1,K=(n,i=1,d,x)=>eval('for(;(d=F(i++))<=n&&!(x=!(n%d)&&K(n/d)););x||n<2'))=>eval('for(a=0;n;)K(++a)&&--n;a')

function test() {
  var i=+I.value
  O.textContent=X(i)
}

test()
<input id=I value=100 >
<button onclick="test()">Go</button><pre id=O></pre>


1

हास्केल, 123 बाइट्स

f=2:scanl(+)3f
m((a:b):c)=a:m(b?(a#c))
v#((a:b):c)|v==a=b?(v#c)
_#l=l
y?(z:e)|y>z=z:y?e
a?b=a:b
l=1:m[[a*b|b<-l]|a<-f]
(l!!)

बहुत आलसी, बहुत असीम!

संभवतः शॉर्ट्स तरीका नहीं है, लेकिन मुझे इस दृष्टिकोण की कोशिश करनी थी, हमिंग नंबरों की सूची की गणना करने के लिए एक काफी प्रसिद्ध विधि का एक सामान्यीकरण। f2 से शुरू होने वाली संख्याओं की सूची है। संक्षिप्तता के लिए, मान लीजिए कि एक lol (सूचियों की सूची) क्रमबद्ध अनंत सूचियों की एक अनंत सूची है, जो उनके पहले तत्वों द्वारा क्रमबद्ध है। mडुप्लिकेट को हटाने के लिए एक योग्य विलय करने के लिए एक समारोह है। यह दो infix सहायक कार्यों का उपयोग करता है। ?एक अनंत क्रमबद्ध सूची को एक लोल में सम्मिलित करता है। #पहली सूचियों के प्रमुख के रूप में प्रकट होने वाले एक लोल से मान को हटाता है, शेष सूची को फिर से जोड़कर ?

अंत में, lसंख्याओं की सूची है जो कि संख्याओं के उत्पाद हैं, जिन्हें 1 के रूप में परिभाषित किया गया है और इसके बाद प्राप्त की गई सभी सूचियों lको एक संख्या के साथ गुणा करके प्राप्त किया जाता है । अंतिम पंक्ति आवश्यक फ़ंक्शन को बताती है (सामान्य रूप से इसे बिना नाम दिए, इसलिए इसे कॉपी न करें) !!सूची में अनुक्रमणिका का उपयोग करके , जो फ़ंक्शन को 0-अनुक्रमित करता है।

100 वीं या 100,000 वीं संख्या की गणना में कोई समस्या नहीं है।


1

भूसी , 13 बाइट्स

ध्यान दें कि हस्क इस चुनौती से नया है। हालांकि यह और इस गोल्फ के लिए सबसे उपयोगी कार्य ( Ξ) इस चुनौती को ध्यान में रखकर नहीं बनाया गया था।

S!!Ṡ¡ȯuΞIṪ*İf

इसे ऑनलाइन आज़माएं!

14 बाइट्स के लिए अधिक कुशल संस्करण:

इसे ऑनलाइन आज़माएं!


0

अजगर 2, 129 128 125 123 121 बाइट्स

g=lambda k:1/k|any(abs(round(5**.5*i)**2-5*i*i)==4>k%i<g(k/i)for i in range(k+1))
f=lambda n,k=1:n and f(n-g(k),k+1)or~-k

Ideone पर इसका परीक्षण करें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.