यात्रा कद्दू की समस्या


23

पृष्ठभूमि:

जैक एक कद्दू है जो हर हेलोवीन में अपने कद्दू पैच के पास गांवों के नागरिकों को लुभाने का आनंद लेता है। हालाँकि, हर साल जब कोई अपने अंदर मोमबत्ती जलाता है, तो उसके पास सीमित समय होता है कि वह मोमबत्ती जलाए जाने से पहले सभी को हिला दे, इस प्रकार किसी भी अन्य ग्रामीणों को हिला नहीं सकता क्योंकि कोई भी उसे देख नहीं सकता है। पिछले वर्षों में, वह केवल अपने खराब निर्णय लेने के कारण गाँवों की एक छोटी सी राशि को पाटने में सफल रहा है, लेकिन अब जब आपके पास उसकी मदद करने के लिए है, तो वह अधिक से अधिक गाँवों में जा सकेगा!

कार्य:

गाँव के स्थानों की सूची और एक मोमबत्ती की उम्र को देखते हुए, अधिकतम संख्या में गाँव जैक जा सकते हैं। आपको स्वयं पथ मुद्रित करने की आवश्यकता नहीं है।

इनपुट:

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

आउटपुट:

मोमबत्ती के बाहर जलने से पहले जैक की अधिकतम संख्या के बराबर एक पूर्णांक जा सकता है।

नियम:

यह , इसलिए बाइट्स जीत में सबसे छोटा कोड है। मानक खामियों की अनुमति नहीं है।

परीक्षण के मामलों:

// Format [lifespan] [list of village coordinates] -> [maximum visit-able villages]

4 -1,0 1,0 2,0 3,0 4,0 5,0 -> 3
4 1,1 2,2 3,3 -> 2
5 1,1 2,1 3,1 4,1 5,0 5,1 -> 4

9
शीर्षक पर डरते हुए हँसना
लुइस Mendo

3
"जैक के आंदोलनों को सरल बनाने के लिए" थोड़े विडंबना है, यह अब और अधिक कठिन है: डी
पुरकाकूदरी

1
मुझे लगता है कि अगर मैं गलत नहीं हूं तो आपका पहला केस आउटपुट 3 होना चाहिए
नंबर

1
@ नम्बरनॉट नहीं, एक बार एक गांव डर गया था कि वे एक ही चाल के लिए नहीं गिरेंगे, वह केवल एक बार प्रत्येक गांव को डरा सकता है।
योडल

5
यह एक एन-कद्दू हार्ड समस्या है, इसलिए सामान्य तौर पर गांवों की अधिकतम संख्या को ढूंढना मुश्किल हो सकता है। गांवों की अधिकतम संख्या है?
edc65

जवाबों:


9

जेली, 30 29 27 25 बाइट्स

_AṢæ..
0,0ṭṚç2\+\<S
Œ!ç€Ṁ

इसे ऑनलाइन आज़माएं!

जाहिरा तौर पर जेली का डॉट उत्पाद सिर्फ एक सूची आकार के बेमेल को अनदेखा करता है और अन्य सरणी के अतिरिक्त तत्वों को गुणा नहीं करता है, बस उन्हें जोड़ता है। 2 बाइट्स को बंद करता है।

व्याख्या

_AṢæ..              Helper link to calculate distance. Arguments: a, b
_                     subtract the vertices from each other
 A                    take absolute values of axes
  Ṣ                   sort the axes
   æ..                dot product with [0.5]

0,0ṭṚç2\+\<S        Helper link to calculate max cities. Arguments: perm, max
0,0                   create pair [0,0]
   ṭ                  append that to the permutation
    Ṛ                 reverse the permutation (gets the [0,0] to the beginning)
     ç2\              find distances of each pair using the previous link
        +\            find all partial sums
          <           see if each sum was less than the max
           S          sum to count cases where it was

