पायलट बचाओ!


12

सवाल

हमें उनके अंतरिक्ष स्टेशन पर रोबोट सेना द्वारा कब्जा कर लिया गया है। हमारा स्पेस शिप पायलट जेल में है जो कि लेवल 1 में है। बचने का एक ही तरीका है और वो है अपने स्पेस शिप पायलट को बचाना। इसका मतलब है कि इसका स्तर N से स्तर 1 तक बढ़ रहा है। हालाँकि यह बहुत जोखिम भरा है क्योंकि आपको जेल में कम से कम कदम उठाने की जरूरत है।

शर्तेँ

  • वहाँ जाने के 4 तरीके हैं:

    1. स्तर N से स्तर N - 1 पर जाएँ e.g. from 12 to 11
    2. स्तर N से स्तर N + 1 पर जाएँ e.g. from 12 to 13
    3. टेलीकॉम का इस्तेमाल लेवल 2k से लेवल k तक करें e.g. from 12 to 6
    4. 3k से लेवल k तक teleport का उपयोग करें e.g. from 12 to 4
  • टेलीपोर्ट केवल एक-तरफ़ा हैं (आप 12 से 4 में प्राप्त कर सकते हैं लेकिन यह 4 से 12 तक पहुंचना असंभव है)

  • हर क्रिया एक कदम उठाती है

इनपुट

इनपुट को STDIN, या आपकी प्रोग्रामिंग भाषा में निकटतम विकल्प से पढ़ा जाना चाहिए। इनपुट में एक पूर्णांक होता है nजहां 1 <= n <= 10^8

उत्पादन

आउटपुट को न्यूनतम चरणों की संख्या होनी चाहिए जो nकि स्तर 1 से जाने के लिए होती है।

उदाहरण

Level         Minimum number of steps
1             0
8             3
10            3
267           7
100,000,000   25

कोड प्रोग्राम की कोशिश करें जो हमें कम से कम समय में जेल से हमारे अंतरिक्ष जहाज पायलट को बचाने और घर लौटने में मदद करेगा!

सबसे छोटा कोड जीत जाएगा!


7
यह सलाह दी जाती है कि (लेकिन अनिवार्य नहीं) किसी उत्तर को स्वीकार करने से पहले कम से कम एक सप्ताह इंतजार करना चाहिए। भले ही आप स्वीकार किए गए उत्तर को बदलने का इरादा रखते हैं यदि भविष्य में एक छोटा पोस्ट किया जाता है, तो दूसरों को यह धारणा मिल सकती है कि यह प्रतियोगिता "खत्म" है और भाग लेने से बचना चाहिए।
डेनिस

1
यह चुनौती मुझे एक ऐसे खेल की याद दिलाती है जिसे मैं अपने कैलकुलेटर के साथ खेला करता था: मैं एक नंबर टाइप करूंगा जो स्क्रीन को भरता है और 2, 3, या 5 से विभाजित करने की कोशिश करता है जितना मैं कर सकता हूं, फिर 1 जोड़ना / घटाना और जारी रखना।
आर्कटिकस

जवाबों:


8

पायथ, 32 बाइट्स

L?<b3tbhSsmm+h%_Wkbdy/+kbd2tS3yQ

इसे ऑनलाइन आज़माएँ: प्रदर्शन या टेस्ट सूट

स्पष्टीकरण:

मैंने समस्या को थोड़ा बदल दिया। मैं 4 नए कार्यों को परिभाषित करता हूं, जो प्रश्न के 4 संचालन को प्रतिस्थापित करते हैं।

  • level / 2( (level % 2) + 1कदम के रूप में गिना जाता है , क्योंकि आपको टेलीपोर्ट के लिए पहले एक स्तर नीचे ले जाने की आवश्यकता हो सकती है)
  • (level + 1) / 2( (level % 2) + 1कदम के रूप में मायने रखता है )
  • level / 3( (level % 3) + 1कदम के रूप में मायने रखता है )
  • (level + 1) / 3( (-level % 3) + 1कदम के रूप में मायने रखता है )

