स्टिकस्टैक नंबर


22

स्टिकस्टैक केवल दो निर्देशों के साथ एक बहुत ही सरल स्टैक-आधारित प्रोग्रामिंग भाषा है:

  • | स्टैक पर स्टैक की लंबाई को धक्का देता है
  • -स्टैक से शीर्ष दो तत्वों को निकालता है और उनके अंतर को वापस धकेलता है ( second topmost - topmost)

भाषा का विवरण

  • कार्यक्रम की शुरुआत में स्टैक खाली है।
  • सभी निर्देशों को क्रमिक रूप से बाएं से दाएं निष्पादित किया जाता है।
  • यदि स्टैक पर 2 से कम नंबर हैं, तो -निर्देश अवैध है।
  • निष्पादन के अंत में स्टैक में ठीक एक नंबर होना चाहिए ।

किसी भी पूर्णांक को स्टिकस्टैक प्रोग्राम द्वारा उत्पन्न किया जा सकता है। उदाहरण के लिए:

|||--||-- generates the number 2 through the following stack states:

[]
[0]
[0, 1]
[0, 1, 2]
[0, -1]
[1]
[1, 1]
[1, 1, 2]
[1, -1]
[2]    

अपने स्टिकस्टैक कोड का मूल्यांकन करने के लिए आप इस ऑनलाइन (CJam) मूल्यांकनकर्ता का उपयोग कर सकते हैं । (कोड के लिए @ मर्टिन के लिए धन्यवाद।)

काम

आपको एक प्रोग्राम या फ़ंक्शन लिखना चाहिए जो इनपुट आउटपुट के रूप में एक पूर्णांक संख्या देता है या एक स्टिकैक प्रोग्राम का प्रतिनिधित्व करने वाला स्ट्रिंग देता है जो दिए गए नंबर को आउटपुट करता है।

स्कोरिंग

  • आपका प्राथमिक स्कोर नीचे दिए गए परीक्षण मामलों के लिए स्टिकस्टैक कार्यक्रमों की कुल लंबाई है । लोअर स्कोर बेहतर है।
  • आपका सबमिशन तभी मान्य होता है जब आप सभी प्रोग्राम मामलों पर अपना प्रोग्राम चलाते हैं और अपना स्कोर गिनाते हैं।
  • आपका द्वितीयक (टाईब्रेकर) स्कोर आपके निर्माण कार्यक्रम या कार्य की लंबाई है।

इनपुट परीक्षण के मामले

(प्रत्येक संख्या एक अलग परीक्षण मामला है।)

-8607 -6615 -6439 -4596 -4195 -1285 -72 12 254 1331 3366 3956 5075 5518 5971 7184 7639 8630 9201 9730

आपका प्रोग्राम किसी भी पूर्णांक (जो आपके डेटा-प्रकार को संभाल सकता है) के लिए काम करना चाहिए न कि दिए गए परीक्षण मामलों के लिए। परीक्षण संख्याओं के समाधान को आपके प्रोग्राम में हार्डकोड नहीं किया जाना चाहिए। यदि हार्डकॉडिंग का संदेह होगा, तो परीक्षण संख्या बदल दी जाएगी।


मैं एक ऐसा खंड जोड़ने का सुझाव देता हूं जो कहता है कि "और एक उचित समय में चलता है" जानवर-बल को रोकने के लिए।

@ वैयक्तिकता "केवल तभी मान्य होती है जब आप सभी परीक्षण मामलों पर अपना कार्यक्रम चलाते हैं"
edc65

जवाबों:


7

अजगर 2 - 5188

काफी कुशल समय-वार, और लगता है (शायद) इष्टतम समाधान है। मैंने देखा कि एक पैटर्न जैसे

|||||-|||-|-|-|------ (25 के लिए एक इष्टतम समाधान)

के रूप में चित्रित किया जा सकता है

 0  |
-1  |                  
+2   |                 -
-3    |               -
+4     | |           -
-5      - |         -
+6         | | | | -
-7          - - - -

जहां अंत में प्रत्येक कुल मूल्य का योग है (प्रत्येक स्तर के मूल्य की संख्या '|' s) है। तो ऊपर के उदाहरण के लिए, हमारे पास है -1*1 + 2*1 - 3*1 + 4*2 - 5*1 + 6*4 = 25। इसका उपयोग करते हुए मैंने यह समाधान लिखा, जो अन्य उत्तरों के समान उत्पादन करता है, और तुच्छ समय में।