Œ!ç€Ṁ               Main link. Arguments: cities, max
Œ!                    get permutations of cities
  ç€                  find max cities for each permutation using the previous link
    Ṁ                 take the maximum

एक टिप्पणी में, ओपी 1000 गांवों तक का प्रबंधन करने का अनुरोध करता है। लेकिन कोई भी उत्तर जो सभी
परमिटों को

@ edc65 कहीं भी यह नहीं कहता है कि ऐसे मामलों को जिन्हें परीक्षण योग्य बनाने की आवश्यकता है, जब तक कि एल्गोरिथ्म सैद्धांतिक रूप से पर्याप्त समय और स्मृति दिए गए कार्य करता है। (प्रोग्राम जो वास्तव में n so 1000 के लिए TSP को हल कर सकते हैं, वे इतने जटिल हैं कि वे अब गोल्फ के लिए मज़ेदार नहीं होंगे।)
PurkkaKoodari

ठीक है 1000 नहीं, लेकिन 15 भी नहीं?
edc65

@ edc65 मुझे एक एल्गोरिथ्म नहीं मिल रहा है जो तेज़ हो और जेली में आसानी से लागू हो सके। मैं दूसरी भाषा में अधिक कुशल समाधान (जैसे हेल्ड-कार्प) बनाने पर गौर कर सकता हूं। BTW, कोई भी उत्तर वास्तव में तेजी से एल्गोरिदम का उपयोग नहीं करता है; जेएस एक बेहतर है, लेकिन धीमी गति से अगर वहाँ कई शहरों में हैं।
पुरकाकूदरी

5

जावा 7, 206 201 बाइट्स

5 बाइट बचाने के लिए @KevinCruijssen को धन्यवाद

int f(float e,int[]a,int[]b){int x=0,y=0,c=0,d=0,t;float s;for(int i:a){s=(i!=x&b[c]==y)|(i==x&b[c]!=y)?Math.sqrt((t=i-x)*t+(t=b[c]-y)*t)*1:Math.abs(i-x)*1.5;d+=e-s>=0?1:0;e-=s;x=i;y=b[c++];}return d;}

Ungolfed

class Travellingpumpkin {

public static void main(String[] args) {

    System.out.println(f( 5 ,new int[] { 1,2,3,4,5,5 } , new int[] { 1,1,1,1,0,1 } ));

}
static int f( double e , int[]a , int[]b ) {
    int x = 0 , y = 0 , c = 0 , d = 0 , t;
    double s ;

    for ( int i : a ) {
    s = ( i != x & b[c] == y )|( i == x & b[c] != y )
         ? Math.sqrt( ( t = i - x ) * t + ( t = b[c] - y ) * t ) * 1
         : Math.abs( i - x ) * 1.5 ;


        d += e-s >= 0 ? 1 : 0 ;
        e -= s ;
        x = i ; y = b [ c++ ] ;
    }
    return d ;

}

   }

2
अच्छा है, "ungolfed" फॉर्म सहित। यद्यपि यदि आपने कहा कि मुझे लगता है कि कोड समीक्षक इसे अपढ़ नहीं कहेंगे। ;)
वाइल्डकार्ड

+1। गोल्फ के लिए एक चीज: आप i-xदो बार और b[c]-yदो बार उपयोग करते हैं , इसलिए आप ,tचीटियों को जोड़ सकते हैं , और फिर इसका उपयोग कर सकते हैं : Math.sqrt((t=i-x)*t+(t=b[c]-y)*t)*1इसके बजाय Math.sqrt((i-x)*(i-x)+(b[c]-y)*(b[c]-y))*1
केविन क्रूज़सेन

यह संभवतः सामान्य मामले में कैसे काम कर सकता है?
edc65

3

स्काला, 196 बाइट्स

