两条道路分叉成黄色的木头(第2部分)


25

这是系列中的第二部分,第三部分是两条道路在黄色的树林中分叉(第3部分)

这是基于两条道路在黄色木材中分叉(第1部分),这是我的先前挑战。这是相当受欢迎的,但也很琐碎(一个Java回答52字节!)所以我做了一些更复杂的事情……

灵感来源

这一挑战的灵感来自罗伯特·弗罗斯特(Robert Frost)的著名诗作《未走的路》:

两条道路在黄色的树林中分叉,
对不起,我无法同时行进
,成为一个行人,我站了很久,尽我所能地
低头看
向灌木丛中的弯曲处。

... 2段落已删去...

我将叹息地告诉这个问题,它的
年代久远了:
两条路在树林中分叉,我-
我走过的路少了,
这一切都改变了。

请注意倒数第二行I took the one less traveled by,。您的目标是在字符串输入中找到行驶最少的道路。您必须输出彼此不同的2个值之一,以信号表明您应该转向哪种方式以减少行驶的道路。一旦路岔(六边形的轨迹变为数字),您就在交叉路口。从那里开始,将有2条由数字组成的路径。位数最低的路径将是未走的路。请注意,未走的道路的路径可能较大,但路径总和较低。下面是一些程序的示例/测试用例,这些程序针对未采用的路径打印“左”或“右”:

 1     2
  1   2
   1 2
    #
    #
    #
left (3 < 6)


 1     2
  2   2
   1 1
    #
    #
    #
left (4 < 5)


 12    2
  11  2
   1 1
    #
    #
    #
right (6 > 5)


 99   989
  99  89
  99 99
  99 99
    #
    #
    #
   # 
left (72 < 79)


1111 1110
 001 111
  11 11
  11 11
    #
   ##
  ##
 ##  
left (9 < 10) (Note: 1111 is interpreted as 1+1+1+1=4, not 1111=1111)


1       1
 0     1
  1   1
  1   1
  1   1
  1   1
   1 1 
    #
    #
    #
     #
      #
left (6 < 7)


1   1 
 0   1  
  1   1
  1   1
  1   1
  1   1
   1 1 
    #
    #
    #
     #
      #
left (6 < 7)

假设和记住的事情

  • 总会有2条路径。不多不少。
  • 您可以一次从STDIN中输入一行,也可以是包含LF字符的字符串,也可以是包含文字反斜杠和n的字符串。如果您需要任何其他方式的输入,请在评论中寻求批准。
  • 您不必担心无效的输入或绑定的路径。这些将永远不会输入到您的程序/功能中。
  • 输入的宽度或高度可以是任何长度,小于您的语言的字符串限制。
  • 永远不会有 #在同一行中和。
  • 路径中的所有数字均为0到9的正整数。
  • 允许输入或输出带有结尾的换行符。
  • 查看我的JS ES6答案下面的作为示例。
  • 2条路径之间始终至少有1个间隔。
  • 每条地图的2条路径始终具有相同的高度,但在其他地图上可能有所不同。
  • 如果您对特定的测试案例感到困惑,请告诉我。
  • 1111被解释为1 + 1 + 1 + 1 = 4,而不是1111 = 1111。该映射是一系列的一位数字,而不是任意长度的数字。
  • 这是,因此最短答案以字节为单位!
  • 禁止标准漏洞

如果您对此挑战有任何疑问,请在评论中问我,祝您好运!


嗨,您可以将所有答案及其字节数粘贴$("div > h1").map(function(){return $(this).text()}).get().join("\n");到控制台中!
程序员

1
这是一个替代版本,其中删除了空格并忽略了删除线答案let answers = $('div > h1').map(function(){return $(this).clone().children(':not(a)').remove().end().text().replace(/\s+/g,' ').trim()}).get();answers.splice(0, 1);answers.join('\n');
David Archibald

2
A#不是六角形...
user253751 '17

1
但是它也相当琐碎(一个Java答案为52个字节!)现在为43个字节。;)
Kevin Cruijssen

再次关闭投票?你到底怎么了?
马修·罗

Answers:


2

05AB1E21 15字节

向左输出0,向右输出1

|vy#õK€SO})øO`›

在线尝试!

说明

|v                # for each line in input
  y#              # split on spaces
    õK            # remove empty strings
      €S          # split each string into a list of chars
        O         # sum each sublist
         }        # end loop
          )ø      # wrap stack in a list and zip
            O     # sum each sublist (side of the tree)
             `›   # compare left to right

11

视网膜,28字节

\d
$*
%r`1\G
-
Os`.
+`-1

