산타는 언제 지하실에 들어 갑니까? (AOC 1 일차)


20

나는 코드의 출현 첫 날의 두 번째 부분을 제작자의 허락하에 재생산하고 있습니다.

산타는 큰 아파트 건물에 선물을 전달하려고하지만 올바른 층을 찾을 수 없습니다. 자신이받은 지시 사항은 약간 혼란 스럽습니다. 그는 1 층 (0 층)에서 시작하여 한 번에 한 문자 씩 지시를 따릅니다.

여는 괄호 (는 그가 한 층 위로 올라 가야한다는 것을 의미하고, 닫는 괄호 )는 그가 한 층 아래로 가야한다는 것을 의미합니다.

아파트 건물은 매우 높고 지하실은 매우 깊습니다. 그는 절대 최고층이나 최저층을 찾지 못할 것이다.

지시 사항이 주어지면 지하실에 들어가는 첫 번째 캐릭터의 위치를 ​​찾으십시오 (1 층).

예를 들어 :

입력 )하면 캐릭터 위치 1에서 지하실로 들어갑니다.

입력으로 ()())인해 캐릭터 위치 5에서 지하실로 들어갑니다.

해결책 1797을 산출 하는 긴 입력이 여기 에 제공 됩니다 .

이것은 코드 골프이므로 가장 짧은 솔루션이 승리합니다!


정확한 문자를 사용해야합니까?
Blue

1
@muddyfish 원래 도전에서 입력은 특정한 형태로 주어졌고, 종종 도전의 핵심 부분은 입력을 파싱하는 것이었다. 나는 이것이 "카멜레온 문제"가되기를 원하지 않지만 원래의 정신은 입력이 대괄호 문자열이어야한다는 것입니다. 나는 이것이 다른 언어들보다 일부 언어를 특권으로한다는 것을 알고 있지만, 유권자들이 해결책에 찬성 투표를 할 때 이것을 고려하도록 요구할 것이다.
시몬스

Parenthifiable 이진수매우 밀접한 관련이 있습니다 ... 나는 속임수가 될 정도로 강하게 느끼지 않으므로 대신 의견을 남기겠습니다.
AdmBorkBork

@TimmyD 나는 당신이 무슨 뜻인지 알지만이 질문은 경쟁 답변이 그 질문에서 너무 많이 그릴 수 없을 정도로 다르다고 생각합니다!
시몬스

1
SMBF (기본적으로 BF) 에서이 문제를 해결하려고 노력하고 있으며이 언어는 디버그 할 수 있습니다 ... ugh.
mbomb007

답변:


17

젤리, 8 7 바이트

O-*+\i-

1 바이트로 골프를 치는 @ Sp3000에 감사합니다!

온라인으로 사용해보십시오!

작동 원리

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

파이썬 2, 44 바이트

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

이 영리한 해결책은 Anarchy golf 에서이 문제에 대한 hallvabo, xsot, mitchs 및 whatisgolf가 발견했습니다 . 당신이 대신 그것을 게시하고 싶다면, 나는 이것을 제거 할 것입니다.

비결은 파이썬 파서가 작업을 수행하도록하는 것입니다. 이 함수 input()는 입력 문자열을 평가하려고 시도하고 일치하지 않는 첫 번째 paren에서 오류를 발생시킵니다. 이 오류는 잡히면 형식이됩니다

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

여기에는 오류가 발생한 문자 번호가 포함됩니다.


7

파이썬, 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]
유안

그리고이 교체는 내가 생각 -2*ord(z)+81하는 1 바이트를 절약2*(z<')')-1
Erwan

5

파이썬 3, 59

grc 덕분에 3 바이트를 절약했습니다.

파이썬에서 수동 문자열 인덱싱을 싫어합니다. 너무 잘못 느낀다.

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#

여기에서 테스트하십시오.

설명

시몬스가 이미 언급했듯이 ()CJam에게는 운이 좋은 선택입니다. CJam은 각각 감소 / 증가 연산자이기 때문입니다. 그것은 우리가 0에서 시작하는 경우 산타가 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와 공동 작업 한 결과입니다.

설명

일반적인 미로 입문서 ( "정상"이라고 말하지만 실제로는 매번 다시 작성합니다) :

  • Labyrinth는 스택 기반 2D 언어이며 첫 번째 유효한 문자 (여기서는 왼쪽 상단)부터 실행됩니다. 명령어 포인터가 취할 수있는 두 개 이상의 가능한 경로가있는 각 접점에서 스택의 맨 위를 확인하여 다음에 갈 곳을 결정합니다. 음수는 왼쪽이고, 0은 앞으로 가고 양수는 오른쪽입니다.
  • 스택은 바닥이없고 0으로 채워 지므로 빈 스택에서 터지는 것은 오류가 아닙니다.
  • 소스 코드의 숫자는 해당 숫자를 푸시하지 않습니다. 대신 스택의 상단을 팝하고를 누릅니다 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

마지막 복제는 수행 할 때마다 스택에 요소를 추가합니다. 우리가 0에 도달하고 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이 커서 URL이 깨지면 알려주십시오. 크롬에서는 괜찮습니다.)

Martin 덕분에 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

자바 스크립트 (ES6), 58 바이트

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

()첫 문자가가 될 때까지 일치하는 쌍을 반복적으로 제거하여 작동 합니다 ). 경고 : 충분한 )s 가없는 문자열에서는 이것을 시도하지 마십시오 . 예:

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

이 시점에서 총 12 개의 문자가 삭제되어 답은 13이됩니다.


대신 그 의견을 답변에 넣을 수 있습니다.
mbomb007

3

MATL , 12 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#)

여기에서 시도하십시오.

Martin 덕분에 2 바이트가 절약되었습니다.

설명:

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

자바 스크립트, 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

펄, 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

파이썬, 44 바이트

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

바닥 i1우리 i가 잘못된 값으로 끝나기 시작합니다 0. 종료되지 않은 경우, 재귀 적으로 하나를 추가하여 첫 번째 문자가 제거되고 해당 문자에 따라 층 번호가 업데이트됩니다.


2

자바 스크립트, 57 바이트

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

'('decs ')'이면 입력을 반복합니다. 첫 번째 음수를 반환합니다.


2

루비, 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

@TimmyD는 자동 초기화되도록 전역 화하는 것이 좋습니다.
Cole Cameron

1

PowerShell, 75 65 62 바이트

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

용도에서와 유사한 기술 Parenthifiable 이진수 실행 유지하는 모든 문자 입력을 통해 루프를, $c의 ounter +1(-1마다 )우리는 부정적인를 공격했는지 테스트 한 후, (즉, 우리는 지하에있어).

편집-인덱스가 아닌 실제 문자를 반복하여 10 바이트를
절약


1

Mathematica, 62 55 바이트

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

모든 긴 기능 이름! Simmons의 CJam 답변과 유사하게 작동합니다.


1

펀드 25 바이트

단항으로 출력합니다. 이것은 1 층에서 시작하여 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

루아, 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 / kona , 23 21 바이트

불필요한 괄호를 제거하여 2 바이트를 절약했습니다.

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

용법:

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

0

펄, 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

자바 스크립트 (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) 

미니 골프를위한 솔루션 과 비슷합니다.

우리는 산타가 항상 지하실에 도달한다고 가정 할 수 있습니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.