指示方向


15

挑战

您已将地图提供给看起来像这样的朋友:

      |
      /
     |
     /
    |
    \
     |
     \
      D

一个简单的地图,从顶部开始,在底部结束。可悲的是,您的朋友不明白。您可以解码地图以便他可以阅读吗?

输入值

输入是由字符的字符串|/\D^Y (空间),和换行符。

  • | 告诉您留在同一列中。
  • \ 告诉您移至右边的列并向下1。
  • / 告诉您移至左侧和下方的列1。
  • D 标记目的地。
    • ^ (如果存在)说明路径中存在分裂。
    • Y(如果存在)表明路径重新连接。像对待它一样|

输入的排列方式将使其成为一种路径:

   |
   |
   \
    |
    ^
   / \
  /   |
 D    |

两条路径之间始终会有一个空格,所有路径将重新连接或到达输入的最后一行。每个地图只会有一个分割。输入映射的长度没有限制。路径永远不会超过两个。

输出量

输出应该是一串方向。

  • 大号 ”应该告诉你的朋友搬家大号 EFT,并采取1周的一步。
  • [R ”应该告诉你的朋友搬家[R飞行,并采取1周的一步。
  • F ”应告诉您的朋友前进1步。

对于输入示例图,输出将如下所示:

F F L F R R R

请注意,您的朋友是从地图顶部开始并面朝下。从他的角度给出方向。对于“ ^”的实例,您的程序必须能够选择通向目标(D)的路径。如果两条路径重新组合,则您的程序必须选择最直的路径(具有最大|s 的一条)。方向必须以空格隔开,并且必须 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

其他详情

  • 这是代码高尔夫球,因此在8月19日下一个星期三之前代码最短的人将获胜。
  • 建设性的反馈意见欢迎并深表赞赏。
  • 部分受“ 隐藏宝藏地图”的启发
  • 随意将标题更改为更具创意的名称。
  • 如果您发现我犯的错误,请纠正它们。
  • 当然,玩得开心。

谢谢!

也许有点晚了,但是UndefinedFunction是JavaScript的胜利者!感谢所有进入的人。没有其他条目将被接受。


它似乎仍然关闭。第一个示例以结尾L L,我认为应该如此L L L。与这个例子Y仍具有1在年底似乎也有其他错误。我阅读地图就像F F R R R F F F R R L F是正确理解规则一样。
马丁·恩德

@MartinBüttner,您应该以D结尾,您只需要2L。3个LS将晃过D.
The_Basset_Hound

2
路径能否在到达最后一行之前到达死角?还是所有路径都到达输入的最后一行?
jrich

@BassetHound不应该有一个L^两个L两个/?为什么FY示例末尾再添加两个?
马丁·恩德

@ETHproductions是的。
The_Basset_Hound 2015年

Answers:


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


笔记

  • \输入中的所有反斜杠()均转义为\\,以便javascript可以识别它们。

  • 两个输出都包含尾随空格。


晃来晃去,以为我把所有的东西都修好了。
The_Basset_Hound 2015年

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”。

非高尔夫版本:

<?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;
    }
};


日志:
感谢Kamehameha,保存了36个字节。
通过稍微更改逻辑来节省许多字节。
感谢axiac,节省了42个字节。
用三元运算符替换每个if语句。


3
欢迎光临本站!
isaacg 2015年

2
您可以尝试$a=$b='';使用- $a='';$b='';节省大约3个字节。
Kamehameha 2015年

1
而且,类似的串联$a=$a.'L ';可以减少为$a.='L '。您似乎已经在几个地方做到了。这将节省大约6个字节:)
Kamehameha 2015年

1
我不太了解PHP,但是我相信您可以在foreach(foreach($e as$i))中的“ as”之后删除空格。我已经测试过了,看来效果很好。
ProgramFOX

1
一对夫妇更多的技巧来节省几个字节,如@ProgramFox提到有关asforeach,之间的空间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
$

它还可以正确处理多个分支(需要在下一个分支之前加入,以便任何时候最多具有两个分支)。我在评论中询问了多个分叉,但是当答案(“不需要”)到来时,代码已经完成。

带有测试套件的完整代码和更多注释可以在github上找到。


哇,辛苦了!我仍然需要学习很多东西!
jrenk
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.