কিছু আপেল বাছাই করুন!


11

সমস্যা

একনাগাড়ে সারিবদ্ধভাবে রাখা 7 টি বালতি কল্পনা করুন। প্রতিটি বালতিতে কমপক্ষে 2 টি আপেল থাকতে পারে। 1 টি থেকে 13 লেবেলযুক্ত 13 টি আপেল রয়েছে They সেগুলি 7 টি বালতির মধ্যে বিতরণ করা হয়। উদাহরণ স্বরূপ,

{5,4}, {8,10}, {2,9}, {13,3}, {11,7}, {6,0}, {12,1}

যেখানে 0 খালি স্থান প্রতিনিধিত্ব করে। প্রতিটি বালতির মধ্যে আপেলগুলি যে ক্রমে প্রদর্শিত হয় তা প্রাসঙ্গিক নয় (যেমন {5,4। 4,5} এর সমতুল্য)।

আপনি যে কোনও আপেলকে একটি বালতি থেকে সংলগ্ন বালতিতে স্থানান্তর করতে পারেন, তবে অন্য অ্যাপলের জন্য গন্তব্য বালতিতে জায়গা থাকার ব্যবস্থা রয়েছে। প্রতিটি সরানো আপনি যে আপেলটি স্থানান্তর করতে চান তার সংখ্যা দ্বারা বর্ণিত হয় (যা দ্ব্যর্থহীন কারণ এখানে কেবল একটি খালি জায়গা রয়েছে)। উদাহরণস্বরূপ, সরানো প্রয়োগ

7

উপরের বিন্যাসে ফলাফল হবে

{5,4}, {8,10}, {2,9}, {13,3}, {11,0}, {6,7}, {12,1}

উদ্দেশ্য

এমন একটি প্রোগ্রাম লিখুন যা এসটিডিএন থেকে কোনও ব্যবস্থা পড়ে এবং এটি নীচের বিন্যাসে সাজিয়ে তোলে

{1,2}, {3,4}, {5,6}, {7,8}, {9,10}, {11,12}, {13,0}

যতটা সম্ভব চালগুলি ব্যবহার করা। আবার, যে ক্রমে আপেল প্রদর্শিত মধ্যে প্রতিটি বালতি প্রাসঙ্গিক নয়। বালতিগুলির ক্রমটি বিবেচনা করে। কমা দ্বারা বিভক্ত প্রতিটি বিন্যাস সাজানোর জন্য ব্যবহৃত চালগুলি আউটপুট করা উচিত। উদাহরণ স্বরূপ,

13, 7, 6, ...

আপনার স্কোর নিম্নলিখিত ব্যবস্থা সমাধানের জন্য প্রয়োজনীয় পদক্ষেপের সংখ্যার সমান:

{8, 2}, {11, 13}, {3, 12}, {6, 10}, {4, 0}, {1, 7}, {9, 5}
{3, 1}, {6, 9}, {7, 8}, {2, 11}, {10, 5}, {13, 4}, {12, 0}
{0, 2}, {4, 13}, {1, 10}, {11, 6}, {7, 12}, {8, 5}, {9, 3}
{6, 9}, {2, 10}, {7, 4}, {1, 8}, {12, 0}, {5, 11}, {3, 13}
{4, 5}, {10, 3}, {6, 9}, {8, 13}, {0, 2}, {1, 7}, {12, 11}
{4, 2}, {10, 5}, {0, 7}, {9, 8}, {3, 13}, {1, 11}, {6, 12}
{9, 3}, {5, 4}, {0, 6}, {1, 7}, {12, 11}, {10, 2}, {8, 13}
{3, 4}, {10, 9}, {8, 12}, {2, 6}, {5, 1}, {11, 13}, {7, 0}
{10, 0}, {12, 2}, {3, 5}, {9, 11}, {1, 13}, {4, 8}, {7, 6}
{6, 1}, {3, 5}, {11, 12}, {2, 10}, {7, 4}, {13, 8}, {0, 9}

হ্যাঁ, এই ব্যবস্থাগুলির প্রত্যেকটির একটি সমাধান রয়েছে।

