रास्ता दिखाना


15

चुनौती

आपने एक मित्र को एक नक्शा दिया है जो इस तरह दिखता है:

      |
      /
     |
     /
    |
    \
     |
     \
      D

एक साधारण नक्शा जो शीर्ष पर शुरू होता है और सबसे नीचे होता है। अफसोस की बात है कि आपका दोस्त नहीं मिला। क्या आप मैप को डीकोड कर सकते हैं ताकि वह उसे पढ़ सके?

इनपुट

इनपुट से मिलकर वर्णों की स्ट्रिंग है |, /, \, D, ^, Y, (स्थान) , और नई-पंक्तियों।

  • | एक ही कॉलम में रहने के लिए कहता है।
  • \ दाएं और नीचे कॉलम में जाने के लिए कहता है 1।
  • / कॉलम को बाईं ओर ले जाने के लिए कहता है और नीचे 1।
  • D गंतव्य को चिह्नित करता है।
    • ^ (यदि मौजूद है) पथ में एक विभाजन के बारे में बताता है।
    • Y(यदि मौजूद है) रास्तों के बारे में बताता है। इसे एक की तरह व्यवहार करें |

इनपुट की व्यवस्था की जाएगी ताकि यह एक तरह का रास्ता बनाए:

   |
   |
   \
    |
    ^
   / \
  /   |
 D    |

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

उत्पादन

आउटपुट दिशाओं का एक स्ट्रिंग होना चाहिए।

  • " L " को अपने मित्र को L eft को स्थानांतरित करने और 1 कदम आगे बढ़ाने के लिए कहना चाहिए ।
  • " R " को अपने मित्र को R ight स्थानांतरित करने और 1 कदम आगे बढ़ाने के लिए कहना चाहिए ।
  • " एफ " को अपने दोस्त को 1 कदम आगे बढ़ने के लिए कहना चाहिए।

इनपुट उदाहरण मानचित्र के लिए, आउटपुट निम्नानुसार होगा:

F F L F R R R

ध्यान दें कि आपका मित्र मानचित्र के शीर्ष पर शुरू हो रहा है और मानचित्र का सामना कर रहा है। उसके दृष्टिकोण से दिशाएँ दें। "^" की एक आवृत्ति के लिए, आपका कार्यक्रम गंतव्य (डी) की ओर जाने वाले मार्ग को चुनने में सक्षम होना चाहिए। यदि दो पथ पुनर्संयोजित होते हैं, तो आपके प्रोग्राम |को अनुसरण करने के लिए सबसे सीधा रास्ता (सबसे अधिक s वाला) चुनना होगा । दिशाओं को रिक्त स्थान द्वारा अलग किया जाना चाहिए, और डी पर समाप्त होना चाहिए ।

उदाहरण

इनपुट

      |
      |
      \
       \
        ^
       / |
      |  |
      \  |
       \ \
        \ \
         \ /
          Y
          D

उत्पादन

F F L L L F F F L L R F

चूंकि बायीं ओर के पथ में केवल 1 है |, इसलिए हम सबसे सही पथ का उपयोग करते हैं जिसमें 3 है।


इनपुट

\
 |
 /
|
\
 |
 /
D

उत्पादन

L F R F L F R

इनपुट

    /
   \
    /
   \
    ^
   \ \
    D \

उत्पादन

R L R L R L

अन्य जानकारी

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

धन्यवाद!

थोड़ी देर हो सकती है, हो सकता है, लेकिन जावास्क्रिप्ट में विजेता कोडिंग अपरिभाषित हो! प्रवेश करने वाले सभी लोगों को धन्यवाद। कोई अन्य प्रविष्टि स्वीकार नहीं की जाएगी।


यह अभी भी बंद लगता है। पहला उदाहरण समाप्त होता है L L, जो मुझे लगता है कि होना चाहिए L L L। उदाहरण के साथ Yअभी भी 1अंत में है और यह भी लगता है कि अन्य त्रुटियां हैं। मैं नक्शे को पढ़ता हूं जैसे F F R R R F F F R R L Fकि मैं नियमों को सही ढंग से समझता हूं।
मार्टिन एंडर

@ मार्टिनबटनर आप डी पर समाप्त होने वाले हैं, आपको केवल 2 एलएस की आवश्यकता होगी। 3 Ls डी। से आगे जाएगा
The_Basset_Hound