डिजाइन द्वारा इन आपरेशनों प्रत्येक संख्या के लिए लागू किया जा सकता है, संख्या है अगर 0 mod 2, 1 mod 2, 0 mod 3, 1 mod 3या 2 mod 3

आप आसानी से सोच सकते हैं कि यह क्यों काम करता है। मुख्य विचार यह है, कि कम से कम एक इष्टतम समाधान है, जिसमें एक पंक्ति में दो (नीचे ले जाना) या दो (चाल) नहीं हैं। प्रमाण: यदि आपके पास एक समाधान है, जिसमें एक पंक्ति में दो ऐसे गति हैं, तो आप उनकी जगह ले सकते हैं और समाधान को छोटा या बराबर कर सकते हैं। उदाहरण के लिए, आप बदल सकते हैं (ऊपर जाएँ, ऊपर जाएँ, 2k से k तक टेलीपोर्ट करें) (2k से k तक का टेलीपोर्ट, ऊपर जाएँ) और अन्य सभी मामलों में समान।

L?<b3tbhSsmm+h%_Wkbdy/+kbd2tS3yQ
L                                 define a function y(b), which returns:
 ?<b3                               if b < 3:
     tb                               return b-1
                                    else:
          m                tS3        map each d in [2, 3] to:
           m              2             map each k in [0, 1] to:
              %_Wkbd                      (b mod d) if k == 0 else (-b mod d)
             h                            +1, this gives the additional steps
            +       y/+kbd                + f((b+k)/d) (recursive call)
         s                            combine the two lists
       hS                             and return the minimum element
                               yQ call y with input number

फ़ंक्शन yअनुमानित रूप से संस्मरण का उपयोग करता है और इसलिए रनटाइम विस्फोट नहीं करता है।


1
मुख्य विचार यह है, कि इष्टतम समाधान में एक पंक्ति में कभी दो (नीचे स्थानांतरित) या दो (चाल) नहीं हैं। - 29 के बारे में क्या -> 28 -> 27 -> 9 -> 3 -> 1? यदि यह एक इष्टतम समाधान है, तो आपने यह कैसे तय किया कि दो-अप / दो-डाउन पथ के लिए हमेशा एक विकल्प होता है, जो संख्याओं के अधिक अजीब क्षेत्र में आगे नहीं बढ़ता है?
TessellatingHeckler

1
@TessellatingHeckler शायद मुझे अधिक सटीक होना चाहिए। नहीं है कम से कम एक इष्टतम समाधान, कि एक पंक्ति में दो (नीचे ले जाने के) या दो (ऊपर ले जाएँ) गति नहीं है। जैसे 29 -> 30 -> 10 -> 9 -> 3 -> 1
जकुब

मैं यह नहीं कहता कि यह गलत है, केवल यह कि मैं "इस बारे में आसानी से नहीं सोच सकता कि यह क्यों काम करता है"। मैं तर्क कर रहा था: कमरे 1 का सबसे तेज़ रास्ता तीन की शक्ति से शुरू हो रहा है, तीन हर चाल से विभाजित है। तो तीन की शक्ति के पास संख्याओं के लिए सबसे तेज़ मार्ग बार-बार घटाया जाता है या तीन की शक्ति को प्राप्त करने के लिए जोड़ा जाता है, फिर 3 से बार-बार विभाजित करते हैं। यदि इसके बजाय वे बढ़ते हुए n / 2 से शुरू करते हैं, तो वे तीन की शक्ति से आगे बढ़ते हैं, और इसलिए सबसे तेज़ संभव मार्ग पिछले। मैं नहीं देखता कि वे कैसे / हमेशा / दूसरे मार्ग को समान रूप से छोटा पाएंगे; ऐसा लगता है कि वे अब 'बदतर' विकल्प वाले क्षेत्र में हैं।
TessellatingHeckler 12

4

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

