न्यूनतम फ़ौजी चुनौती!


19

चुनौती

इस कार्य में आपको एक पूर्णांक N (10 6 से कम ) दिया जाएगा, न्यूनतम तरीका खोजें जिसमें आप केवल फाइबोनैचि संख्याओं का उपयोग करके N को योग कर सकते हैं - इस विभाजन को Zeckendorf प्रतिनिधित्व कहा जाता है ।

आप किसी भी फाइबोनैचि संख्या का एक से अधिक बार उपयोग कर सकते हैं और यदि कोई एक से अधिक प्रतिनिधित्व आउटपुट है।

उदाहरण के लिए यदि इनपुट 67 है तो एक संभावित आउटपुट फाइबोनैचि संख्या 1,3,8,55 का उपयोग कर सकता है, जो कि फाइबोनैचि संख्याओं की न्यूनतम संख्या भी है जिसका उपयोग 67 प्राप्त करने के लिए किया जा सकता है ।

इनपुट N को एक ही लाइन पर दिया गया है, इनपुट EOF द्वारा समाप्त किए गए हैं।

उदाहरण

प्रारूप में दिया गया input: output

0: 0
47: 34+13
3788: 2584+987+144+55+13+5
1646: 1597+34+13+2
25347: 17711+6765+610+233+21+5+2
677: 610+55+8+3+1
343: 233+89+21
3434: 2584+610+233+5+2

प्रतिबन्ध

  • आदानों की संख्या 10 6 मानों से अधिक नहीं होगी ।
  • आपका प्रोग्राम सभी इनपुट के लिए 5 सेकंड से अधिक नहीं चलना चाहिए।
  • आप अपनी पसंद की किसी भी भाषा का उपयोग कर सकते हैं।
  • सबसे छोटा समाधान जीत!

"आप किसी भी फाइबोनैचि संख्या ..." एह? "इनपुट की संख्या 10 ^ 6 मान से अधिक नहीं होगी।" तो हमें कभी भी 10 ^ 6 से अधिक संख्याओं को एक साथ जोड़ने की आवश्यकता नहीं होगी? क्या आपका मतलब है कि इनपुट की राशि 10 ^ 6 से अधिक नहीं होगी?
मेलामोकब

7
Spoilers: 1) लालची एल्गोरिथ्म (इनपुट शून्य होने तक सबसे बड़ी फाइबोनैचि संख्या घटाना) इष्टतम समाधान पैदा करता है। 2) एक इष्टतम समाधान को एक फाइबोनैचि संख्या का दो बार उपयोग करने की आवश्यकता नहीं है (जो 1 से निम्नानुसार है)। 3) एन <= 1000000 के लिए एक इष्टतम समाधान, 14 से अधिक शब्द नहीं होंगे।
जॉय एडम्स

6
@ जॉय: आमतौर पर, लालची एल्गोरिथ्म अलग-अलग फाइबोनैचि संख्याओं के रूप में सकारात्मक पूर्णांक को विघटित करता है, जैसे कि लगातार फाइबोनैचि संख्याओं का उपयोग नहीं किया जाता है (इसे ज़ेकेनडोर्फ़ प्रमेय कहा जाता है)।
नबंवर

1
स्पॉयलर 4: 0 1 से शुरू होने वाले फाइबोनैचि अनुक्रम के 29 शब्द पर्याप्त हैं।
पीटर टेलर

@ नब: गणित के भाग को समझाने के लिए धन्यवाद।
क्विक्सोटिक

जवाबों:


16

मोटोरोला 68000 असेंबली - 34 बाइट्स

(GNU कोडांतरक वाक्यविन्यास)

| short min_fib_partition(long N asm("%d2"), long *out asm("%a0"))
min_fib_partition:
    | Generate Fibonacci numbers on the stack (-1, 1, 0, 1, 1, 2, 3, ..., 1134903170).
    moveq #-1, %d0          | A = -1
    moveq #1, %d1           | B = 1
generate_loop:
    move.l %d0, -(%sp)      | Push A to the stack.
    exg.l %d0, %d1          | A' = B
    add.l %d0, %d1          | B' = A + B
    bvc.s generate_loop     | Stop when signed long overflows.

    | Go back up the stack, partitioning N using the greedy algorithm.
    moveq #0, %d0           | Initialize return value (number of terms).
subtract_loop:
    move.l (%sp)+, %d1      | Pop a Fibonacci number F off the stack.
    cmp.l %d1, %d2          | If N < F, continue to smaller Fibonacci number.
    blt.s subtract_loop
    addq.w #1, %d0          | Increment the term count.
    move.l %d1, (%a0)+      | Append F to the output array.
    sub.l %d1, %d2          | N -= F
    bne.s subtract_loop     | Continue if N has not yet reached zero.

    | Clear the stack by searching for that -1.
