サンタはいつ地下室に入るのですか?(AOC 1日目)


20

Advent of Codeの初日の2番目の部分を、作成者の許可得て複製しています。

サンタは大きなアパートの建物でプレゼントを配達しようとしていますが、正しい階を見つけることができません-彼が得た方向は少し混乱しています。彼は1階(フロア0)から開始し、一度に1文字ずつ指示に従います。

開き括弧、(は彼が1フロア上に移動することを意味し、閉じ括弧)、は彼が1フロア下に移動することを意味します。

アパートの建物は非常に高く、地下室は非常に深いです。彼は最上階や最下階を見つけることはありません。

一連の指示が与えられたら、地下室に入室させる最初のキャラクターの位置を見つけます(階-1)。

例として:

入力する)と、文字位置1で地下室に入ります。

入力する()())と、彼は文字位置5で地下室に入ります。

ソリューション1797を生成する長い入力をここに示します。

これはコードゴルフであるため、最短のソリューションが勝ちです!


これらの正確な文字を使用する必要がありますか?
ブルー

1
@muddyfish元のチャレンジでは、入力は特定の形式で行われたため、チャレンジの重要な部分は入力の解析でした。これを「カメレオンの問題」にしたくないのですが、オリジナルの精神は、入力が角括弧の列であるべきだと思います。私はこれが他の言語よりもいくつかの言語に特権を与えていることを理解していますが、ソリューションへの賛成票を授与する際にこれを考慮に入れるよう有権者に求めます。
シモンズ

Parenthifiable Binary Number非常に密接に関連しています ...私はそれがだまされているほど強く感じていないので、代わりにコメントを残します。
AdmBorkBork

@TimmyDあなたの言っていることがわかりますが、この質問は十分に異なっていると感じているので、競争の答えはその質問からあまり多くを引き出すことができません!
シモンズ

1
私はこれをSMBF(基本的にはBF)で解決しようとしていますが、この言語はデバッグするのに苦労しています...うーん。
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

Python 2、44バイト

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

この賢明な解決策は、アナーキーゴルフのこの問題について、hallvabo、xsot、mitchs、whatisgolfによって発見されました。代わりに投稿する場合は、これを削除します。

秘Theは、Pythonのパーサーに仕事をさせることです。この関数input()は、入力文字列を評価しようとし、一致しない最初のかっこでエラーをスローします。このエラーは、キャッチされると次の形式になります

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バイトのゴルフ用。


サイトへようこそ!これは非常に素晴らしい最初の投稿です。:)
アレックスA.

あなたは置き換えることができます[0:g][:g]
エルワン・

そして1セーブでこの置換は私が考えるバイト-2*ord(z)+812*(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

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とのコラボレーションの結果です。

説明

通常のラビリンス入門書(「通常」と言いますが、実際に毎回これを書き換えます):

  • Labyrinthはスタックベースの2D言語で、最初の有効な文字(ここでは左上)から実行が開始されます。各ジャンクションで、命令ポインタが通る可能性のあるパスが2つ以上ある場合、スタックの最上部をチェックして次に進むべき場所を決定します。負は左に、ゼロは前進、正は右に曲がります。
  • スタックは底なしでゼロで埋められているため、空のスタックからポップしてもエラーにはなりません。
  • ソースコードの数字は、対応する数字をプッシュしません。代わりに、スタックの一番上をポップしてプッシュしn*10 + <digit>ます。これにより、多数を簡単に構築できます。新しい番号を開始するには_、ゼロをプッシュするを使用します。

ゴルフの目的のために、メインループは2つのタスクを1つに結合するため、このコードは少し奇妙です。最初のパスの前半では、次のことが行われます。

+(+             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では問題ありません。)

Martinのおかげで1バイト節約されました!

バランスの取れた括弧の最初のセットを照合して抽出し、空の文字列がその結果と一致する回数をカウントします。これがRetinaでこれを行う最も良い方法であるかどうか、特にPCREモードで短くするかどうかはわかり$#_ませんが、1回のエラーによるオフセットと複数の一致の問題のために、置換の使用は長くなったようです。

このアルゴリズムは無効な入力に対して奇妙な振る舞いを引き起こします。サンタが地下に行かなかった場合、彼は他の動きの後に不思議なことにそこにテレポートすると仮定します。



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)

ここで試してみてください

または、(and 以外の文字の使用が許可されている場合)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

()最初の文字がaになるまで、一致するsのペアを再帰的に削除して動作し)ます。警告:十分な)s がない文字列ではこれを試さないでください。例:

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

この時点で、回答が13になるように、合計で12文字が削除されたことがわかります。


代わりに、そのコメントを答えに入れることができます。
mbomb007

3

MATL12 11バイト

入力文字列に対して-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

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$_;$_=$.

いくつかのヒントをくれたデニスに感謝します。

-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はから始まり、falseyの値で1終了しiます0。終了していない場合は、最初の文字を削除して結果に1を再帰的に追加し、その文字に基づいてフロア番号を更新します。


2

Javascript、57バイト

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

入力を反復処理するだけで、「(」の場合はincs、「)」の場合はincsを繰り返します。最初の負で返します。



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をグローバルにすると、自動的に初期化されます。
コールキャメロン

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

Befunge 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

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)


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) 

ミニゴルフのこのソリューションに似てます

私たちはサンタが常に地下室に着くと仮定することができます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.