n=int(1e8);s,f,L=0,input(),[1,0]+[n]*(n-1)
def h(q):
 if 0<=q<=n and L[q]>s:L[q]=s+1
while n in L:
 for i,v in enumerate(L):
  if v==s:map(h,(i-1,i+1,i*2,i*3))
 s+=1
print L[f]

ब्रूट बल सभी तरह से; 1 to 100,000,00064 बिट कंप्यूटर पर सभी नंबरों की एक सूची है ~ 800Mb मेमोरी।

सूची सूचकांक संख्याओं का प्रतिनिधित्व करता है, मान अनुमत बचाव चरणों में 1 से दूरी का प्रतिनिधित्व करते हैं।

  • सेट सूची [1] = 0 का अर्थ है "0 चरणों में पहुंचने योग्य"।
  • सूची में प्रत्येक संख्या के लिए जो 0 चरणों में उपलब्ध है (यानी 1)
    • सेट नंबर + 1, नंबर -1, नंबर * 2, नंबर * 3 1 चरण में उपलब्ध है
  • सूची में प्रत्येक संख्या के लिए जो 1 चरण में उपलब्ध है (अर्थात 0,2,2,3)
    • सेट नंबर + 1, नंबर -1, नंबर * 2, नंबर * 3 2 चरणों में उपलब्ध है
  • ... आदि जब तक हर सूची सूचकांक नहीं पहुंच जाता है।

रनटाइम 10 मिनट से थोड़ा अधिक है। * अहम *।

कोड टिप्पणियाँ

n=int(1e8)           # max input limit.
s=0                  # tracks moves from 1 to a given number.
f=input()            # user input.

L=[1,0]+[n]*(n-1)    # A list where 0 can get to room 1 in 1 step,
                     # 1 can get to itself in 0 steps,
                     # all other rooms can get to room 1 in 
                     # max-input-limit steps as a huge upper bound.


def helper(q):
    if 0<=q<=n:      # Don't exceed the list boundaries.
      if L[q]>s:     # If we've already got to this room in fewer steps
                     # don't update it with a longer path.
          L[q]=s+1   # Can get between rooms 1 and q in steps+1 actions.


while n in L:        # until there are no values still at the 
                     # original huge upper bound

 for i,v in enumerate(L):
  if v==s:                            # only pick out list items
                                      # rechable in current s steps,
      map(helper,(i-1,i+1,i*2,i*3))   # and set the next ones reachable
                                      # in s+1 steps.

 s+=1                                 # Go through the list again to find
                                      # rooms reachable in s+1 steps

print L[f]                            # show answer to the user.

अन्य

  • यदि आप इसे पायथनविन में चलाते हैं, तो आप बाद में दुभाषिया में सूची एल तक पहुंच सकते हैं।
  • हर कमरे में कप्तान के पास 30 चालों या उससे कम समय में एक रास्ता है।
  • केवल एक कमरा 30 कदम दूर है - कमरा 72,559,411 - और 244 कमरे हैं जो 29 चाल दूर हैं।
  • इसमें अधिकतम मामले के लिए भयानक रनटाइम विशेषताएँ हो सकती हैं, लेकिन एक प्रश्न टिप्पणी है " @Geobits सभी प्रोग्राम जो 5 मिनट में 20000 परीक्षण मामलों के लिए सबसे छोटे तरीके खोजने चाहिए " और यह 6 सेकंड में 1-20,001 का परीक्षण करता है।

2

अजगर 2 ... 1050

खराब लिखा हुआ, अपराजित, अडिग।

स्टड पर प्रारंभ स्तर को पढ़ता है, स्टडआउट पर न्यूनतम संख्या में चरण प्रिंट करता है।

def neighbors(l):
    yield l+1
    yield l-1
    if not l%3:yield l/3
    if not l%2:yield l/2