বিধি

  • আপনার দ্রবণটি চলন প্রতি বালতির সংখ্যায় বহুপক্ষীয় সময়ে চলতে হবে। পয়েন্টটি হ'ল চতুর হিউরিস্টিক্স ব্যবহার করা।
  • সমস্ত অ্যালগরিদম অবশ্যই নির্দোষ হতে হবে ic
  • টাই হওয়ার ক্ষেত্রে সংক্ষিপ্ততম বাইট গণনাটি জয়ী হয়।

2
আপনি যখন একটি আপেল স্থানান্তর করতে পারেন যখন কেবলমাত্র একটি স্থান থাকে তখন গন্তব্যটি চিহ্নিত করার কী দরকার?
জন ডিভোরাক

আমার ব্রুট-ফোর্স সমাধানটি যদি যুক্তিযুক্ত সময়ে চালিত হয় তবে কী হবে? কেবলমাত্র 700 মি রাজ্য রয়েছে - কয়েক মিনিটের ক্ষেত্রে সহজেই গণনা করা যায়। "যুক্তিসঙ্গত পরিমাণ" সংজ্ঞা দিন।
জন ডিভোরাক

@ জানডভোরাক "কী পয়েন্ট" - ভাল কল করার জন্য। এটি আমার কাছে ঘটেনি। সমাধানটি জোর করার জন্য প্রয়োজনীয় সময়ের চেয়ে কম হিসাবে আমি এখানে যুক্তিসঙ্গত সংজ্ঞা দিচ্ছি ;)
অরবি

আপনার "যুক্তিসঙ্গত" সংজ্ঞাটির অর্থ কি আমাদের প্রথমে নিষ্ঠা-শক্তি সমাধানটি প্রয়োগ করা উচিত, তারপরে আরও দ্রুত যা গণনা করা হয়?
জন ডিভোরাক

বালতির চূড়ান্ত ক্রম কি গুরুত্বপূর্ণ?
এএমকে

উত্তর:


4

স্কোর: 448

আমার ধারণাটি 1 টি দিয়ে শুরু করে ধারাবাহিকভাবে তাদের সাজানোর জন্য এটি আমাদের সুন্দর সম্পত্তিটি দেয় যে যখন আমরা স্থানটি আগের / পরের ঝুড়িতে সরিয়ে নিতে চাই, আমরা সেখানে দুটি আপেলের মধ্যে ঠিক কোনটি স্থানান্তরিত করতে পারি তা জানতে পারি - সর্বোচ্চ / যথাক্রমে এক মিনিট। এখানে পরীক্ষার বিরতি:

#1: 62     #6: 40
#2: 32     #7: 38
#3: 46     #8: 50
#4: 50     #9: 54
#5: 40    #10: 36

Total score: 448 moves

কোডটি আরও অনেক গল্ফ করা যেতে পারে তবে কোডের আরও ভাল মানের অতিরিক্ত উত্তরগুলি অনুপ্রাণিত করবে।

সি ++ (৫০১ বাইট)

#include <cstdio>
#define S(a,b) a=a^b,b=a^b,a=a^b;
int n=14,a[14],i,j,c,g,p,q;
int l(int x){for(j=0;j<n;++j)if(a[j]==x)return j;}
int sw(int d){
    p=l(0);q=p+d;
    if(a[q]*d>a[q^1]*d)q^=1;
    printf("%d,", a[q]);
    S(a[q],a[p])
}
int main(){
    for(;j<n;scanf("%d", a+j),j++);
    for(;++i<n;){
        c=l(i)/2;g=(i-1)/2;
        if(c-g){
            while(l(0)/2+1<c)sw(2);
            while(l(0)/2>=c)sw(-2);
            while(l(i)/2>g){sw(2);if(l(i)/2>g){sw(-2);sw(-2);}}
        }
    }
}

আরও উন্নতিগুলি সি তে স্যুইচ করা হতে পারে এবং বৃহত্তর মানগুলি নীচের দিকে (এবং সেগুলি শেষ পর্যন্ত উভয় সমাধানের সংমিশ্রণ করে) শুরু করে স্কোর হ্রাস করার চেষ্টা করতে পারে।


1
আপনার কোডের একটি স্ট্রিং ইতিমধ্যে একটি সি প্রোগ্রাম গঠন করে। বিশেষত, এটি প্রথম লাইনটি কেবল মোছার মাধ্যমে সিটিতে কাজ করতে পারে।
feersum

