圣诞老人什么时候进入地下室?(AOC第一天)


20

在创作者的允许下,我正在复制《代码出现》第一天的第二部分

圣诞老人正试图在一个大型公寓楼中送礼物,但他找不到合适的楼层-他的指示有些混乱。他从一楼(0楼)开始,然后一次按照一个字符跟随说明。

圆括号“,(”表示他应该上升一层,而圆括号“ ),”则意味着应该下降一层。

公寓楼很高,地下室很深。他将永远找不到顶层或底层。

给定一组说明,找到导致他进入地下室的第一个角色的位置(-1楼)。

例如:

输入)导致他进入角色位置1的地下室。

输入()())导致他进入角色位置5的地下室。

此处给出的长输入将产生解决方案1797。

这就是代码高尔夫,所以最短的解决方案是成功的!


我们必须使用那些确切的字符吗?
蓝色

1
@muddyfish在最初的挑战中,输入是以特定形式给出的,因此,挑战的关键部分通常是解析输入。虽然我不希望这成为“变色龙问题”,但我认为原始的精神是输入应该是一串括号。我意识到这确实使某些语言优先于其他语言,但我呼吁选民在授予对解决方案的投票时要考虑到这一点。
西蒙斯(Simmons)

非常密切相关的Parenthifiable二进制数 ...我不觉得很足够强烈,这是一个欺骗,所以我就发表评论吧。
AdmBorkBork '16

@TimmyD我明白您的意思,但是我觉得这个问题与以往的问题足够不同,以至于竞争性的答案将无法从该问题中获得太多收益!
西蒙斯(Simmons)

1
我正在尝试在SMBF(基本上是BF)中解决此问题,并且这种语言需要SUCKS进行调试...呃。
mbomb007 '16

Answers:


17

果冻,8 7字节

O-*+\i-

感谢@ Sp3000打高尔夫球1个字节!

在线尝试!

怎么运行的

O-*+\i-    Main link. Input: s (string)

O          Ordinal; replace each character with its code point.
           This maps "()" to [48, 49].
 -*        Apply x -> (-1) ** x.
           This maps [48, 49] to [1, -1].
   +\      Compute the cumulative sum, i.e., the list of partial sums.
     i-    Find the first index of -1.

16

Python 2,44字节

try:input()
except Exception,e:print e[1][2]

hallvabo,xsot,mitch和whatisgolf 在无政府状态高尔夫上发现了这个聪明的解决方案。如果您想发布它,我将删除它。

诀窍是让Python的解析器完成这项工作。该函数input()尝试评估输入字符串,并在第一个不匹配的paren上引发错误。捕获到此错误后,就会形成表格

SyntaxError('unexpected EOF while parsing', ('<string>', 1, 1, ')'))

其中包括发生错误的字符号。


7

Python,79 77字节

lambda m:[sum([2*(z<')')-1for z in m][:g])for g in range(len(m)+1)].index(-1)

可能有更好的方法来执行此操作,但是我没有想法。这也是我在codegolf上的第一篇文章。

感谢@Erwan。打高尔夫球的2个字节。


欢迎光临本站!这是一篇非常不错的第一篇文章。:)
Alex A.

您可以替换[0:g][:g]
Erwan 2016年

这种更换节省1个字节我想-2*ord(z)+81通过2*(z<')')-1
二湾

5

Python 3、59

由于grc,节省了3个字节。

我真的不喜欢在Python中进行手动字符串索引。感觉真不对劲。

def f(x):
 c=q=0
 while-~c:c+=1-(x[q]>'(')*2;q+=1
 return q

5

C,55个字节

g;main(f){for(;f;g++)f+=81-getchar()*2;printf("%d",g);}

在这里尝试。

编辑:不知道为什么我在那里留下一个未使用的变量...


5

CJam,10个字节

0l'_*:~1#)

要么

0l'_*~]1#)

或(归功于丹尼斯)

Wl+'_*:~1#

在这里测试。

说明

正如A Simmons已经指出的那样,()对于CJam来说,这是一个幸运的选择,因为它们分别是减量/增量运算符。这意味着,如果我们从零开始,我们正在寻找圣诞老人到达第1楼的步骤。