def f(l:Int,c:(Int,Int)*)=c.permutations.map(x=>((0,0)+:x sliding 2 map{p=>val Seq(c,d)=Seq((p(0)._1-p(1)._1)abs,(p(0)._2-p(1)._2)abs).sorted
c*1.5+(d-c)}scanLeft 0d)(_+_)takeWhile(_<l)size).max-1

Ungolfed:

def g (l: Int, c: (Int, Int)*) = {
    c.permutations
    .map { x =>
        ((0, 0) +: x).sliding(2).map({ p =>
            val Seq(c, d) = Seq((p(0)._1 - p(1)._1) abs, (p(0)._2 - p(1)._2) abs).sorted
            c * 1.5 + (d - c)
        }).scanLeft(0d)(_ + _).takeWhile(_ < l).size
    }.max - 1
}

Explanantion:

def f(l:Int,c:(Int,Int)*)= //defien a function with an int and a vararg-int-pait parameter
  c.permutations           //get the permutations of c, that is all possible routes
  .map(x=>                 //map each of them to...
    ((0,0)+:x                //prepend (0,0)
    sliding 2                //convert to a sequence of consecutive elemtens
    map{p=>                  //and map each of them to their distance:
      val Seq(c,d)=Seq(        //create a sequence of
        (p(0)._1-p(1)._1)abs,  //of the absolute distance between the x points
        (p(0)._2-p(1)._2)abs   //and he absolute distance between the y coordinates
      ).sorted                 //sort them and assign the smaller one to c and the larger one to d
      c*1.5+(d-c)              //we do the minimum difference diagonally
    }                        //we now have a sequence of sequence of the distances for each route
    scanLeft 0d)(_+_)       //calculate the cumulative sum
    takeWhile(_<l)          //and drop all elements that are larger than the candle lifespan
    size                    //take the size
  ).max-1                   //take the maximum, taht is the size of the largest route and subtract 1 because we added (0,0) at the beginning

3

जावास्क्रिप्ट (ईएस 6), 145

अनाम पुनरावर्ती कार्य, पैरामीटर sमोमबत्ती की उम्र है, पैरामीटर lगांव समन्वय सूची है।

एक गहराई पहले खोज , जब दूरी मोमबत्ती की उम्र तक पहुँचती है

f=(s,l,x=0,y=0,v=0,A=Math.abs,X=Math.max)=>X(v,...l.map(([t,u],i,[h,...l],q=A(t-x),p=A(u-y),d=(l[i-1]=h,p+q+X(p,q))/2)=>s<=d?v:f(s-d,l,t,u,1+v)))

कम गोल्फ वाले स्निपेट को नीचे देखते हैं

परीक्षा

f=(s,l,x=0,y=0,v=0,A=Math.abs,X=Math.max)=>
  X(v,...l.map(
      ([t,u],i,[h,...l],q=A(t-x),p=A(u-y),d=(l[i-1]=h,p+q+X(p,q))/2)=>
      s<=d?v:f(s-d,l,t,u,1+v)
  ))

// ungolfed version

F=(s, l, 
   x=0, y=0, // current position
   v=0 // current number of visited sites 
  ) =>
   Math.max(v, ...l.map(
     (
       [t,u], i, [h,...l], // lambda arguments
       q = Math.abs(t-x), p = Math.abs(u-y), // locals
       d = (p+q+Math.max(p,q))/2
     ) => (
       l[i-1] = h,
       s <= d 
         ? v 
         : F(s-d, l, t, u, v+1)
     ) 
  ))

;[[4,[[-1,0],[1,0],[2,0],[3,0],[4,0],[5,0]], 3]
,[4, [[1,1],[2,2],[3,3]], 2]
,[5, [[1,1],[2,1],[3,1],[4,1],[5,0],[5,1]], 4]
].forEach(test=>{
  var span=test[0],list=test[1],check=test[2],
      result = f(span, list)
  console.log(result==check?'OK':'KO',span, list+'', result)
})


3

MATL , 27 बाइट्स