@ ফেয়ারসাম আপনি ঠিক বলেছেন শুরুতে, আমার কাছে আরও সি ​​++ নির্দিষ্ট কোড ছিল, তবে এর পরে সিটিতে স্যুইচ করার সাথে মনে হয় আমি এ থেকে মুক্তি পেয়েছি।
ইয়াসেন

যারা এটি যাচাই করার চেষ্টা করছেন তাদের আরও পরিষ্কার করে দেওয়ার জন্য আপনি কী আপনার সমাধানটিতে ইনপুট ফর্ম্যাটটি পরিবর্তন করেছেন তা উল্লেখ করতে পারেন?
অরবি

2

সি, 426 448

ইয়াসেনের পদ্ধতির অনুরূপ 1 থেকে 13 পর্যন্ত এটি একবারে এক ধরণের আপেল সাজায় , যখনই যখন এটির একটি বড় সংখ্যার উপরে বা একটি ছোট সংখ্যাকে নীচে নামানোর সুযোগ থাকে তবে তা তা গ্রহণ করবে। দুঃখের বিষয়, এটি কেবল প্রথম পরীক্ষার সমস্যার ক্ষেত্রে পারফরম্যান্সের উন্নতি করে তবে এটি একটি সামান্য উন্নতি। পরীক্ষার সমস্যাগুলি চালানোর সময় আমি একটি ভুল করেছি। দেখে মনে হচ্ছে আমি ইয়াসেনের পদ্ধতিটি কেবল পুনরায় প্রয়োগ করেছি।

#1: 62    #6: 40
#2: 32    #7: 38
#3: 46    #8: 50
#4: 50    #9: 54
#5: 40    #10: 36

এটি ধনুর্বন্ধনী বা কমা ব্যতীত ইনপুট লাগে eg

8 2 11 13 3 12 6 10 4 0 1 7 9 5

এখানে গল্ফ কোডটি কয়েকটা অপ্রয়োজনীয় নিউলাইনগুলি গণনা করছে 423 বাইটে (সম্ভবত আরও গল্ফ করা যেতে পারে, তবে আমি আশা করি এই স্কোরটি পরাজিত হবে):

#define N 7
#define F(x,y) for(y=0;y<N*2;y++)if(A[y]==x)break;
#define S(x,y) x=x^y,y=x^y,x=x^y;
#define C(x,y) ((A[x*2]==y)||(A[x*2+1]==y))
A[N*2],i,j,d,t,b,a,n,s,v,u,w,g;main(){for(;i<N*2;i++)scanf("%d",A+i);g=1;while
(!v){F(0,i);b=i/2;F(g,u);w=u/2;d=b<w?1:-1;n=(b+d)*2;a=(b+d)*2+1;if(A[n]>A[a])
S(n,a);t=d-1?a:n;printf("%d,",A[t]);S(A[i],A[t]);while(C((g-1)/2,g))g++;v=1;for
(j=0;j<N*2;j++)if(!C(j/2,(j+1)%(N*2)))v=0;}}

এবং অরোগল্ফড কোড যা স্কোরটিও মুদ্রণ করে:

#include <stdio.h>
#include <stdlib.h>

#define N 7

int apples[N*2];

int find(int apple)
{
    int i;
    for (i = 0; i < N*2; i++) {
        if (apples[i] == apple)
            return i;
    }    
}

void swap(int i, int j)
{
    int temp;
    temp = apples[i];
    apples[i] = apples[j];
    apples[j] = temp;
}

int contains(int bucket, int apple)
{
    if ((apples[bucket * 2] == apple) || (apples[bucket * 2 + 1] == apple))
        return 1;
    return 0;
}

int is_solved()
{
    int i, j;
    for (i = 0; i < N * 2; i++) {
        j = (i + 1) % (N * 2);
        if (!contains(i / 2, j))
            return 0;
    }
    return 1;
}