0   e# Push 0, the initial floor.
l   e# Read input.
'_* e# Riffle the input string with underscores, which duplicate the top of the stack.
:~  e# Evaluate each character, using a map which wraps the result in an array.
1#  e# Find the position of the first 1.
)   e# Increment because we're looking for a one-based index.

4

迷宫,18字节

+(+"#(!@
:  :
%2_,

在线尝试!这个答案是与@MartinBüttner合作的结果。

说明

普通的迷宫引物(我说“通常”,但实际上每次都重写):

  • 迷宫是一种基于堆栈的2D语言,其执行从第一个有效字符(此处为左上方)开始。在每个结点处,有两个或更多条指令指针可以通过的路径,将检查堆栈的顶部以确定下一步的位置。负向左转,零向前进,正向右转。
  • 堆栈是无底的,并填充有零,因此从空堆栈弹出不会出错。
  • 源代码中的数字不会压入相应的数字,而是弹出堆栈顶部并压入n*10 + <digit>。这使得容易建立大量。要开始一个新的数字,请使用_,按0。

这段代码有点怪异,因为出于高尔夫目的,主循环将两个任务组合为一个。对于第一遍的前半部分,将发生以下情况:

+(+             Add two zeroes, decrement, add with zero
                This leaves -1 on the stack
"               NOP at a junction. -1 is negative so we try to turn left, fail, and
                turn right instead.
:               Duplicate -1

现在,栈顶已初始化为-1,可以开始实际的处理了。这是主循环的作用。

,               Read a byte of input
_2%             Take modulo 2.
:+              Duplicate and add, i.e. double
(               Decrement
                This maps "(" -> -1, ")" -> 1
+               Add to running total
"               NOP at a junction. Go forward if zero, otherwise turn right.
:               Duplicate the top of the stack

最后一个副本为我们执行的每个迭代将一个元素添加到堆栈中。这很重要,因为当我们达到零并在NOP前进时,我们会:

#               Push stack depth
(               Decrement
!               Output as num
@               Terminate

3

的Oracle SQL 11.2 160个 159字节

SELECT MIN(l)FROM(SELECT l,SUM(m)OVER(ORDER BY l)p FROM(SELECT LEVEL l,DECODE(SUBSTR(:1,LEVEL,1),'(',1,-1)m FROM DUAL CONNECT BY LEVEL<=LENGTH(:1)))WHERE p=-1;

未打高尔夫球

SELECT MIN(l) -- Keep the min level
FROM(
  SELECT l,SUM(m)OVER(ORDER BY l)p -- Sum the () up to the current row
  FROM(
    SELECT LEVEL l,DECODE(SUBSTR(:1,LEVEL,1),'(',1,-1)m -- ( equal 1 and ) equal -1 
    FROM DUAL 
    CONNECT BY LEVEL<= LENGTH(:1)
  )
)
WHERE p=-1 -- Keep the rows where the () sum is equal to -1

3

视网膜22 21

!M` ^((\()|(?<-2>。))+

在线尝试尝试大型测试案例。(对于大型测试用例而言,URL很大,让我知道它是否适合您,在chrome中似乎还可以。)

感谢马丁,节省了1个字节!

我们匹配第一组平衡括号并将其提取,然后计算空字符串与该结果匹配的次数。我不确定这是否是在Retina中执行此操作的最好方法,特别是如果PCRE模式使它更短时,但是$#_由于一次错误和不止一场比赛的问题,使用替换方法似乎会更长。

该算法会导致无效输入的奇怪行为,它实质上是假设如果圣诞老人没有进入地下室,他会在其他移动之后神秘地传送到地下室。



3

Grep + AWK,51字节

grep -o .|awk '/\(/{s++}/)/{s--}s<0{print NR;exit}'

grep命令将每个字符放在新行上。


3

Pyth,13个字节

f!hsm^_1Cd<zT

说明

              - autoassign z = input()
f             - First where V returns Truthy.
          <zT -     z[:T]
    m         -    [V for d in ^]
        Cd    -     ord(d)
     ^_1      -      -1**^
   s          -   sum(^)
 !h           -  not (^+1)

在这里尝试

旧算法,15个字节

f!h-/J<zT\(/J\)

说明:

                - autoassign z = input()
f               - First where V returns Truthy.
      <zT       -      z[:T]
     J          -     autoassign J = ^
    /    \(     -    ^.count("(")
           /J\) -    J.count(")")
   -            -   ^-^
 !h             -  not (^+1)

在这里尝试

或者如果允许比其他使用字符()9个字节(移动前处理到输入)

f!.v+<zT1

说明

          - autoassign z = input()
f         - First where V returns Truthy.
     <zT  -     z[:T]
    +   1 -    ^+"1"
  .v      -   eval(^)
 !        -  not ^

在这里尝试


3

JavaScript(ES6),58个字节

f=(s,t=s)=>s<')'?f(s.replace('()',''),t):t.length-s.length+1

通过递归地删除一对匹配的()s直到第一个字符为a来工作)。警告:请勿在)s 不足的字符串上尝试此操作。例:

((()())()))
((())()))
(()()))
(()))
())
)

此时,可以看到总共删除了12个字符,因此答案为13。


您可以将该评论放入答案中。
mbomb007 '16

3

MATL12 11字节

使用Dennis的计算思想-1将1个字节保存为输入字符串

1_j^Ys0<f1)

在线尝试!

1_         % number -1
j          % take string input
^          % element-wise power. This transforms '('  to 1 and ')' to -1
Ys         % cumulative sum
0<         % true for negative values
f          % find all such values 
1)         % pick first. Implicit display

2

CJam,12个 10字节

0q{~_}%1#)

在这里尝试。

感谢马丁,节省了两个字节。

说明:

0              Load 0 onto the stack
 q             Load input onto the stack without evaluating
  {  }       Code block
   ~_          Evaluate the next command and duplicate the top stack element. The format of the question is good for CJam and Golfscript since ) and ( are increment and decrement operators (though the wrong way round).
        %      Map this code block over the string. This yields an array of Santa's floor positions
         1#   Find the first instance of a 1, since decrement and increment are swapped
           )  Fix the off-by-1 error caused by zero-indexing

2

Javascript,117个字节

o=f=0;i=prompt().split('');for(c in i){switch (i[c]){case '(':f++;break;case ')':f--;if(f<0){alert(o+1);i=[];}}o++;}

忽略其他字符。用途promptalert


2

Perl,34 + 1 = 35个字节

$.+=s+.+++s+\)++while")"gt$_;$_=$.

感谢Dennis的一些提示。

-p标志一起运行。它可以在Perl 5.10中使用,但更高版本需要在此处留一个空格:++ while

较旧的版本:

$_ = <>;                # get a line of input
while ($_ lt ')') {     # while it begins with a (
    s/.//;              # remove the first (
    s/\)//;             # remove the first )
    $i += 2;            # increase index by 2
}
print $i + 1;           # print the position

2

Python,44个字节

f=lambda s,i=1:i and-~f(s[1:],i-1+2*(s<')'))

下限i开始于,1因此我们i以falsey值终止0。如果未终止,则递归地添加一个,结果是删除第一个字符,并根据该字符更新楼层编号。


2

Javascript,57个字节

p=>{c=0;for(i in p){c+=p[i]==')'?-1:1;if(c<0)return+i+1}}

非常简单,只需遍历输入,如果'('则减少'')的增量。返回第一个负数。


2

Ruby,47个字节

匿名函数。

->s{i,l=-1,0;l+=s[i+=1]>?(?-1:1 while l>-1;i+1}

1

C,73个字节

main(f,c){f=c=0;for(;f!=-1;c++){f+=1-((getchar()&1)<<1);}printf("%d",c);}

期望在STDIN上输入;除了(和之外,其他字符都不会)出现在输入中(至少直到我们找到答案之前)。输入必须为ASCII。

在STDOUT上发出答案。

(和使用ASCII之间的1位差)

/* old-style arguments, implicitly int */
main(x, f)
{
    /* c is our character counter, f is the floor*/
    c = f = 0;
    /* increase c while f is not -1 */
    for (;f != -1; c++) {
        /* use difference in LSB to add one for (, subtract one for ) */
        f += 1-((getchar()&1)<<1);
    }
    /* answer */
    printf("%d", c);
}

格式正确的版本:


您可以将其f=c=0移至循环的初始化中for(f=c=0;f!=...以节省字节吗?
AdmBorkBork '16

@TimmyD最好使它们成为全局的,以便它们自动初始化。
科尔·卡梅隆

1

PowerShell,75 65 62字节

[char[]]$args[0]|%{$c+=(1,-1)[$_%40];$d++;if($c-lt0){$d;exit}}

采用了类似的技术,因为在Parenthifiable二进制数来遍历所有输入的字符,保持运行$c的ounter +1每个(-1每一个),然后检测我们是否已经打了负(即,我们是在地下室)。

编辑-通过遍历实际字符而不是其索引来保存10个字节
编辑2-通过将相等性检查交换为模来节省3个额外的字节,因此隐式转换


1

Mathematica,62 55字节

Position[Accumulate[(-1)^ToCharacterCode@#],-1][[1,1]]&

所有长函数名称!与Simmons的CJam答案类似。


1

删除25个字节

一元输出。这将使您从第一层开始,直到0。

1<\1_v#:+-*2%2~
:#._@>$1>

1

球拍(102)

(λ(s)(let l((c 0)(b 0)(s(string->list s)))(if(> 0 b)c(l(+ 1 c)((if(eqv?(car s)#\()+ -)b 1)(cdr s)))))

不打高尔夫球

(λ (input)
  (let loop ((count 0) (balance 0) (chars (string->list input)))
    (if (> 0 balance)
        count
        (loop (+ 1 count)
              ((if (eqv? (car chars) #\() + -) balance 1)
              (cdr chars)))))

1

APL,18个字符

{1⍳⍨¯1=+\¯1*')'=⍵}

用英语:

  • ¯1*')'=⍵:-1,其中输入=“)”,否则为1;
  • +\:总和;
  • 1⍳⍨¯1=:找到第一个-1的索引。

1

Lua,92 89 87字节

它接受命令行参数。

编辑:保存3个字节

编辑:保存2个字节,并更正了可能发生在边缘情况下的错误,现在它通过其退出代码输出

r=0i=0(...):gsub(".",function(c)i=i+1r=r+(c==")"and-1or 1)if r<0then os.exit(i)end end)

不打高尔夫球

r,i=0,0                     -- set r (the actual floor), and i(the character count)
(...):gsub(".",function(c) -- apply an anonymous functions on each character of the input
  i,r=i+1,                  -- increment i
      r+(c==")"and -1 or 1) -- decrement r if c==")", increment it otherwise
  if r<0 then os.exit(i)end -- if r==-1, exit and output the current index
end)

1

k / kona23 21字节

删除不必要的括号可节省2个字节。

{1+(+\1 -1"()"?x)?-1}

用法:

k){1+(+\1 -1"()"?x)?-1} "())"
3

0

Perl,40 + 1 = 41字节

$y++,($i+=/\(/*2-1)<0&&last for/./g;$_=$y

需要-p标志:

$ perl -pe'$y++,($i+=/\(/*2-1)<0&&last for/./g;$_=$y' <<< '()())'
5
$ perl -pe'$y++,($i+=/\(/*2-1)<0&&last for/./g;$_=$y' 1797.txt
1797

假定有效输入。

怎么运行的:

                                           # -p read line by line into $_ and auto prints at the end
        $y++,                              # Counter for steps taken
             ($i+=/\(/*2-1) < 0            # The match /\(/ will give 1 or 0 in a numeric context 1 for `(` and 0 for anything else
                                           # times it by 2 and subtracting -1 will yield 1 or -1
                               && last     # End the iteration if $i < 0
for/./g;                                   # Iterate over each items in the input
                                      $_=$y# Print the output

0

Javascript(ES6),68 67字节

(s,r,f=0)=>s.split``.map((l,i)=>(f+=l=='('?1:-1,f<0?r=r||++i:0))&&r

将输入作为第一个参数

说明

(s, r, f=0)                                  //Gets string, declares r and f to equal undefined and 0
         =>
            s.split``                        //Splits string into character array
            .map(                            //Loops over array
                 (l, i)=>(
                         f +=                //Increment f
                         l=='(' ? 1 : -1,    //By either 1 or -1 depending on character
                         f<0 ?               //If the floor is less than 0
                         r=r||++i            //And is first time below, r equals index (+1 to make it '1 indexed not 0')
                         : 0)
                         &&r                   //Return index

0

Python(3.5),78 71 62字节

递归解决方案

f=lambda s,p=0,v=0:p if v<0else f(s[1:],p+1,v+2*(s[0]<')')-1) 

它类似于解决方案,迷你高尔夫球场

我们可以假设圣诞老人总是到地下室

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.