EH:"iY@OwYc!d|]yyXl++Ys>sX>

EDIT (26 nov 2016): Xlफ़ंक्शन में परिवर्तन के कारण , इसे उपरोक्त कोड द्वारा प्रतिस्थापित किया जाना है 2$X>। नीचे दिए गए लिंक उस संशोधन को शामिल करते हैं।

इसे ऑनलाइन आज़माएं! या सभी परीक्षण मामलों को सत्यापित करें

व्याख्या

कद्दू दूरी दोनों शहरों के बीच अलग Δ x और Δ y प्रत्येक समन्वय के रूप में प्राप्त किया जा सकता में (| Δ x | + | Δ y | + अधिकतम (| Δ x |, | Δ y |)) / 2।

कोड इन चरणों का अनुसरण करता है:

  1. X निर्देशांक और y निर्देशांक के सभी क्रमपरिवर्तन उत्पन्न करें , और प्रत्येक के लिए एक prepend 0. प्रत्येक क्रमपरिवर्तन संभव पथ का प्रतिनिधित्व करता है।
  2. प्रत्येक पथ के लिए पूर्ण निरंतर अंतर की गणना करें (ये हैं | absolute x | और | above y | ऊपर)।
  3. प्रत्येक पथ के प्रत्येक चरण के लिए कद्दू की दूरी प्राप्त करें।
  4. प्रत्येक पथ के लिए दूरी की संचयी राशि की गणना करें।
  5. प्रत्येक पथ के लिए, संचित दूरी से पहले कदमों की संख्या चंद जीवनकाल तक पहुँचती है।
  6. उपरोक्त का अधिकतम लाभ उठाएं।

टिप्पणी कोड:

E        % Input candle lifespan implicitly. Multiply by 2
H:"      % Do thie twice
  i      %   Input array of x or y coordinates
  Y@     %   All permutations. Gives a matrix, with each permutation in a row
  OwYc   %   Prepend a 0 to each row
  !      %   Transpose
  d|     %   Consecutive differences along each column. Absolute value
]        % End
yy       % Duplicate the two matrices (x and y coordinates of all paths)
Xl       % Take maximum between the two, element-wise
++       % Add twice. This gives twice the pumpkin distance
Ys       % Cumulative sum along each column
>        % True for cumulative sums that exceed twice the candle lifespan
s        % Sum of true values for each column
X>       % Maximum of the resulting row array. Inmplicitly display

MATL वास्तव में 1000 (x, y) जोड़े के सभी क्रमचय उत्पन्न कर सकता है?
edc65

@ edc65 नहीं, यह बहुत अधिक है (1000 तत्वों के 10 ^ 2500 से अधिक क्रमांकन हैं)। मुझे नहीं लगता कि कोई भी भाषा
लुइस मेंडो

एक टिप्पणी में, ओपी 1000 गांवों तक का प्रबंधन करने का अनुरोध करता है। लेकिन कोई भी उत्तर जो सभी
परमिटों को

@ edc65 आह, मैं देख रहा हूं। 1000 गांव अवास्तविक लगते हैं अगर समस्या एनपी-हार्ड है, जैसा कि यह प्रतीत होता है
लुइस मेंडो

2

पायथन 2.7 , 422 बाइट्स

अतिरिक्त सुधारों को इंगित करने के लिए NoOneIsHere का धन्यवाद!

edc65 को सूची को बचाने के लिए नहीं बल्कि इसके बजाय पुनरावृत्तियों का उपयोग करने के लिए धन्यवाद!

इसे ऑनलाइन आज़माएं!

from itertools import permutations
def d(s,e):
    d=0
    while s!=e:
        x=1 if s[0]<e[0] else -1 if s[0]>e[0] else 0
        y=1 if s[1]<e[1] else -1 if s[1]>e[1] else 0
        s=(s[0]+x,s[1]+y)
        d+=(1,1.5)[x and y]