2
क्या कोई रास्ता कभी अंतिम पंक्ति तक पहुंचने से पहले एक मृत अंत तक पहुंच सकता है? या सभी रास्ते इनपुट की अंतिम पंक्ति तक पहुंचेंगे?
jrich

@BassetHound वहाँ एक नहीं होना चाहिए Lके लिए ^और दो Lदो के लिए /? और आपने उदाहरण Fके अंत में दो और क्यों जोड़े Y?
मार्टिन एंडर

@ETHproductions हाँ।
The_Basset_Hound

जवाबों:


5

जावास्क्रिप्ट (ईएस 6), 261 248 252 248 212 बाइट्स

चूंकि केवल एक विभाजन का समर्थन किया जाना है:

s=>(s=s.replace(/ /g,o="",d=0).split(`
`)).map((v,j)=>{if(v=="^")for(v="/\\";(w=s[++j])&&(x=w[1]);d=x=="D"?1:w[0]=="D"?0:x>"{"?d+1:w[0]>"{"?d-1:d);o+=(p=v[d>0?1:0]||v[0])<"0"?"R ":p<"E"?"":p=="\\"?"L ":"F "})?o:o


हालाँकि, 240 बाइट्स और हम कई स्प्लिट्स से निपट सकते हैं:

s=>(s=s.replace(/ /g,o="").split(`
`)).map((v,j)=>{if(!v[1])t=d=0
else if(!t){for(t=1;(w=s[++j])&&(x=w[1]);d=x=="D"?1:w[0]=="D"?0:x>"{"?d+1:w[0]>"{"?d-1:d);o+=d>0?"L ":"R "}o+=(p=v[d>0?1:0])<"0"?"R ":p<"E"||p=="^"?"":p=="\\"?"L ":"F "})?o:o


दोनों कार्यक्रम गुमनाम कार्यों को परिभाषित करते हैं।

उपयोग करने के लिए, फ़ंक्शन f=को कोड के पहले जोड़कर एक नाम दें ।

बाद में, उन्हें साथ बुलाया जा सकता है

alert(f(
`   |
   |
   \\
    |
    ^
   / \\
  /   |
 D    |`
))


व्याख्या

(पुराना है, लेकिन अभी भी एक ही अवधारणा है। कई विभाजन समाधान के लिए)

s=>
    //Remove all spaces from the input
    (s=s.replace(/ /g,o="",
                 //Define function c, to convert symbols to directions
                 c=p=>p<"0"?"R ":p<"E"||p=="^"?"":p=="\\"?"L ":"F "
    //Split input into an array by newlines
    ).split(`
`))
    //for each string v in the input array, at index j:
    .map((v,j)=>{
        //if v is only one character long:
        if(!v[1]){
            t=1     //assign t to 1 (true) - we need to test if multiple paths
            d=0     //assign d to 0 - reset the counter for determining shortest path
        }
        //if v is two characters long, and we have not tested which path is shorter yet:
        else if(t){
            for(    t=0;    //assign t to 0 - we will have tested which path is longer

                    //for each string left in the input, while the input still has two characters:
                    (w=s[++j]) && w[1];
                    //assign d to determine which direction to go. This will be conveyed by if d>0
                    d=
                        w[1]=="D"?1:    //if the dest. is only on one side, choose that side.
                        w[0]=="D"?0:
                        w[1]=="|"?d+1:  //otherwise add/subtract from d (like a tug of war) to determine which side has more "|"
                        w[0]=="|"?d-1:
                        d
               );
            o+=d>0?"L ":"R "    //append to the output which direction was taken
        }

        o+=c(v[d>0?1:0])    //append to the output the characters from the correct path in any case, determined by d calculated above 
                            //(or defaulting to 0, if path is not split, in which case the only character is appended)

    }) ? o : o  //coerce the result, which will evaluate to an array of the input, to the output (o) and implicitly return


टिप्पणियाँ

  • \इनपुट में सभी बैकस्लैश ( ) बच गए हैं \\, ताकि जावास्क्रिप्ट उन्हें पहचान सके।

  • दोनों आउटपुट में एक अनुगामी स्थान होता है।


यह डांग, सोचा कि मैं यह सब तय किया था।
The_Basset_Hound

9

PHP, 634 631 607 396 382 381 347 338 330 337 324 बाइट्स

मेरा पहला गोल्फ इतना कोमल है। किसी भी सुझाव बहुत सराहना की है।

