ให้เส้นทาง


15

ท้าทาย

คุณได้มอบแผนที่ให้กับเพื่อนที่มีลักษณะดังนี้:

      |
      /
     |
     /
    |
    \
     |
     \
      D

แผนที่ง่าย ๆ ที่เริ่มต้นที่ด้านบนและสิ้นสุดที่ด้านล่าง น่าเศร้าที่เพื่อนของคุณไม่เข้าใจ คุณสามารถถอดรหัสแผนที่เพื่อให้เขาอ่านได้หรือไม่?

อินพุต

การป้อนข้อมูลที่เป็นสายอักขระประกอบด้วย|, /, \, D, ^, Y, (เว้นวรรค)และการขึ้นบรรทัดใหม่

  • | บอกให้อยู่ในคอลัมน์เดียวกัน
  • \ บอกให้ย้ายไปที่คอลัมน์ด้านขวาและลง 1
  • / บอกให้ย้ายไปที่คอลัมน์ทางซ้ายและลง 1
  • D ทำเครื่องหมายปลายทาง
    • ^ (ถ้ามี) บอกการแยกในเส้นทาง
    • Y(ถ้ามี) บอกถึงการเข้าร่วมเส้นทาง |รักษามันเหมือน

อินพุตจะถูกจัดเรียงเพื่อให้เป็นเส้นทางแบบ:

   |
   |
   \
    |
    ^
   / \
  /   |
 D    |

จะมีช่องว่างระหว่างสองเส้นทางเสมอและเส้นทางทั้งหมดจะเข้าร่วมหรือไปถึงบรรทัดสุดท้ายของอินพุต จะมีเพียงหนึ่งแยกต่อแผนที่ ไม่มีการจำกัดความยาวของแผนที่อินพุต จะไม่มีทางมากกว่าสองเส้นทาง

เอาท์พุต

เอาต์พุตควรเป็นสตริงของทิศทาง

  • " L " ควรบอกเพื่อนของคุณให้ย้ายL eft และก้าวไปข้างหน้า 1 ก้าว
  • " R " ควรจะบอกเพื่อนของคุณที่จะย้ายR ight และใช้เวลา 1 ก้าวไปข้างหน้า
  • " F " ควรบอกเพื่อนของคุณให้ก้าวไปข้างหน้า 1 ก้าว

สำหรับแม็พตัวอย่างอินพุตเอาต์พุตจะเป็นดังนี้:

F F L F R R R

โปรดทราบว่าเพื่อนของคุณเริ่มที่ด้านบนของแผนที่และหันหน้าไปทางแผนที่ บอกทิศทางจากมุมมองของเขา สำหรับอินสแตนซ์ของ "^" โปรแกรมของคุณจะต้องสามารถเลือกเส้นทางที่นำไปสู่ปลายทาง (D) หากทั้งสองเส้นทางรวมกันอีกครั้งโปรแกรมของคุณจะต้องเลือกเส้นทางที่ตรงที่สุด (เส้นทางที่มีเส้นทางมากที่สุด|) ที่จะติดตาม ทิศทางจะต้องคั่นด้วยช่องว่างและต้องจบใน D

ตัวอย่าง

อินพุต

      |
      |
      \
       \
        ^
       / |
      |  |
      \  |
       \ \
        \ \
         \ /
          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 สิงหาคมจะเป็นผู้ชนะ
  • ยินดีต้อนรับข้อเสนอแนะที่สร้างสรรค์และชื่นชมอย่างมาก
  • แรงบันดาลใจบางส่วนจากแผนที่เพื่อสมบัติที่ซ่อนอยู่
  • รู้สึกฟรีเพื่อเปลี่ยนชื่อเป็นสิ่งที่สร้างสรรค์มากขึ้น
  • หากคุณพบข้อผิดพลาดที่ฉันทำให้แก้ไขให้ถูกต้อง
  • และแน่นอนมีความสนุกสนาน

ขอขอบคุณ!

ช้าไปสักหน่อยบางที แต่ UndefinedFunction เป็นผู้ชนะการเข้ารหัสใน JavaScript! ขอบคุณทุกคนที่เข้ามา จะไม่มีการยอมรับรายการอื่น ๆ


