পাইলটকে বাঁচাও!


12

প্রশ্ন

আমরা তাদের স্পেস স্টেশনে রোবট আর্মি দ্বারা বন্দী হয়েছি। আমাদের স্পেস শিপ পাইলট কারাগারে রয়েছে যা স্তরের পর্যায়ে রয়েছে। কীভাবে পালাতে হবে তার একমাত্র উপায় আছে এবং এটি আপনার মহাকাশ শিপ পাইলটটিকে উদ্ধার করছে। এর অর্থ এটি স্তর এন থেকে স্তর 1 এ চলেছে moving তবে এটি খুব ঝুঁকিপূর্ণ কারণ আপনাকে যতটা সম্ভব কমপক্ষে কয়েকটি পদক্ষেপে কারাগারে পৌঁছানো দরকার।

পরিবেশ

  • কীভাবে সরানো যায় তার 4 উপায় রয়েছে:

    1. স্তর N থেকে স্তর এন - 1 এ সরান e.g. from 12 to 11
    2. স্তর N থেকে স্তর এন + 1 এ যান e.g. from 12 to 13
    3. স্তর 2k থেকে স্তর স্তর পর্যন্ত টেলিপোর্ট ব্যবহার করুন e.g. from 12 to 6
    4. স্তর 3 কে থেকে স্তর স্তর পর্যন্ত টেলিপোর্ট ব্যবহার করুন e.g. from 12 to 4
  • টেলিপোর্টগুলি কেবল একমুখী (আপনি 12 থেকে 4 পর্যন্ত পেতে পারেন তবে 4 থেকে 12 পর্যন্ত পাওয়া অসম্ভব)

  • প্রতিটি ক্রিয়া এক পদক্ষেপ নেয়

ইনপুট

এসপিডিআইএন বা আপনার প্রোগ্রামিং ভাষার নিকটতম বিকল্প থেকে ইনপুটটি পড়া উচিত। ইনপুট একটি পূর্ণসংখ্যা নিয়ে গঠিত 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 সম্পর্কে কী? যদি এটি সর্বোত্তম সমাধান হয় তবে আপনি কীভাবে সিদ্ধান্ত নিয়েছিলেন যে সর্বদা দ্বি-আপ / দুই-ডাউন পথের বিকল্প আছে যা সংখ্যার আরও বিশ্রী অঞ্চলে পৌঁছায় না?
টেসেল্ল্যাটিংহেকলার 5

1
@ টেসেল্লাটিংহেকলার সম্ভবত আমার আরও সুনির্দিষ্ট হওয়া উচিত ছিল। নেই অন্তত একটি সন্তোষজনক সমাধান, যে একটি সারিতে দুটি (নিচে নামার) অথবা দুটি (উপরে উঠানো) গতি নেই। উদাহরণস্বরূপ 29 -> 30 -> 10 -> 9 -> 3 -> 1
জাকুব

আমি বলি না যে এটি ভুল, কেবলমাত্র আমি "কেন এটি কাজ করে তা সহজেই ভাবতে পারি না"। আমি যুক্তিযুক্ত ছিলাম: 1 কক্ষের দ্রুততম রুটটি তিনটি শক্তিতে শুরু হচ্ছে, প্রতিটি পদক্ষেপে তিনটি দিয়ে ভাগ করুন। সুতরাং তিনটি শক্তির নিকটবর্তী সংখ্যার দ্রুততম রুট পুনরাবৃত্তি করে বা তিনটির পাওয়ার পাওয়ার জন্য সংযোজন হয়, তবে বার বার 3 দ্বারা বিভাজন করুন যদি তারা পরিবর্তে এন / 2 সরিয়ে শুরু করেন তবে তারা তিনটির শক্তি থেকে আরও পেতে পারেন, এবং অতএব দ্রুততম রুটটি পেরিয়ে। আমি দেখতে পাচ্ছি না কীভাবে তারা / সর্বদা / অন্য কোনও রুটকে সমান সংক্ষিপ্তভাবে আবিষ্কার করবে; দেখে মনে হচ্ছে তারা এখন 'খারাপ' পছন্দ সহ একটি অঞ্চলে।
TessellatingHecler 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 বিট কম্পিউটারে সমস্ত সংখ্যার একটি তালিকা মেমরির ~ 800 এমবি।

তালিকা সূচকটি সংখ্যাগুলিকে উপস্থাপন করে, মানগুলি অনুমোদিত উদ্ধার পদক্ষেপগুলিতে 1 থেকে দূরত্বকে উপস্থাপন করে।

  • তালিকা সেট করুন [1] = 0 অর্থ "0 টি ধাপে পৌঁছনীয়"।
  • তালিকার প্রতিটি সংখ্যার জন্য যা 0 টি ধাপে পৌঁছনযোগ্য (যেমন 1)
    • 1 ধাপে সংখ্যা 1 সেট করুন, নম্বর -1, সংখ্যা * 2, সংখ্যা * 3 পৌঁছনীয়
  • তালিকার প্রতিটি সংখ্যার জন্য যা 1 ধাপে পৌঁছানো যায় (অর্থাত 0,2,2,3)
    • 2 ধাপে সংখ্যা 1 সেট করুন, নম্বর -1, সংখ্যা * 2, সংখ্যা * 3 পৌঁছনীয়
  • ... ইত্যাদি প্রতিটি তালিকার সূচী না পাওয়া পর্যন্ত।

রানটাইমটি 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.

অন্যান্য

  • আপনি যদি পাইথনওয়িনে এটি চালনা করেন তবে আপনি পরে অনুবাদককে L তালিকাটি অ্যাক্সেস করতে পারেন।
  • প্রতিটি ঘরে 30 টি চাল বা তারও কম ক্যাপ্টেনের কাছে পথ রয়েছে।
  • কেবলমাত্র একটি কক্ষ 30 চালা দূরে - ঘর 72,559,411 - এবং 244 কক্ষ রয়েছে যা 29 টি সরানো দূরে।
  • এটি সর্বোচ্চ ক্ষেত্রে ক্ষেত্রে ভয়াবহ রানটাইম বৈশিষ্ট্য থাকতে পারে, তবে প্রশ্ন মন্তব্যের মধ্যে একটি হ'ল " @ সমস্ত প্রোগ্রাম যা 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

প্রতি সে মেশিন ল্যাঙ্গুয়েজে স্ট্যান্ডার্ড ইনপুটটির কোনও ধারণা নেই। যেহেতু চ্যালেঞ্জটি বিশুদ্ধ গণনামূলক, তাই আমি ইনপুট প্যারামিটার গ্রহণ করে EAXফলাফলটি ফিরিয়ে নিয়ে একটি ফাংশন লিখতে পছন্দ করেছি AL

কোডটির পিছনে গণিতটি সুন্দরভাবে @ জাকুব দ্বারা ব্যাখ্যা করা হয়েছে: অনুসন্ধানটি কেবলমাত্র টেলিফোনগুলিকে এক-স্তরীয় পদক্ষেপের চেয়ে বেশি ছেদ করা পথগুলির মধ্যেই পরিচালিত হয়। পারফরম্যান্সটি ইনপুট রেঞ্জের নিম্ন প্রান্তে প্রতি সেকেন্ডে প্রায় 12000 পরীক্ষার কেস এবং উপরের প্রান্তে 50 সেকেন্ডে প্রতি সেকেন্ড হয়। মেমরির ব্যবহারটি পুনরাবৃত্তি স্তরের স্ট্যাক স্পেসের 12 বাইট is

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           
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.