<?php
foreach(str_split(strtr(fgets(STDIN),[' '=>'']))as $i){if($i!=D){$z=$i=='^';$x=$i==Y;$s=!$z&&!$x?($i=='/'?R:($i=='|'?F:($i=='\\'?L:$s))):$s;$a.=$z?R:($x?F:(($c==1||!$c)?$s:''));$b.=$z?L:($x?F:(($c==2||!$c)?$s:''));$c=$z?1:($x?0:($c==1?2:($c==2?1:$c)));}else{echo(substr_count($a,F)<substr_count($b,F)&&$c==0||$c==2)?$b:$a;}}

लघु स्पष्टीकरण:
मेरे पास एक गिनती है जो 0 है यदि इनपुट में केवल एक ही रास्ता है। जब पथ विभाजित होता है तो बाएं पथ के लिए 1 और दाएं पथ के लिए 2 होता है। दोनों रास्तों (या केवल एक) को परिभाषित करने के बाद, मैं जांचता हूं कि किस पथ में अधिक "एफ" है।

Ungolfed संस्करण:

<?php
$input = fgets(STDIN);
$inputArray = str_split($input);
foreach ($inputArray as $currentChar) {
    if ($currentChar != 'D') {
        if ($i == '^') {
            $firstPath .= 'R';
            $secondPath .= 'L';
            $count = 1;
        } elseif ($i == 'Y') {
            $secondPath .= 'F';
            $firstPath .= 'F';
            $count = 0;
        } else {
            if ($i == ' ') {
                continue;
            }
            if ($i == '/') {
                $direction = 'R';
            } else {
                if ($i == '|') {
                    $direction = 'F';
                } else {
                    if ($i == '\\') {
                        $direction = 'L';
                    } else {
                        $direction = '';
                    }
                }
            }
            if ($count == 1) {
                $firstPath .= $direction;
                $count = 2;
            } elseif ($count == 2) {
                $secondPath .= $direction;
                $count = 1;
            }
            if (!$count) {
                $firstPath .= $direction;
                $secondPath .= $direction;
            }
        }
    } else {
        echo (substr_count($firstPath, 'F') < substr_count($secondPath, 'F')) || $count == 2 ? $secondPath : $firstPath;
    }
};


लॉग: कम से कम
36 बाइट्स के लिए धन्यवाद Kamehameha।
तर्क को थोड़ा बदलकर कई बाइट्स को बचाया।
बची हुई 42 बाइट्स एक्सिस के लिए धन्यवाद।
हर जगह बदल दिया अगर टर्नरी ऑपरेटरों के साथ क़ानून।


3
साइट पर आपका स्वागत है!
isaacg

2
आप $a=$b='';इसके बजाय की कोशिश कर सकते हैं - $a='';$b='';लगभग 3 बाइट्स बचाता है।
कमेहमे

1
साथ ही, जैसे समागम $a=$a.'L ';को कम किया जा सकता है $a.='L '। आपको लगता है कि कुछ स्थानों पर ऐसा किया गया है। वह लगभग 6 बाइट बचा
लेगा

1
मैं PHP को बहुत अच्छी तरह से नहीं जानता, लेकिन मेरा मानना ​​है कि आप अपने फॉर्च्यूनर में "जैसे" के बाद जगह छोड़ सकते हैं foreach($e as$i); मैंने परीक्षण किया है और यह ठीक काम करता है।
प्रोग्रामफॉक्स

1
कुछ बाइट्स को सहेजने के लिए कुछ और टिप्स, जैसा कि @ProgramFox के बारे में बताया asगया है foreach, के बीच के रिक्त स्थान echoऔर चर नाम को आपके पास हटाया जा सकता है echo$b। इसके अलावा, समानता परीक्षण की एक जोड़ी भी कम हो सकता है, $c==0हो सकता है !$cऔर यदि ऐसा है, तो आप आरंभ कर सकते हैं $cकरने के लिए ''के साथ $aऔर $b!
डोम हेस्टिंग्स

3

PHP, 281 बाइट्स

$b=0;$p=['|'=>'$a[$b].="F ";$f[$b]++;','/'=>'$a[$b].="R ";','\\'=>'$a[$b].="L ";','^'=>'$d.=$a[0];$n=2;$a=["R ","L "];$f=[];$b=1;','Y'=>'$d.=$a[$f[0]<$f[$n=1]]."F ";$a=[];','D'=>'$d.=$a[$b];exit(rtrim($d));'];foreach(str_split($argv[$n=1])as$c){if($x=$p[$c]){eval($x);$b=++$b%$n;}}