return d
l,m=4,0
for o in permutations([(1,1),(2,2),(3,3)]):
    a,c=l-d((0,0),o[0]),1
    for j in range(len(o)-1):
        a-=d(o[j],o[j+1])
        c+=(0,1)[a>0]
    m=max(c,m)
print m

स्पष्टीकरण:

फ़ंक्शन दिए गए नियमों के अनुसार दो बिंदुओं के बीच की दूरी की गणना करता है, लूप इनपुट के जनरेटर द्वारा उत्पन्न सभी क्रमपरिवर्तन के माध्यम से पुनरावृत्ति करता है और दूरी की गणना करता है, यदि दूरी मोमबत्ती की उम्र से कम है तो इसे घटाता है और जगह में जोड़ता है काउंटर, यदि वह काउंटर वर्तमान अधिकतम से अधिक है तो वह इसे प्रतिस्थापित करता है।

ungolfed:

from itertools import permutations

def distance(start_pos, end_pos):
    distance = 0
    while start_pos != end_pos:
        mod_x = 1 if start_pos[0] < end_pos[0] else -1 if start_pos[0] > end_pos[0] else 0
        mod_y = 1 if start_pos[1] < end_pos[1] else -1 if start_pos[1] > end_pos[1] else 0
        start_pos = (start_pos[0] + mod_x, start_pos[1] + mod_y)
        distance += (1, 1.5)[mod_x and mod_y]
    return distance

lifespan, max_amount = 4, 0
for item in permutations([(1,1), (2,2), (3,3)]):
    lifespan_local, current = lifespan - distance((0,0), item[0]), 1
    for j in range(len(item) - 1):
        lifespan_local -= distance(item[j], item[j + 1])
        current += (0, 1)[lifespan_local > 0]
    max_amount = max(current, max_amount)
print max_amount

नमस्कार, और PPCG में आपका स्वागत है! आप बना सकते हैं current c, और ll m
NoOneIsHere

वाह धन्यवाद! उस एक को याद किया
Gmodjackass

एक टिप्पणी में, ओपी 1000 गांवों तक का प्रबंधन करने का अनुरोध करता है। लेकिन कोई भी उत्तर जो सभी
परमिटों को

कुछ बिंदु पर उस पर ध्यान देंगे, सिर के लिए धन्यवाद। मैंने वास्तव में टिप्पणियों को नहीं पढ़ा क्योंकि उनमें से कई हैं।
गमोडजैकस

किया, जनरेटर का उपयोग करते हुए, अब उन सभी क्रमपरिवर्तनों को संग्रहीत करने के बजाय, जो उन्हें जाने पर उत्पन्न करते हैं, उन्हें क्रमपरिवर्तन के लिए O (n) का उपयोग करना चाहिए।
गमोडजैकस

1

PHP, 309 बाइट्स

function j($x,$y,$c,$v){if($s=array_search([$x,$y],$v))unset($v[$s]);for($c--,$i=4;$c>0&&$i--;)$m=($n=j($x+[1,0,-1,0][$i],$y+[0,1,0,-1][$i],$c,$v))>$m?$n:$m;for($c-=.5,$i=4;$c>0&&$i--;)$m=($n=j($x+[1,-1,-1,1][$i],$y+[1,1,-1,-1][$i],$c,$v))>$m?$n:$m;return$s?++$m:$m;}echo j(0,0,$argv[1],array_chunk($argv,2));

बिल्कुल क्रूर बल और बहुत कम नहीं। उपयोग की तरह:

php -r "function j($x,$y,$c,$v){if($s=array_search([$x,$y],$v))unset($v[$s]);for($c--,$i=4;$c>0&&$i--;)$m=($n=j($x+[1,0,-1,0][$i],$y+[0,1,0,-1][$i],$c,$v))>$m?$n:$m;for($c-=.5,$i=4;$c>0&&$i--;)$m=($n=j($x+[1,-1,-1,1][$i],$y+[1,1,-1,-1][$i],$c,$v))>$m?$n:$m;return$s?++$m:$m;}echo j(0,0,$argv[1],array_chunk($argv,2));" 5 1 1 2 1 3 1 4 1 5 0 5 1