มันยังคงดูเหมือน ตัวอย่างแรกจะสิ้นสุดลงในซึ่งผมคิดว่าควรจะเป็นL L L L Lตัวอย่างที่Yยังคงมี1ในตอนท้ายและดูเหมือนว่าจะมีข้อผิดพลาดอื่น ๆ ฉันอ่านแผนที่ราวกับF F R R R F F F R R L Fเข้าใจกฎอย่างถูกต้อง
Martin Ender

@ MartinBüttnerคุณควรจะจบใน D คุณจะต้อง 2 Ls 3 Ls จะผ่าน D.
The_Basset_Hound

2
เส้นทางสามารถไปถึงทางตันก่อนถึงเส้นสุดท้ายได้หรือไม่? หรือเส้นทางทั้งหมดจะไปถึงบรรทัดสุดท้ายของอินพุตหรือไม่
ริ

@BassetHound ไม่ควรมีหนึ่งLสำหรับ^สองLสำหรับสอง/หรือไม่ และทำไมคุณเพิ่มอีกสองตัวอย่างFในตอนท้ายY?
Martin Ender

@ETHproductions ใช่
The_Basset_Hound

คำตอบ:


5

Javascript (ES6), 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 สำหรับเส้นทางที่ถูกต้อง หลังจากกำหนดเส้นทางทั้งสอง (หรือเพียงหนึ่งเส้นทาง) ฉันจะตรวจสอบว่าเส้นทางใดมี "F's" มากกว่า

เวอร์ชันที่ไม่ถูกปรับแต่ง:

<?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 ไบต์ขอบคุณ axiac
ถูกแทนที่ทุก ๆ ถ้า statment กับผู้ประกอบการที่ประกอบไปด้วย


3
ยินดีต้อนรับสู่เว็บไซต์!
isaacg

2
คุณสามารถลอง$a=$b='';แทน - $a='';$b='';บันทึกประมาณ 3 ไบต์
Kamehameha

1
นอกจากนี้ยัง$a=$a.'L ';สามารถลดการเรียงต่อกันได้เช่น$a.='L 'กัน คุณดูเหมือนจะทำอย่างนั้นในสองแห่ง นั่นจะประหยัดได้ประมาณ 6 ไบต์ :)
Kamehameha

1
ฉันไม่รู้ PHP ดีมาก แต่ฉันเชื่อว่าคุณสามารถปล่อยพื้นที่หลังจาก "เป็น" ใน foreach ( foreach($e as$i)) ของคุณ ฉันได้ทดสอบแล้วและดูเหมือนว่าจะทำงานได้ดี
ProgramFOX

1
คู่เคล็ดลับการประหยัดไม่กี่ไบต์เป็น @ProgramFox กล่าวถึงเกี่ยวกับasในforeachช่องว่างระหว่างและชื่อตัวแปรที่สามารถถอดออกเพื่อให้คุณมีecho echo$bนอกจากนี้สองของการทดสอบความเท่าเทียมกันสามารถจะสั้นเกินไป$c==0อาจจะเป็น!$cและหากเป็นกรณีที่คุณสามารถ initialise $cไป''ด้วย$aและ$b!
Dom Hastings

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)
    }
}

มันเป็นสนามกอล์ฟที่สวยงามและมันก็กลายเป็นการพัฒนาโปรแกรม golfed ดังต่อไปนี้ (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;}

มันเป็นเวอร์ชั่น golfed ของต้นฉบับ:

$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
$

นอกจากนี้ยังจัดการส้อมหลายอย่างถูกต้อง (ต้องเข้าร่วมก่อน fork ถัดไปเพื่อให้มีสองสาขาได้ตลอดเวลา) ฉันถามเกี่ยวกับส้อมหลายอันในความคิดเห็น แต่รหัสก็ทำไปแล้วเมื่อคำตอบ ("ไม่จำเป็น") มา

รหัสที่สมบูรณ์แบบด้วยชุดทดสอบและแสดงความคิดเห็นเพิ่มเติมสามารถพบได้บน GitHub


ว้าวทำได้ดีมาก! ฉันยังต้องเรียนรู้บางสิ่ง!
jrenk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.