int main()
{
    int i, j, dir, bucket, max, min, score;
    int target_i, target_bucket, target;

    /* Read the arrangement */
    for (i = 0; i < N*2; i++) {
        scanf("%d ", apples + i);
    }

    target = 1;
    while (1) {

        i = find(0);
        bucket = i / 2;
        target_i = find(target);
        target_bucket = target_i / 2;

        /* Change the direction of the sort if neccesary */
        if (bucket < target_bucket) dir = 1;
        else dir = -1;

        /* Find the biggest and smallest apple in the next bucket */
        if (apples[(bucket + dir) * 2] < apples[(bucket + dir) * 2 + 1]) {
            min = (bucket + dir) * 2;
            max = (bucket + dir) * 2 + 1;
        } else {
            min = (bucket + dir) * 2 + 1;
            max = (bucket + dir) * 2;
        }

        /* If we're going right, move the smallest apple. Otherwise move the
           biggest apple */
        if (dir == 1) {
            printf("%d, ", apples[min]);
            swap(i, min);
            score++;
        } else {
            printf("%d, ", apples[max]);
            swap(i, max);
            score++;
        }

        /* Find the next apple to sort */
        while (contains((target - 1) / 2, target))
            target++;

        /* If we've solved it then quit */
        if (is_solved())
            break;
    }
    printf("\n");
    printf("%d\n", score);
}

2

পাইথন 3 - 121

এটি সমাধান না পাওয়া পর্যন্ত এটি গভীরতার সাথে গভীরতার সাথে প্রথম অনুসন্ধানের প্রয়োগ করে। এটি পরিদর্শন করা রাজ্যগুলিকে সঞ্চয় করতে একটি অভিধান ব্যবহার করে যাতে উচ্চতর গভীরতার উইন্ডো না থাকলে এগুলি আবার দেখা না করে। কোন রাজ্যে যাচাই করা উচিত তা সিদ্ধান্ত নেওয়ার সময়, এটি গুরূত্বপূর্ণ উপাদানগুলির সংখ্যাকে হুরিস্টিক হিসাবে ব্যবহার করে এবং কেবলমাত্র সেরা সম্ভাব্য রাজ্যগুলিতে যায়। মনে রাখবেন যেহেতু তাদের বালতির মধ্যে থাকা উপাদানগুলির ক্রম কোনও গুরুত্ব দেয় না, তাই এটি সর্বদা বালতিগুলির মধ্যে ক্রম বজায় রাখে। এটি কোনও উপাদান ভুল জায়গায় প্রতিস্থাপিত হয়েছে কিনা তা পরীক্ষা করা সহজ করে তোলে।

ইনপুটটি ইনটসের একটি অ্যারে, প্রথম ইনটি বালতির সংখ্যার সাথে।

সুতরাং উদাহরণস্বরূপ, # 8 এর জন্য (এটি আমার মেশিনে চালাতে খুব দীর্ঘ সময় নেয়, অন্যরা কয়েক সেকেন্ডে শেষ করে):

c:\python33\python.exe apples.py 7 3 4 10 9 8 12 2 6 5 1 11 13 7 0

পরীক্ষার সেটে ফলাফলগুলি এখানে: # 1: 12, # 2: 12, # 3: 12, # 4: 12, # 5: 11, # 6: 11, # 7: 10, # 8: 14, # 9: 13, # 10: 14

কোডটি এখানে:

import sys    

BUCKETS = int(sys.argv[1])    

# cleans a state up so it is in order
def compressState(someState):
  for i in range(BUCKETS):
    if(someState[2*i] > someState[2*i + 1]):
      temp = someState[2*i]
      someState[2*i] = someState[2*i + 1]
      someState[2*i + 1] = temp
  return someState    

state = compressState([int(x) for x in sys.argv[2:]])
print('Starting to solve', state)
WINNINGSTATE = [x for x in range(1, BUCKETS*2 - 1)]
WINNINGSTATE.append(0)
WINNINGSTATE.append(BUCKETS*2 - 1)
maxDepth = 1
winningMoves = []
triedStates = {}    