मेरा मानना ​​है कि यह इष्टतम समाधान है, क्योंकि मैं हर संभव इष्टतम ऊंचाई का परीक्षण करता हूं (मैं वास्तव में आवश्यकता से कई अधिक परीक्षण करता हूं) और मुझे पूरा यकीन है कि समाधान में हमेशा दो के साथ सबसे अधिक एक परत शामिल होती है। अंतिम के अलावा सकारात्मक संख्याओं के लिए इसकी गारंटी दें लेकिन नकारात्मक के बारे में 100% निश्चित नहीं)।

def solution(num):
    if num == 0:
        return '|'

    neg = num<0
    num = abs(num)
    high = int(num**0.5)

    def sub(high):
        counts = [1]*high
        total = num - (high+neg)/2

        if total%high == 0:
            counts[-1] += total/high
        else:
            counts[-1] += total/high
            if (total%high)%2==1 and not neg:
                counts[-1] += 1
                counts[-(total%high)-1] += 1
            elif (total%high)%2==0 and neg:
                counts[(total%high)-2] += 1
                counts[0] += 1
            else:
                counts[total%high-1] += 1

        string = ""
        for c in counts[::-1]:
            string = '|-'*(c-1)+'|'+string+'-'
        return '|'+string

    return min((sub(h) for h in range(2-neg,2*high+2,2)), key=lambda s: len(s))

यहाँ वह कोड है जो मैंने इसका परीक्षण किया था

string = "-8607 -6615 -6439 -4596 -4195 -1285 -72 12 254 1331 3366 3956 5075 5518 5971 7184 7639 8630 9201 9730"
total = 0

def string_to_binary(string):
    total = 0
    for i,char in enumerate(string[::-1]):
        total += (char=='|')*(2**i)
    return total

def stickstack(bits,length):
    stack = []
    for i in range(length):
        d,bits = divmod(bits,2**(length-i-1))
        if d == 1:
            stack.append(len(stack))
        else:
            stack[-2] -= stack[-1]
            stack = stack[:-1]
    return stack

for num in string.split():
    s = solution(int(num))
    print '%s:' % num
    print s
    result = stickstack(string_to_binary(s),len(s))
    print 'Result: %s' % result
    print 'Length: %s' % len(s)
    total += len(s)
    print

print 'Total length: %s' % total

2
महान समाधान! मेरा मानना ​​है कि स्कोर इष्टतम है (मेरे bruteforce गणना के आधार पर) और आपके विवरण के आधार पर मुझे लगता है कि आपका एल्गोरिदम हमेशा सबसे अच्छा समाधान देता है।
रैंडमरा

@randomra मुझे लगता है कि इसकी संभावना है कि यह है, लेकिन मैं केवल के बारे में मजबूर किया गया था +/- 100 तो मैं यह कहने के लिए तैयार नहीं था कि यह आवश्यक रूप से सबसे अच्छा था, लेकिन अब मुझे लगता है कि मैं इसके बारे में नहीं देख सकता यह कैसे बेहतर हो सकता है।
केसाब

+1 बहुत अच्छा। मैं इसे कैसे आज़मा सकता हूँ? क्या अजगर? (मैं एक अजगर नहीं हूं, मेरे पास सिर्फ आकस्मिक रूप से एक अजगर 3.4 है जो मेरे लैपटॉप पर स्थापित है)।
edc65

@ edc65 मैंने इसे जांचने के लिए कोड जोड़ा; यह भी पायथन 2.7 का उपयोग कर रहा है, इसलिए प्रिंट स्टेटमेंट की तरह काम पायथन 3 के साथ काम नहीं करेगा
केएसएबी

इसके लायक क्या है, मैं पुष्टि कर सकता हूं कि यह परिणाम इष्टतम है: मैंने एक जानवर बल समाधान (वास्तव में एक बीएफएस) की कोशिश की, 450 की लंबाई (और अभी भी चल रहा है) की पुष्टि की। वही तुम्हारा परिणाम है।
edc65

12

जावा, 5208 5240 5306 6152