1+

在线尝试!

0向左和向右打印1向右。假定任何行上都没有尾随空格。

说明

\d
$*

每个数字转换N到运行N的。

%r`1\G
-

每行(%)一条,\G从末尾(r)匹配连续的()行,然后将它们替换为-(即,将右分支变成-s)。

Os`.

对所有字符进行排序,使所有-s都直接位于所有1s的前面。

+`-1

反复取消一对-1

1+

尝试匹配至少一个1(如果是这样,则左路径中的权重更多)。


7

Python 2中95个 89 88 87字节

这是我第一次使用python。绝对不是最佳选择,而是一个不错的开始。

f=lambda x,i:sum(sum(map(int,y))for y in x.split()[i::2]if"#"<y)
lambda x:f(x,1)>f(x,0)

在线尝试!


我认为您可以替换"#"!=y"#"<y
数学迷

7

芯片,216字节

 EZ,Z~.
E~]x-.|
F].>vm'
Ax]}#----------------.
Bx]}#---------------.|z.
Cx]}#------------.,Z|##' E
Dx]}#---------.,Z|`@@('A~^~t
 E.>#------.,Z|`@@-('
A~S`#v--.,Z|`@@-('
*f,--<,Z|`@@-('
e |,Z|`@@-('
,Z|`@@-('
>@@-('
a

在线尝试!

比第1部分的答案大一点...

总览

Chip是受实际电路启发的2D语言,它处理字节流中每个字节的组成位。

该解决方案保持了所看到数字的连续总和,每次遇到一段空白时都会翻转输入的符号,然后终止于第一个#。所以,为了输入

 11   12
  2   2
   1 1
    #
    #
    #

我们得到1 + 1 - 1 - 2 + 2 - 2 + 1 - 1 = -1。结果的符号作为输出给出,负数产生结果1,正数为0

因此,输出的1意思是左路径较少,而0意思是右。

说明

在较高的层次上,它是这样工作的:

@元素的主要对角线是累加器,输出由a底部的决定。(八对@均值表示8位,但是最高位是符号,因此此解决方案可以处理+127或-128的最大差。只要我们在终止之前返回,则中途溢出是可以的。)

Ax]}#--... 开头的四行正在读取输入,如果是数字,则取反(如果需要),然后将值传递给加法器。

前三行决定我们要查看的是数字还是空白序列,并跟踪是否需要取反数字。

输入中楔入的其余元素和最右边的元素处理终止条件,并将输出映射到ASCII(这样我们就可以得到字符'0''1'而不是value 0x00x1。此ASCII映射不需要额外的字节,否则我不会已包括在内。)


2
我喜欢代码有点像两条不同的道路。
Laikoni

@Laikoni我什至都没有注意到,这很酷:)
Phlarx

4

JavaScript(ES6),55个字节

x=>x.replace(/\d(?=.*( )|)/g,(d,s)=>t-=s?d:-d,t=0)&&t<0

假设每行没有尾随空格,并且输出truerightfalseleft。诀窍是匹配输入中的每个数字,如果在同一行上后面有空格,则从总数中减去;否则,将其添加到总数中。如果最终总数小于0,则正确的道路是行人较少的道路,反之亦然。

试试看:

f=x=>x.replace(/\d(?=.*( )|)/g,(d,s)=>t-=s?d:-d,t=0)&&t<0
<textarea placeholder = "paste in a map here..." oninput = "document.querySelector('div').innerText = f(this.value)"></textarea>
<div></div>


您需要将a x=放在开头,因为不允许使用表达式,仅允许将函数存储为变量和整个程序。
程序员

@ programmer5000为什么?覆盖默认值似乎有些奇怪,并且似乎并不表示问题所在。
小麦巫师

1
@ programmer5000实际上,默认情况下允许使用未命名的函数。(感谢您的摘录,顺便说一句)
ETHproductions

4

Python 3中85 94个字节

import re
g=lambda s,i:sum(map(int,''.join(re.findall('\d+',s)[i::2])))
lambda s:g(s,0)>g(s,1)

在线尝试!

诅咒!没有足够仔细地阅读问题。添加了一个修复程序(''.join()),但代价为9个字节。


很近!很好,谢谢!
数据流

3

Python 2,78个字节

-1个字节感谢@math_junkie

在线尝试

def F(S,r=0):
 for c in S.split():
    if'#'<c:r+=sum(map(int,c));r=-r
 print r>0

打印False左路径和True右路径


r=-r而不是r*=-1应该节省一个字节
数学迷

2

视网膜,180字节

字节数假定为ISO 8859-1编码。

^(?=( *(0|(1|(?<3>2|(?<3>3|(?<3>4|(?<3>5|(?<3>6|(?<3>7|(?<3>8|(?<3>9))))))))))+.+¶)+)(.+ (0|(?<-3>1|(?<-3>2|(?<-3>3|(?<-3>4|(?<-3>5|(?<-3>6|(?<-3>7|(?<-3>8|(?<-3>9))))))))))+¶)+ *#

在线尝试!

我以为我也会尝试仅使用正则表达式的解决方案(上面是一个简单的.NET正则表达式,它仅匹配应该采用正确路径的输入,除了使用 用作的简写\n)。

它令人讨厌地重复,但这就是当您必须分别对待每个可能的数字时发生的事情。

解决方案是平衡组的相当简单的应用:首先,通过将N捕获推入3每个数字的堆栈,将左分支中的数字相加N。然后,我们尝试到达#,同时从堆栈3 N时间弹出N右侧分支中每个数字。仅当左分支中的数字总和大于右分支中的数字之和时(因为您不能从空堆栈中弹出),才有可能。


我对.NET正则表达式不熟悉,但是您不能做一个字符集:[0-9]匹配所有数字或\d吗?
程序员

@ programmer5000当然,但是然后我无法区分它们,以确定我应该推动多少次捕获以求和。
马丁·恩德

2

的JavaScript(ES6),106个 104字节

s=b=>(b=b.split`\n`,c=0,d=0,b.forEach(a=>{a=a.match(/\d+/g)||[],c+=+(a[0]?a[0]:0),d+=+(a[1]?a[1]:0)}),c<d)

s=b=>(b=b.split("\n"),c=0,d=0,b.forEach(a=>{a=a.match(/\d+/g)||[],c+=+(a[0]?a[0]:0),d+=+(a[1]?a[1]:0)}),c<d)

s是一个函数,true如果未走的路在左侧,则返回。取消高尔夫:

var proc = function(str){
    str = str.split("\n");
    var left = 0;
    var right = 0;
    str.forEach(item=>{
        var match = item.match(/\d+/g) || [];
        console.log(match);
        left += +(match[0] ? match[0] : 0);
        right += +(match[1] ? match[1] : 0);
    });
    return left < right;
};

s=b=>(b=b.split`\n`,c=0,d=0,b.forEach(a=>{a=a.match(/\d+/g)||[],c+=+(a[0]?a[0]:0),d+=+(a[1]?a[1]:0)}),c<d)
<textarea placeholder = "paste in a map here..." oninput = "document.querySelector('div').innerText = s(this.value)"></textarea>
<div></div>


我希望有人能得到比这更好的成绩...
programmer5000

接受挑战@ programmer5000
David Archibald

@DavidArchibald已经有人做过,但是我希望得到一个新的答案。您对系列中的第三个感兴趣吗?
程序员

当然。没意识到有3
David Archibald

2

PowerShell,80字节

$args-split'\s|#'-ne''|%{$a+=(($i=[char[]]$_-join'+'|iex),-$i)[($x=!$x)]};$a-gt0

在线尝试!

(只需在Python答案下尖叫即可。:D)

输出True左路径和False为正确的道路。

将输入作为一个以`n,表示的字符串,该字符串在PowerShell中等效于“一个包含文字反斜杠和n的字符串”,或者作为文字多行字符串。然后-split,我们在\s(空格,包括换行符)上输入,或#过滤掉所有空结果-ne'',因此只剩下一个数字数组。那些被送入循环|%{...}

每次迭代时,我们首先获取当前元素$_,将其转换为char数组,将-join其与加号一起转换+iexInvoke-Expression并类似于eval)。它已存储到其中,$i因此我们可以适当地对路径的此特定块上的数字求和。然后,我们将其和它的负数用作数组的两个元素,($i, -$i)通过前后翻转布尔值将其索引为该数组。意思是,通过该循环的第一次迭代,第一个左路径块,我们将索引到-$i;中。下次,我们将接$i;等等。那些累积$a在一起+=

最后,我们评估是否$a-greater t0。如果是,则右路径具有较大的和,否则,左路径具有较大的和。该布尔结果留在管道上,并且输出是隐式的。


2

CJam19 18字节

qN/Sf%z{'1*:~:+}/>

在线尝试!

0向左和向右打印1向右。

说明

q      e# Read all input.
N/     e# Split into lines.
Sf%    e# Split each line around runs of spaces.
z      e# Transpose to group each branch.
       e# Note that each branch will have the same number of digit segments
       e# now but the first branch will also have all the #s at the end in
       e# separate segments.
{      e# For each branch...
  '1*  e#   Join the segments into a single string with 1s as separators.
       e#   This will add the same number of 1s between digit segments in
       e#   both branches (which won't affect their relative sum) and it 
       e#   will also insert a 1 before each # in the first branch.
  :~   e#   Evaluate each character. The digit characters are simply turned
       e#   into their values, but # is the exponentiation operator in CJam.
       e#   This is why we inserted those additional 1s, because 1# is a no-op.
  :+   e#   Sum the digits in the branch.
}/
>      e# Check whether the left branch's sum is greater than the right one's.

1

Mathematica,80岁 77字节

感谢Martin Ender节省了3个字节!

#<#2&@@Total@Partition[Tr/@ToExpression[Characters@StringSplit@#/."#"->0],2]&

纯函数,以换行符分隔的字符串作为输入,然后返回True以采用左侧路径,False以采用右侧路径。那些冗长的Mathematica命令名称;这就像10个令牌。


0

19 18字节

LR+XDax:-x+$+$0SGx

在命令行上将输入作为单个字符串输入(如果在实际命令行上运行,则需要使用引号和转义换行符)。-1左输出,1右输出。在线尝试!

说明

循环显示数字,将数字总和添加到计数中。每次交换提示符号,最终结果是左侧值为负,右侧值为正。然后,我们打印最后的提示符号(-11)。

                    a is 1st cmdline arg; XD is regex `\d`; x is "" (implicit)
                    Note that "" in a math context is treated as 0
  +XD               Apply regex + to XD (resulting in `\d+`)
LR   a              Loop over matches of that regex in a:
             $0      Regex match variable containing the full match
           $+        Sum digits by folding on +
      x:-x+          Swap the sign of the tally and add this sum
               SGx  After the loop, print the sign of the tally

0

Haskell,64个字节

g=sum.map fromEnum
f(a:b:r)|a>"#"=g a-g b+f r|1<3=0
(>0).f.words

在线尝试!用法:匿名函数(>0).f.words以换行符分隔的字符串作为参数,并返回Falseleft和True right。

说明:

给定输入

 99   989
  99  89
  99 99
    #
    #
   # 

,即字符串" 99 989\n 99 89\n 99 99\n #\n #\n #",然后words去除所有换行符和空格,并返回剩余字符串的列表:["99","989","99","89","99","99","#","#","#"]。该函数从列表中f获取前两个元素,a并通过将其与字符串“#”进行比较来b检查是否a为数字字符串。(因为char '#'小于所有数字chars '0''1'...,每个以数字开头的字符串在字典上都比"#"。大。)该函数g将字符串中的每个char映射到其ascii字符代码并返回其总和。在f应用中,对于正确的路径,将为负,否则为正,因此请检查结果是否大于零。gab计算时g a - g b,即左路径的值减去右路径的值,并将其添加到对的递归调用中f处理以下几行。如果左路径走得更远的结果f(>0)


0

Python 3,84个字节

由于当前所有的Python提交都是函数,所以我想我会编写一个完整的程序。

x=0
try:
 while 1:
  for n in input().split():x=-x+sum(map(int,n))
except:print(x>0)

True如果左路径走得少,False则打印,否则打印。在线尝试!

对于输入的每一行,这会在空格上分割,将每个结果元素的数字相加,然后将其添加到计数中,同时在每个步骤中翻转计数的符号。它继续读取输入行,直到被a击中为止#,这时map(int,n)会引发异常,然后退出循环,True如果提示为正,False则进行打印。


0

批处理,169字节

@echo off
set/as=0
:l
set/pr=
if not %r: =%==# call:c - %r%&goto l
cmd/cset/a"s>>9
exit/b
:c
call:r + %3
:r
set/as%1=%2%%10,d=%2/10
if %d% gtr 0 call:r %1 %d%

0向左打印,-1向右打印。注意:读取行,直到找到带有的行#,然后停止读取。路径总和的差异限制为511(添加1个字节以支持更大的差异)。每条路径的每一行中不得超过9位数字(支持任意数量的行)。说明:该子例程处理要添加的数字,然后掉进去处理前两个参数。这意味着调用和左右数字将在右边数字相加而在左边数字相减。最后,将结果移位以提取符号。d子例程具有两个参数:是加还是减以及数字。它以10为模,提取最后一位,以10除以余数,并在仍有余数的情况下递归调用自身。该c子例程具有三个参数:是相加还是相减,要相加或相减的数字以及要相加的其他数字。它称dc用的参数子例程-


0

八度,46字节

@(a)diff((a(:)-48)'*(bwlabel(a>35)(:)==1:2))<0

在线尝试! 将2D字符数组a作为输入的函数。

说明:

a=

    1   1  
     0   1 
      1   1
      1   1
      1   1
      1   1
       1 1 
        #  
        #  
        #  
         # 
          #

a > 35                   %convert the matrix to a binary matrix
                         %where there is a number corresponing
                         %element of the binary matrix is 1.

*   *  
 *   * 
  *   *
  *   *
  *   *
  *   *
   * * 

bwlabel(a>35)            %label each connected component. 


1   2  
 1   2 
  1   2
  1   2
  1   2
  1   2
   1 2 

B=bwlabel(a>35)(:)==1:2  % a binary `[n ,2]` matrix created 
                         % each column related to one of labels

A=(a(:)-48)'             % convert array of characters to array of numbers 

A * B                    % matrix multiplication that computes 
                         % the sum of numbers under each label

diff(A*B)<0              % check if the left is grater than the right

0

Java 7,219 216字节

boolean c(String s){int l=0,r=0;for(String x:s.split("\n")){l+=f(x,0);r+=f(x,1);}return l>r;}int f(String x,int i){if(x.contains("#"))return 0;int n=0;for(int c:x.trim().split("\\s+")[i].getBytes())n+=c-48;return n;}

这次长度超过52个字节。;)
再次返回false右和true左。

说明:

boolean c(String s){              // Method with String parameter and boolean return-type
  int l=0, r=0;                   //  Right and left counters
  for(String x : s.split("\n")){  //  Loop over de lines
    l += f(x,0);                  //   Add all left digits to the left-counter
    r += f(x,1);                  //   Add all right digits to the right-counter
  }                               //  End of loop
  return l>r;                     //  Return whether the left-counter is larger than the right-counter
}                                 // End of method

int f(String x, int i){           // Separate method with String and integer parameters, and int return-type
  if(x.contains("#"))             //  If the current line contains "#"
    return 0;                     //   Simply return 0
  int n=0;                        //  Counter
  for(int c :                     //  Loop over the digits by
              x.trim()            //    first removing leading and trailing whitespaces
              .split("\\s+")      //    then split them right in the middle
              [i]                 //    then pick either the left or right side based on the int index parameter
              .getBytes())        //    and convert that String to a byte-array
    n += c-48;                    //   For each of those digit-characters: add it to the counter
                                  //  End of loop (implicit / single-line body)
  return n;                       //  Return the counter
}                                 // End of separate method

测试代码:

在这里尝试。

class M{
  boolean c(String s){int l=0,r=0;for(String x:s.split("\n")){l+=f(x,0);r+=f(x,1);}return l>r;}int f(String x,int i){if(x.contains("#"))return 0;int n=0;for(int c:x.trim().split("\\s+")[i].getBytes())n+=c-48;return n;}

  public static void main(String[] a){
    M m = new M();
    System.out.println(m.c(" 1     2\n  1   2\n   1 2\n    #\n    #\n    #"));
    System.out.println(m.c(" 1     2\n  2   2\n   1 1\n    #\n    #\n    #"));
    System.out.println(m.c(" 12    2\n  11  2\n   1 1\n    #\n    #\n    #"));
    System.out.println(m.c(" 99   989\n  99  89\n  99 99\n  99 99\n    #\n    #\n    #\n   # "));
    System.out.println(m.c("1111 1110\n 001 111\n  11 11\n  11 11\n    #\n   ##\n  ##\n ##  "));
    System.out.println(m.c("1       1\n 0     1\n  1   1\n  1   1\n  1   1\n  1   1\n   1 1 \n    #\n    #\n    #\n     #\n      #"));
    System.out.println(m.c("1   1 \n 0   1 \n  1   1\n  1   1\n  1   1\n  1   1\n   1 1 \n    #\n    #\n    #\n     #\n      #"));
  }
}

输出:

false
false
true
false
false
false
false
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.