यह दो गोल्फिंग पुनरावृत्तियों का परिणाम है। अनगोल्ड संस्करण है:

$a=$f=[];       // these assignments are not required (they were suppresed in v2)
$n=1;           // this assignment can be squeezed into $argv[$n=1]
$b=0;           // if this assignment is suppressed $b becomes '' and breaks the logic
$code = [
    '|' => '$a[$b].="F ";$f[$b]++;',
    '/' => '$a[$b].="R ";',
    '\\'=> '$a[$b].="L ";',
    '^' => '$d.=$a[0];$n=2;$a=["R ","L "];$f=[];$b=1;',
    'Y' => '$d.=$a[$f[0]<$f[$n=1]]."F ";$a=[];',
    'D' => '$d.=$a[$b];echo(rtrim($d));',
];
foreach (str_split($argv[1]) as $char) {
    // ignore input characters not in the keys of $code
    if ($x = $code[$char]) {
        eval($x);
        $b = ++ $b % $n;   // cycles between 0 and 1 ($n == 2) or stays 0 ($n == 1)
    }
}

यह अपने आप में बहुत गोल्फ है और यह निम्नलिखित गोल्फ कार्यक्रम (312 बाइट्स) के सुधार के रूप में उभरा है।

$b=0;foreach(str_split($argv[$n=1])as$c){if($c=='|'){$a[$b].='F ';$f[$b]++;}elseif($c=='/'){$a[$b].='R ';}elseif($c=='\\'){$a[$b].='L ';}elseif($c=='^'){$d.=$a[0];$n=2;$a=['R ','L '];$f=[];$b=1;}elseif($c==Y){$d.=$a[$f[0]<$f[$n=1]].'F ';$a=[];}elseif($c==D){$d.=$a[$b];exit(rtrim($d));}else continue;$b=++$b%$n;}

यह मूल का गोल्फ संस्करण है:

$map = $argv[1];

$dir = '';              // the already computed directions
$nb = 1;                // the number of branches
$branches = [ '' ];     // the branches (2 while between '^' and 'Y', 1 otherwise)
$nbF = [ 0, 0 ];        // the number of 'F's on the branches (used to select the branch)
$curr = 0;              // the current branch
foreach (str_split($map) as $char) {
    if ($char == '|') {             // go 'F'orward
        $branches[$curr] .= 'F ';       // put it to the current branch
        $nbF[$curr] ++;                 // count it for the current branch
    } elseif ($char == '/') {       // go 'R'ight
        $branches[$curr] .= 'R ';
    } elseif ($char == '\\') {      // go 'L'eft
        $branches[$curr] .= 'L ';
    } elseif ($char == '^') {       // fork; choose the path ('L' or 'R') that contains the most 'F'orward segments
        $dir .= $branches[0];           // flush the current path (it was stored as the first branch)
        $nb = 2;                        // start two branches
        $branches = [ 'R ', 'L ' ];     // put the correct directions on each branch
        $nbF = [ 0, 0 ];                // no 'F's on any branch yet
        $curr = 1;                      // need this to let it be 0 on the next loop
    } elseif ($char == 'Y') {       // join
        $dir .= $branches[$nbF[0] < $nbF[1]];   // flush; choose the branch having the most 'F's
        $dir .= 'F ';                           // treat it like a "|"
        $branches = [ '' ];                     // back to a single, empty branch
        $nb = 1;
    } elseif ($char == 'D') {       // finish
        $dir .= $branches[$curr];       // flush
        break;                          // and exit; could use 'return' but it's one byte longer; use exit() in the final program and save 5 bytes
    } else {
        continue;
    }
    $curr = ++ $curr % $nb;
}
echo rtrim($dir);

उदाहरण निष्पादन:

$ php -d error_reporting=0 directions.php '
      |
      |
      \
       \
        ^
       / |
      |  |
      \  |
       \ \
        \ \
         \ /
          Y
          D
'; echo
F F L L L F F F L L R F
$

यह कई कांटे को सही ढंग से संभालता है (किसी भी समय अधिकतम दो शाखाओं में होने के लिए अगले कांटे से पहले जुड़ने की आवश्यकता होती है)। मैंने एक टिप्पणी में कई कांटे के बारे में पूछा लेकिन जवाब ("जरूरत नहीं") आने पर कोड पहले ही हो चुका था।

टेस्ट सूट और अधिक टिप्पणियों के साथ पूरा कोड जीथब पर पाया जा सकता है ।


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