यह एक पुनरावर्ती फ़ंक्शन है जो लक्ष्य के करीब किनारों पर है, जब यह 5 के भीतर हो जाता है, तो आधार मामलों के साथ (जो अक्सर केवल एक कदम होता है)।

मूल रूप से, आप एक साधारण पैटर्न के साथ लाठी के (a*b)+(a/2)लिए प्राप्त कर सकते हैं (a+b)*2। यदि aविषम है, तो परिणाम नकारात्मक होगा, जिससे कुछ अजीब तर्क हो सकता है।

परिणाम के रूप में 185,367 की लंबाई के साथ, 2 या 31 मिनट के लिए एक मिनट का समय लगता है । यह सभी परीक्षण मामलों के लिए लगभग तुरंत काम करता है, हालांकि। यह 4*(sqrt|n|)औसत पर स्कोर करता है। सबसे लंबा व्यक्तिगत परीक्षण मामला है 9730, जिसके परिणामस्वरूप 397-लंबाई स्टिक स्टैक होता है:

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||-|||||||||||||||||||||-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|--------------------------------------------------------------------------------------------------|-

अद्यतन करें:

मूल पैटर्न से जोड़ने / घटाने का एक छोटा तरीका मिला। वापस नेतृत्व में (अभी के लिए)!


एक दोहन और परीक्षण मामलों के साथ:

import static java.lang.Math.*;

public class StickStacker {

    public static void main(String[] args){
        StickStacker stacker = new StickStacker(); 
        int tests[] = {-8607,-6615,-6439,-4596,-4195,-1285,-72,12,254,1331,3366,3956,5075,5518,5971,7184,7639,8630,9201,9730};
        int sum = 0;
        for(int test : tests){
            String sticks = stacker.stickStack3(test);
            sum += sticks.length();
            System.out.println("In: " + test + "\t\tLength: " + sticks.length());
            System.out.println(sticks+"\n");
        }
        System.out.println("\n\nTotal: "+sum);          
    }

    String stickStack3(int n){return"|"+k(n);}
    String k(int n){
        String o="";
        int q=(int)sqrt(abs(n)),a,b,d=1,e=0,c=1<<30,
        z[]={232,170,42,10,2,0,12,210,52,844,212};
        a=n>0?q:-q;
        a-=n>0?a%2<1?0:1:a%2<0?0:-1;

        for(b=0;b<abs(a)+10;b++)
            if(abs(n-(a*b+a/2-(n>0?0:1)))<abs(a)&&abs(a)+b<c){
                    c=abs(a)+b;
                    d=a;e=b;
            }

        for(a=0;a++<e;)o+="-|";
        for(a=0;a++<abs(d);)o="|"+o+"-";

        c=n-(d*e+d/2-(n>0?0:1));
        if(c>0&&c<abs(d)){
            if(c%2==0)
                o=o.substring(0,c)+"-|"+o.substring(c);
            else
                o=o.substring(0,c+1)+"-|"+o.substring(c+1)+"|-";
            c=0;
        }else if(c<0&-c<abs(d)){
            if(c%2!=0)
                o=o.substring(0,-c)+"-|"+o.substring(-c);
            else
                o=o.substring(0,-c-1)+"-|"+o.substring(-c-1)+"|-";  
            c=0;
        }

        return n==0?"":n<6&&n>-6?
                Long.toBinaryString(z[n+5])
                .replaceAll("0","-")
                .replaceAll("1","|"):
                o+k(c);
    }
}

विल गोल्फ (अधिक) एक सटीक टाई की अप्रत्याशित घटना में।


क्या आप 2 ^ 31 के अपने स्कोर के बारे में निश्चित हैं? 2 ^ 30 के लिए मेरा स्कोर 131099 है, और 2 ^ 31-1 के लिए 185369 है।
edc65

@ edc65 मैंने इसे गलत लिखा होगा। मुझे लगा कि यह थोड़ा कम लग रहा है ... वैसे भी, ध्यान देने के लिए धन्यवाद, और कुछ प्रतियोगिता देने के लिए। अब यह देखने का समय है कि क्या मैं बेहतर कर सकता हूं :)
ज्योबिट्स

4

जावास्क्रिप्ट (ईएस 6) 5296 6572