# does a depth-first search
def doSearch(curState, depthLimit):
  if(curState == WINNINGSTATE):
    return True
  if(depthLimit == 0):
    return False
  myMoves = getMoves(curState)
  statesToVisit = []
  for move in myMoves:
    newState = applyMove(curState, move)
    tns = tuple(newState)
    # do not visit a state again unless it is at a higher depth (more chances to win from it)
    if(not ((tns in triedStates) and (triedStates[tns] >= depthLimit))):
      triedStates[tns] = depthLimit
      statesToVisit.append((move, newState[:], stateScore(newState)))
  statesToVisit.sort(key=lambda stateAndScore: stateAndScore[2])
  for stv in statesToVisit:
    if(stv[2] > statesToVisit[0][2]):
      continue
    if(doSearch(stv[1], depthLimit - 1)):
      winningMoves.insert(0, stv[0])
      return True
  return False    

# gets the moves you can make from a given state
def getMoves(someState):
  # the only not-allowed moves involve the bucket with the 0
  allowedMoves = []
  for i in range(BUCKETS):
    if((someState[2*i] != 0) and (someState[2*i + 1] != 0)):
      allowedMoves.append(someState[2*i])
      allowedMoves.append(someState[2*i + 1])
  return allowedMoves    

# applies a move to a given state, returns a fresh copy of the new state
def applyMove(someState, aMove):
  newState = someState[:]
  for i in range(BUCKETS*2):
    if(newState[i] == 0):
      zIndex = i
    if(newState[i] == aMove):
      mIndex = i
  if(mIndex % 2 == 0):
    newState[mIndex] = 0
  else:
    newState[mIndex] = newState[mIndex-1]
    newState[mIndex-1] = 0
  newState[zIndex] = aMove
  if((zIndex % 2 == 0) and (newState[zIndex] > newState[zIndex+1])):
    newState[zIndex] = newState[zIndex+1]
    newState[zIndex+1] = aMove
  return newState    

# a heuristic for how far this state is from being sorted
def stateScore(someState):
  return sum([1 if someState[i] != WINNINGSTATE[i] else 0 for i in range(BUCKETS*2)])    

# go!
while(True):
  triedStates[tuple(state)] = maxDepth
  print('Trying depth', maxDepth)
  if(doSearch(state, maxDepth)):
    print('winning moves are: ', winningMoves)
    break
  maxDepth += 1

আমি এটিকে উত্সাহিত করেছি কারণ এটি সর্বোত্তম সমাধানগুলি দেখতে দরকারী, তবে লক্ষ্য করুন যে এটি বহুল আলোচিত সময়ে চলবে না এমন প্রশ্নে প্রয়োজনীয় বালতিগুলির সংখ্যা অনুসারে চলে। আমি বিশ্বাস করি না যে কোনও অ্যালগরিদম যা সর্বোত্তম সমাধান (সাধারণভাবে) উত্পাদন করে তা বহুপদী সময়ে চলতে পারে।
অরবি

প্রথম পরীক্ষার সমস্যার জন্য, আপনার প্রোগ্রামটি 10, 8, 1, 12, 6, 7, 11, 3, 5, 13, 4, 9 উত্পন্ন করে, যা কোনও বৈধ সমাধান নয়। আমি মনে করি আপনি প্রশ্নটি ভুল বুঝে থাকতে পারেন। প্রশ্নটি লক্ষ্য করুন যে "আপনি যে কোনও আপেলকে একটি বালতি থেকে একটি সংলগ্ন বালতিতে নিয়ে যেতে পারেন" অর্থাৎ বালতিটি তার ডান বা বাম দিকে (একটি স্বেচ্ছাসেবী বালতি নয়)।
অরবি

ওহ, আমি পুরোপুরি পাশের সীমাবদ্ধতাটি মিস করেছি! আমি এটি পোস্ট করার পরে আমার একটি সন্দেহজনক সন্দেহ হয়েছিল যে চলমান সময়ের সীমাবদ্ধতাও লঙ্ঘিত হয়েছে। আমি এটি লিখতে গিয়ে 100% নিশ্চিত ছিলাম না, কারণ বারবারের রাজ্যগুলি এড়িয়ে যাওয়ার গতিশীল প্রোগ্রামিং উপাদান আমাকে বিভ্রান্ত করেছিল। উত্সাহের জন্য ধন্যবাদ যদিও এটি দুটি গুণতে ব্যর্থ হয়; এটি একটি মজাদার ধাঁধা এবং আমি আরও ভাল, বৈধ উত্তর নিয়ে আসতে পারি কিনা তা আমি দেখতে পাচ্ছি।
আরটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.