clear_stack_loop:
    tst.l (%sp)+
    bge clear_stack_loop

done:
    rts

36 → 34: निर्मित फाइबोनैचि जनरेटर गिनती के बजाय अतिप्रवाह पर रोकते हैं, और 0मामले को ठीक करते हैं इसलिए यह [0]बजाय आउटपुट करता है []। हालाँकि, Nअब एक नकारात्मक दुर्घटनाओं को पार कर रहा है ।

शीर्ष पर टिप्पणी इस फ़ंक्शन का सी प्रोटोटाइप है, भाषा मापदंडों का उपयोग करके यह पहचानने के लिए कि कौन से पैरामीटर कहाँ जाते हैं (डिफ़ॉल्ट रूप से, वे स्टैक पर जाते हैं)।

मेरा TI-89 , इसके 10MHz प्रोसेसर के साथ, इस फ़ंक्शन को 1 - 1,000,000 पर चलाने के लिए 5 मिनट लगते हैं।

हालांकि मशीन कोड गोल्फस्क्रिप्ट समाधान की तुलना में कम (वर्तमान में) है, यह संभवत: सबसे छोटे समाधान के रूप में इसे स्वीकार करना अनुचित होगा क्योंकि:

यदि आपके पास TI-89/92 / V200 है, तो आप यहाँ (पुराना) पूरा प्रोजेक्ट डाउनलोड कर सकते हैं:

https://rapidshare.com/files/154945328/minfib.zip

गुड लक आप वास्तविक फ़ाइल देने के लिए RapidShare। क्या किसी को इस बड़ी फ़ाइलों के लिए एक अच्छे मेजबान का पता है? 8940 बाइट्स का एक बहुत बड़ा कारण है।


आप सूची में एक चौथा बिंदु जोड़ सकते हैं: समाधान आउटपुट को सही प्रारूप में नहीं देता है: पी मैं अकेले स्ट्रिंग शाब्दिक पर 7 वर्णों का उपयोग कर रहा हूं। BTW क्या आप इनपुट 0 के लिए सूची [0] लौटाते हैं? यह मुझे लगता है कि आप खाली सूची लौटाते हैं। यह एक विशेष परेशान करने वाला मामला है।
पीटर टेलर

@Peter टेलर: आप सही कह रहे हैं, मैं चूक गया। मुझे शब्द और शब्द मिल गए। मैं जल्द ही एक पोस्ट करूँगा।
जोए एडम्स

5

जावास्क्रिप्ट (142)

केवल एक बार में एक इनपुट संभालती है। क्योंकि जावास्क्रिप्ट के लिए मल्टी-लाइन इनपुट बेकार है।

k=n=prompt(f=[a=b=1])|0;while((b=a+(a=b))<n)f.push(b);for(i=f.length,g=[];i--;)if(f[i]<=k)g.push(f[i]),k-=f[i];alert(n+': '+(n?g.join('+'):0))

http://jsfiddle.net/EqMXQ/


5

सी, 244 वर्ण

#define P printf
int f[30];int main(){f[28]=f[29]=1;int i=28;for(;i>0;--i)f[i-1]=f[i+1]+f[i];int x;while(scanf("%i",&x)!=-1){P(x?"%i: ":"0: 0\n",x);if(x>0){int i=0,a=0;while(x>0){while(f[i]>x)++i;if(a++)P("+");P("%i",f[i]);x-=f[i];}P("\n");}}}

व्हॉट्सएप के साथ:

#define P printf
int f[30];
int main(){
    f[28] = f[29] = 1;
    int i = 28;
    for(; i > 0; --i) f[i-1] = f[i+1] + f[i];
    int x;
    while(scanf("%i",&x) != -1) {
        P(x ? "%i: " : "0: 0\n",x);
        if(x > 0) {
            int i = 0, a = 0;
            while(x > 0) {
                while(f[i] > x) ++i;
                if(a++) P("+");
                P("%i",f[i]);
                x -= f[i];
            }
            P("\n");
        }
    }
}

यह कार्यक्रम मानक इनपुट से बाहर संख्याओं को पढ़ेगा और मानक आउटपुट पर लिखेगा।


5

गोल्फस्क्रिप्ट, 43 वर्ण

~]{:|': '[{0 1{|>!}{.@+}/;|1$-:|}do]'+'*n}%

मुझे लगता है कि इसे और अधिक प्रयास के साथ 3 से 5 चार्ट तक कम किया जा सकता है। उदाहरण के लिए तो दूर फेंक बेकार बेकार लगता है।


3

एफ # - 282 252 241 वर्ण