संपादित करें जैसा कि मैंने कहा मेरा विवरण में, मैं पूर्णांक समीकरणों को हल करने में अच्छा नहीं कर रहा हूँ। बी मूल्य का मेरा अनुमान इतना अच्छा नहीं था, इसलिए मैंने कोशिश करने के लिए मूल्यों की सीमा को चौड़ा किया है। और (वाह) मैं अब तक अग्रणी हूं।

2 बग फिक्स संपादित करें , वही परिणाम। मैं एक विचार है, लेकिन इसे नीचे कील नहीं कर सकते।

बाइट्स: ~ 460, काफी गोल्फ। यह 32 बिट पूर्णांक पर काम करता है, 0 के पास समय चलाता है।

कोड नीचे F फ़ंक्शन (स्निपेट में छिपा हुआ) है।
परीक्षण करने के लिए स्निपेट (फ़ायरफ़ॉक्स में) चलाएं।

व्याख्या

सकारात्मक संख्या, के साथ शुरू करने के लिए। एक "आधार" के साथ शुरू करें (यदि आप चाहें तो सीजेएम में प्रयास करें, रिक्त स्थान की अनुमति है)

| gives 0  
||| -- gives 1
||||| ---- gives 2
||||||| ------ gives 3 

सारांश: 1 स्टिक, फिर बी * 2 स्टिक, फिर बी * 2 डैश

फिर एक या अधिक जोड़ने का प्रयास करें '- |' बीच में विभाजित। प्रत्येक एक निश्चित वेतन वृद्धि जोड़ देता है जो शुरुआती आधार का दो गुना है और कई बार दोहराया जा सकता है। तो हमारे पास एक फॉर्मूला है, जिसमें b = बेस और r = इंक्रीमेंट रिपीट फैक्टर है

v=b+r*2*b

b=1, r=0 to 3, inc=2
| || -- 1 
| || -| -- 3 
| || -| -| -- 5 
| || -| -| -| -- 7

b=3, r=0 to 3, inc=6
| |||||| ------ 3
| |||||| -| ------ 9
| |||||| -| -| ------ 15
| |||||| -| -| -| ------ 21

देख? अतिरिक्त मूल्य जल्दी बढ़ जाता है और प्रत्येक अतिरिक्त अभी भी केवल 2 वर्ण है। आधार वृद्धि हर बार 4 और चार्ट देती है।

V और हमारे सूत्र v = b + r * 2 * b को देखते हुए, हमें 2 ints b और r खोजने की आवश्यकता है। मैं इस तरह के समीकरण का विशेषज्ञ नहीं हूँ, लेकिन b = int sqrt (v / 2) एक अच्छा शुरुआती अनुमान है।

फिर हमारे पास एक r और b होता है जो एक साथ v के पास एक मान देते हैं। हम वी के साथ बार-बार वृद्धि (|| -) या डिक्रीमेंट (- -) तक पहुंचते हैं।

ऋणात्मक संख्याओं के लिए समान तर्क का पालन करें, यद्यपि सूत्र समान है लेकिन समान नहीं है।


1

जावास्क्रिप्ट, 398710

कोड के 94 बाइट्स / चार्ट

मैं एक समाधान के साथ आया था! ... और फिर स्पियर का जवाब पढ़ा और यह बिल्कुल वैसा ही था।

मुझे लगा कि मैं इसे वैसे भी पोस्ट करूंगा, क्योंकि js थोड़े कम चार्ट के लिए अनुमति देता है।

यहाँ कोड का एक अज्ञात संस्करण है:

function p(a){
    s = "";
    if(a<=0){
        for(i=0; i<-2*a-1;i++)
            s="|"+s+"-";
        return "|"+s;
    }
    return "|"+p(0-a)+"-";
}

1
ठीक है, अगर हम 398710 समाधान खेल रहे हैं, पर खेल! कोई व्यक्ति cjam या pyth के साथ आएगा और हम दोनों को हरा देगा, हालांकि :(
Spear

1

पायथन, 398710 (71 बाइट्स)

सबसे सरल संभव समाधान, मुझे लगता है। N का प्रतिनिधित्व करने के लिए स्टिकस्टैक के 4 * n (+/- 1) अक्षरों का उपयोग करता है।

def s(n):return'|'*(n*2+1)+'-'*n*2 if n>=0 else'|'*(n*-2)+'-'*(n*-2-1)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.