def findpath(start, goal):
    closedset = set([])
    openset = set([start])
    came_from = {}
    g_score = {}
    g_score[start] = 0
    f_score = {}
    f_score[start] = 1
    while len(openset) > 0:
        current = min(f_score, key=f_score.get)
        if current == goal:
            return came_from
        else:
            openset.discard(current)
        del f_score[current]
        closedset.add(current)
        for neighbor in neighbors(current):
            if neighbor in closedset:
                continue
            tentative_g_score = g_score[current] + 1
            if (neighbor not in openset) or (tentative_g_score < g_score[neighbor]):
                came_from[neighbor] = current
                g_score[neighbor] = tentative_g_score
                f_score[neighbor] = tentative_g_score + 1
                openset.add(neighbor)
def min_path(n):
    path = findpath(n,1)
    i,current = 0,1
    while current <> n:
        i+=1
        current = path[current]
    return i
print min_path(input())

2

32-बिट x86 मशीन कोड, 59 बाइट्स

हेक्स में:

31c9487435405031d231dbb103f7f14a7c070f94c301d008d353e8e3ffffff5b00c3585331d2b102f7f152e8d2ffffff5a00d05a38d076019240c3

मशीन भाषा प्रति se में मानक इनपुट की कोई अवधारणा नहीं है। चूंकि चुनौती शुद्ध कम्प्यूटेशनल है, इसलिए मैंने इनपुट पैरामीटर लेने वाले एक फंक्शन को लिखने का विकल्प चुना EAXऔर इसमें परिणाम लौटाया AL

कोड के पीछे के गणित को @ जाकुब द्वारा अच्छी तरह से समझाया गया है: खोज केवल उन रास्तों के बीच में आयोजित की जाती है, जिनके पास एक से अधिक एक-स्तरीय चालों वाले टेलीपोर्ट्स होते हैं। प्रदर्शन इनपुट रेंज के निचले सिरे में प्रति सेकंड लगभग 12000 परीक्षण मामले और ऊपरी अंत में 50 मामले प्रति सेकंड है। मेमोरी खपत रिकर्सन लेवल के प्रति स्टैक स्पेस के 12 बाइट्स है।

0:  31 c9               xor ecx, ecx  
_proc:
2:  48                  dec eax       
3:  74 35               je _ret       ;if (EAX==1) return 0;
5:  40                  inc eax       ;Restore EAX
6:  50                  push eax      
7:  31 d2               xor edx, edx  ;Prepare EDX for 'div'
9:  31 db               xor ebx, ebx  
b:  b1 03               mov cl, 3     
d:  f7 f1               div ecx       ;EAX=int(EAX/3); EDX=EAX%3
f:  4a                  dec edx       ;EDX is [-1..1]
10: 7c 07               jl _div3      ;EDX<0 (i.e. EAX%3==0)
12: 0f 94 c3            sete bl       ;BL=EDX==0?1:0
15: 01 d0               add eax, edx  ;If EAX%3==2, we'd go +1 level before teleport
17: 08 d3               or bl, dl     ;BL=EAX%3!=0
_div3:
19: 53                  push ebx      ;Save register before...
1a: e8 e3 ff ff ff      call _proc    ;...recursive call
1f: 5b                  pop ebx       
20: 00 c3               add bl, al    ;BL is now # of steps if taken 3n->n route (adjusted) less one
22: 58                  pop eax       ;Restore original input parameter's value
23: 53                  push ebx      
24: 31 d2               xor edx, edx  
26: b1 02               mov cl, 2     
28: f7 f1               div ecx       ;EAX=EAX>>1; EDX=EAX%2
2a: 52                  push edx      ;Save register before...
2b: e8 d2 ff ff ff      call _proc    ;...another recursive call
30: 5a                  pop edx       
31: 00 d0               add al, dl    ;AL is now # of steps if using 2n->n route (adjusted) less one
33: 5a                  pop edx       
34: 38 d0               cmp al, dl    ;Compare two routes
36: 76 01               jbe _nsw      
38: 92                  xchg eax, edx ;EAX=min(EAX,EDX)
_nsw:
39: 40                  inc eax       ;Add one for the teleport itself
_ret:
3a: c3                  ret           
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.