let mutable d=int(stdin.ReadLine())
let q=d
let rec f x=if x<2 then 1 else f(x-2)+f(x-1)
let s x=
 d<-d-x
 x
printf"%d: %s"q (Core.string.Join("+",[for i in List.filter(fun x->x<d)[for i in 28..-1..0->f i]do if d-i>=0 then yield s i]))

3

पायथन - 183 चार्ट

कोड के अधिकांश कई आदानों को संभाल रहा है :(

f=lambda a,b,n:b>n and a or f(b,a+b,n)
g=lambda n:n>0and"%d+%s"%(f(0,1,n),g(n-f(0,1,n)))or""
try:
 while 1:
  n=input()
  print "%d: %s"%(n,n<1and"0"or g(n).strip("+"))
except:0

क्या आप n=input()पिछली पंक्ति के अंत में रख सकते हैं ?
mbomb007

मुझे ऐसा लगता है। : \
st0le

तुम भी एक चरित्र को बचाने के बाद अंतरिक्ष को हटा सकते हैंprint
mbomb007

2

गणितज्ञ 88

n = RandomInteger[10000, 10];

Print[k=#,For[i=99;l={},k>0,If[#<=k,k-=#;l~AppendTo~#]&@Fibonacci@i--];":"l~Row~"+"]&/@n

आउटपुट का उदाहरण

3999: 2584+987+377+34+13+3+1
9226: 6765+1597+610+233+21
7225: 6765+377+55+21+5+2
9641: 6765+2584+233+55+3+1
6306: 4181+1597+377+144+5+2
4507: 4181+233+89+3+1
8848: 6765+1597+377+89+13+5+2
6263: 4181+1597+377+89+13+5+1
2034: 1597+377+55+5
6937: 6765+144+21+5+2


1

स्काला - 353 वर्ण (कई इनपुट को संभालने के लिए 100 वर्ण)

def h(m:Int){lazy val f={def g(a:Int,b:Int):Stream[Int]=a #:: g(b,a+b);g(0,1);};if(m==0)println(m+": "+m)else{var s=0;var t= f.takeWhile(_ <= m);var w="";while(s!= m){s+=t.last;w+=t.last+"+";t=t.takeWhile(_<=m-s);};println(m+": "+w.take(w.length-1))}}
Iterator.continually(Console.readLine).takeWhile(_ != "").foreach(line => h(Integer.parseInt(line)))

Iterator.continually(Console.readLine).takeWhile(_ != "").foreach(line => h(Integer.parseInt(line)))io.Source.stdin.getLines.foreach(l=>h(Integer.parseInt(l)))40-ईश वर्णों को सहेजने के लिए छोटा किया जा सकता है ।
गारेथ

1

पायथन 3 (170 वर्ण)

while 1:
 s=input()
 if not s:break
 s=n=int(s);f=[1];t=[]
 while f[-1]<n:f+=[sum(f[-2:])]
 for i in f[::-1]:
  if s>=i:s-=i;t+=[i]
 print(n,'=','+'.join(map(str,t))or 0)

मल्टीलाइन इनपुट, खाली लाइन पर रोक


1

सी, 151 वर्ण

main() {int i=1,n,f[30]={1,1};for(;i++<30;)f[i]=f[i-1]+f[i-2];while(scanf("%d",&n))for(i=30;;--i)if(f[i]<=n){printf("%d\n",f[i]);if(!(n-=f[i]))break;}}

पठनीय संस्करण:

main() {
    int i=1,n,f[30]={1,1};
    for(;i++<30;)f[i]=f[i-1]+f[i-2];
    while(scanf("%d",&n))
        for(i=30;;--i)
            if(f[i]<=n) {
                printf("%d\n",f[i]);
                if (!(n-=f[i])) break;
            }
}

1

आर, 170

x=scan();Filter(function(i)cat(unlist(Map(function(d)if(i>=d&&i){i<<-i-d;d},rev(lapply(Reduce(function(f,x)c(f[2],sum(f)),1:94,c(0,1),F,T),head,n=1)))),sep='+',fill=T),x)

कई निविष्टियाँ संभालता है और बिल्ली STDOUT का परिणाम है

> x=scan();Filter(function(i)cat(unlist(Map(function(d)if(i>=d&&i){i<<-i-d;d},rev(lapply(Reduce(function(f,x)c(f[2],sum(f)),1:94,c(0,1),F,T),head,n=1)))),sep='+',fill=T),x)
1: 100
2: 200
3: 300
4: 
Read 3 items
89+8+3
144+55+1
233+55+8+3+1
numeric(0)
>

1

आर (460 वर्ण)


फ़ाइल "इनपुट" से आर। रीडिंग का उपयोग करते हुए एक और संस्करण , फ़ाइल "आउटपुट" के लिए आउटपुट

d=as.list(as.integer(scan("input","",sep="\n")));n=36;f=rep(1,n);for(i in 3:n){f[i]=f[i-2]+f[i-1]};d2=lapply(d,function(x){a=vector("integer");i=1;while(x>0){id=which(f>=x)[1];if(x==f[id]){x=x-f[id];a[i]=f[id]}else{x=x-f[id-1];a[i]=f[id-1]}i=i+1}a});d=mapply(c,d,d2,SIMPLIFY=0);for(i in 1:length(d)){t=d[[i]];l=length(t);if(l==1){d[[i]]=paste(t[1],t[1],sep=": ")}else{d[[i]]=paste(t[1],": ",paste(t[2:l],collapse="+"),sep="")}}lapply(d,write,"output",append=1)

"इनपुट" उदाहरण

0
47
3788
1646
25347
677
343
3434

"आउटपुट" उदाहरण

0: 0
47: 34+13
3788: 2584+987+144+55+13+5
1646: 1597+34+13+2
25347: 17711+6765+610+233+21+5+2
677: 610+55+8+3+1
343: 233+89+21
3434: 2584+610+233+5+2

अधिक पठनीय संस्करण:

dt <- as.list(as.integer(scan(file = "input", what = "", sep = "\n")))
n <- 36
fib <- rep(1, n)
for(i in 3:n){fib[i] <- fib[i-2] + fib[i-1]}
dt2 <- lapply(dt, function(x){answ <- vector(mode = "integer")
                               i <- 1
                               while(x > 0){
                                   idx <- which(fib>=x)[1]
                                   if(x == fib[idx]){
                                       x <- x - fib[idx]
                                       answ[i] <- fib[idx]
                                   } 
                                   else {
                                       x <- x - fib[idx-1]
                                       answ[i] <- fib[idx-1]
                                   }
                                   i <- i + 1
                               }
                               answ})
dt <- mapply(FUN = c, dt, dt2, SIMPLIFY = FALSE)
for(i in 1:length(dt)){
    t1 <- dt[[i]]
    t1.len <- length(t1)
    if(t1.len == 1){
        dt[[i]] <- paste(t1[1], t1[1], sep=": ")
    } else {
        dt[[i]] <- paste(t1[1], ": ", paste(t1[2:t1.len], collapse = "+"), sep="")
    }
}
lapply(dt, write, "output", append=TRUE)

0

डी (196 वर्ण)

के साथ भागो rdmd --eval=…। यह आसानी से बायलरप्लेट को छुपाता है import x, y, z;और void main() {…}:

int f(int i){return i-->1?f(i--)+f(i):i+2;}int n;foreach(x;std.stdio.stdin.byLine.map!(to!int))writeln(x,": ",x?n=x,reduce!((r,i)=>f(i)<=n?n-=f(i),r~="+"~f(i).text:r)("",29.iota.retro)[1..$]:"0")

0

जावा का उपयोग करना

package org.mindcraft;

import java.util.Scanner;

public class Fibbo {
    public static void main(String[] args) {
    String number = null;
    int tmp, sum;
    int i = 1, j = 1;
    Scanner in = new Scanner(System.in);
    number = in.nextLine();
    String[] arr = number.split(" ");
    for (int it = 0; it < arr.length; it++) {
        tmp = Integer.parseInt(arr[it]);
        String value = tmp+" : ";
        while (tmp > 0) {
            i = 1;
            j = 1;
            for (int k = 0; k < 10000; k++) {
                sum = i + j;
                if (sum > tmp) {
                    //if (value == null) {
                    char ch=value.charAt(value.length()-2);
                    if(ch==':')
                    {
                        value = value+" "+ j + "";
                    } else {
                        value = value + " + " + j;
                    }

                    tmp = tmp - j;
                    break;
                }
                i = j;
                j = sum;
            }
        }
        System.out.println(value);
    }
}
}

यह कोड गोल्फ है, इसलिए अपने उत्तर को गोल्फ के लिए सुनिश्चित करें।
केएसएफटी

1
PPCG में आपका स्वागत है! जैसा कि केएसएफटी ने कहा, यह एक कोड-गोल्फ चुनौती है। कृपया इस प्रश्न का उत्तर कोड के कुछ बाइट्स में देने का प्रयास करें। बहुत कम से कम, आप अनावश्यक व्हाट्सएप को हटा सकते हैं और एकल-अक्षर वर्ग / विधि / चर नाम का उपयोग कर सकते हैं। ऐसा करने के बाद, कृपया अपने उत्तर में बाइट की गिनती भी शामिल करें।
मार्टिन एंडर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.