अधिक व्हॉट्सएप के साथ और एक फाइल में सहेजा गया:

<?php 
function j( $x, $y, $c, $v)
{
    if( $s = array_search( [$x,$y], $v ) )
        unset( $v[$s] );

    for( $c--, $i=4; $c>0 && $i--;)
        $m = ( $n=j($x+[1,0,-1,0][$i],$y+[0,1,0,-1][$i],$c,$v) )>$m ? $n : $m;

    for( $c-=.5, $i=4; $c>0 && $i--;)
        $m = ( $n=j($x+[1,-1,-1,1][$i],$y+[1,1,-1,-1][$i],$c,$v) )>$m ? $n : $m;

    return $s ? ++$m : $m;
}
echo j( 0, 0, $argv[1], array_chunk($argv,2) );

1

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

def f(c,l):
 def r(t):p=abs(t[0]-x);q=abs(t[1]-y);return p+q-.5*min(p,q)
 v=0;x,y=0,0
 while c>0 and len(l)>0:
  l.sort(key=r);c-=r(l[0]);x,y=l.pop(0)
  if c>=0:v+=1
 return v

cकैंडल का जीवनकाल है, टुपल्स की lएक सूची है - गांव निर्देशांक, vविज़िट किए गए गाँवों की संख्या है , गाँव के निर्देशांक (x,y)की जोड़ी है जैक वर्तमान में है।

r(t)एक फ़ंक्शन है जो वर्तमान स्थिति की दूरी की गणना करता है और इसका उपयोग सूची को सॉर्ट करने के लिए किया जाता है ताकि निकटतम बन जाए l[0]। प्रयुक्त सूत्र है | isx | + | Δy | - मिनट (| minx |, | (y |) / 2।

यहाँ यह कोशिश करो!


1

रैकेट

(define (dist x1 y1 x2 y2)     ; fn to find distance between 2 pts
  (sqrt(+ (expt(- x2 x1)2)
          (expt(- y2 y1)2))))

(define (fu x1 y1 x2 y2)       ; find fuel used to move from x1 y1 to x2 y2;
  (let loop ((x1 x1)
             (y1 y1)
             (fuelUsed 0))
    (let* ((d1 (dist (add1 x1) y1 x2 y2))        ; horizontal movement
           (d2 (dist x1 (add1 y1) x2 y2))        ; vertical movement
           (d3 (dist (add1 x1) (add1 y1) x2 y2)) ; diagonal movement
           (m (min d1 d2 d3))) ; find which of above leads to min remaining distance; 
      (cond 
        [(or (= d2 0)(= d1 0)) (add1 fuelUsed)]
        [(= d3 0) (+ 1.5 fuelUsed)]
        [(= m d1) (loop (add1 x1) y1 (add1 fuelUsed))]
        [(= m d2) (loop x1 (add1 y1) (add1 fuelUsed))]
        [(= m d3) (loop (add1 x1) (add1 y1) (+ 1.5 fuelUsed))]))))

(define (f a l)
  (define u (for/list ((i l))
    (fu 0 0 (list-ref i 0) (list-ref i 1))))  ; find fuel used for each point; 
  (for/last ((i u)(n (in-naturals)) #:final (>= i a))
    n))

परिक्षण:

(f 4 '((1 1) (2 2) (3 3))) ;-> 2
(f 5 '((1 1) (2 1) (3 1) (4 1) (5 0) (5 1))) ;-> 4

आउटपुट:

2
4

हालाँकि, उपरोक्त कोड x और y के नकारात्मक मानों के लिए काम नहीं करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.