Noel Baba ne zaman bodrum katına giriyor? (AOC 1. Gün)


20

Advent of Code'un ilk gününün ikinci bölümünü , yaratıcıdan izin alarak yeniden üretiyorum .

Noel Baba büyük bir apartmanda hediyeler vermeye çalışıyor, ancak doğru katı bulamıyor - aldığı yönler biraz kafa karıştırıcı. Zemin katta (kat 0) başlar ve her seferinde bir karakter olan talimatları takip eder.

Açılış parantezi, (bir kat yukarı gitmesi gerektiği anlamına gelir ve kapanış parantez, )bir kat aşağı gitmesi gerektiği anlamına gelir.

Apartman çok uzun ve bodrum çok derin; üst veya alt katları asla bulamaz.

Bir dizi talimat verildiğinde, bodrum katına girmesine neden olan ilk karakterin konumunu bulun (kat -1).

Örnek olarak:

Girdi ), karakter 1'deki bodrum katına girmesine neden olur.

girdi ()()), karakter pozisyonunda bodrum katına girmesine neden olur.

Burada çözeltiyi 1797 vermesi gereken uzun bir girdi verilmiştir .

Bu kod golf, bu yüzden en kısa çözüm kazanır!


Bu karakterleri kullanmak zorunda mıyız?
Mavi

1
muddyfish Orijinal meydan okumalarda girdiler belirli bir biçimde verildi ve bu yüzden sık sık meydan okumanın kilit bir kısmı girdileri ayrıştırmaktı; bunun bir "bukalemun sorunu" olmasını istemiyorum ama bence orijinalin ruhu girdinin bir dizi parantez olması gerektiğidir. Bunun bazı dilleri diğerlerine göre ayrıcalıklı kıldığının farkındayım, ancak seçmenleri çözüm önerileri verirken bunu dikkate almaya çağırırım.
Simmons

Parentifiable ikili sayılarla çok yakından ilgili ... Bir dupe için yeterince güçlü hissetmiyorum, bunun yerine sadece bir yorum bırakacağım.
AdmBorkBork

@TimmyD Ne demek istediğini anlıyorum ama bu sorunun rekabetçi cevapların bu sorudan çok fazla çekemeyeceği kadar farklı olduğunu düşünüyorum!
Simmons

1
Ben SMBF (temelde BF) ve bu dil hata ayıklamak için berbat içinde çözmeye çalışıyorum ... ugh.
mbomb007

Yanıtlar:


17

Jöle, 8 7 bayt

O-*+\i-

1 bayt golf için @ Sp3000 için teşekkürler!

Çevrimiçi deneyin!

Nasıl çalışır

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 bayt

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

Bu akıllı çözüm, Anarşi golfünde bu problem üzerinde hallvabo, xsot, mitchs ve whatisgolf tarafından bulundu . Herhangi biriniz bunun yerine göndermek istiyorsanız, bunu kaldıracağım.

İşin püf noktası, Python'un ayrıştırıcısının işi yapmasına izin vermektir. İşlev input()bir giriş dizesini değerlendirmeye çalışır ve eşleşmeyen ilk eşleştirmeye bir hata atar. Yakalandığında bu hatanın bir formu vardır.

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

hatanın oluştuğu karakter numarasını içerir.


7

Python, 79 77 Bayt

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

Muhtemelen bunu yapmanın daha iyi bir yolu var, ama fikirlerim kalmadı. Ayrıca bu benim codegolf benim ilk yazı.

@Erwan'a teşekkürler. 2 bayt golf için.


Siteye Hoşgeldiniz! Bu çok güzel bir ilk gönderi. :)
Alex A.

Eğer yerine [0:g]göre[:g]
Erwan

ve 1 tasarrufu bu yedek bence bayt -2*ord(z)+81tarafından2*(z<')')-1
Erwan

5

Python 3, 59

Grc sayesinde 3 bayt kaydedildi.

Ben gerçekten Python manuel dize indeksleme yapmak sevmiyorum. Çok yanlış geliyor.

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

5

C, 55 bayt

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

Burada deneyin .

Düzenleme: Neden orada kullanılmayan bir değişken bıraktı emin değilim ...


5

CJam, 10 bayt

0l'_*:~1#)

veya

0l'_*~]1#)

veya (Dennis'e verilen krediler)

Wl+'_*:~1#

Burada test edin.

açıklama

A Simmons'un daha önce de belirttiği gibi (), sırasıyla azalan / artan operatörler olduğu için CJam için şanslı bir seçimdir. Bu, sıfırdan başlıyorsak, Noel Baba'nın 1. kata ulaştığı adımı arıyoruz.

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

Labirent , 18 bayt

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

Çevrimiçi deneyin! Bu cevap @ MartinBüttner ile işbirliğinin bir sonucuydu.

açıklama

Her zamanki Labirent primeri ("olağan" diyorum, ama aslında bunu her seferinde yeniden yazıyorum):

  • Labirent, ilk geçerli karakterden (burada sol üstte) başlayan, yığın tabanlı bir 2D dildir. Talimat işaretçisinin alması gereken iki veya daha fazla yolun bulunduğu her kavşakta, bir sonraki nereye gidileceğini belirlemek için yığının üstü kontrol edilir. Negatif sola, sıfır ileri ve pozitif sağa döner.
  • Yığın dipsizdir ve sıfırlarla doldurulur, bu nedenle boş bir yığından haşhaş bir hata değildir.
  • Kaynak koddaki rakamlar karşılık gelen sayıyı itmez - bunun yerine yığının üst kısmını açar ve iter n*10 + <digit>. Bu, büyük sayıların kolayca oluşturulmasını sağlar. Yeni bir sayı başlatmak için, tuşunu _sıfıra iten kullanın .

Bu kod biraz gariptir, çünkü golf amaçlı olarak, ana döngü iki görevi bir arada birleştirir. İlk geçişin ilk yarısı için şunlar olur:

+(+             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

Yığın üstte -1 ile başlatıldığına göre, gerçek işleme başlayabilir. İşte ana döngü bunu yapar.

,               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

Son kopya, gerçekleştirdiğimiz her yineleme için yığına bir öğe ekler. Bu önemlidir, çünkü sıfıra çarptığımızda ve NOP'da ilerlediğimizde:

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

3

Oracle SQL 11.2, 160 159 bayt

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;

Un-golfed

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

Retina ,22 21

! 'M' ^ ((\ () |?. (<- 2>)) +

Çevrimiçi deneyin veya büyük test senaryosunu deneyin. (URL, büyük test durumu için büyüktür, sizin için kırılıp kırılmadığını bana bildirin, kromda TAMAM görünüyor.)

Martin sayesinde 1 bayt kurtarıldı!

İlk dengeli parantez kümesini eşleştirip ayıklıyoruz, ardından boş dizenin bu sonuçla kaç kez eşleşeceğini sayıyoruz. Bunun Retina'da bunu yapmanın en güzel yolu olup olmadığından emin değilim, özellikle PCRE modu daha kısa yaparsa, ancak $#_bir hatayı kapatmak ve birden fazla eşleşme sorunu nedeniyle değiştirme kullanmak daha uzun görünüyordu.

Bu algoritma geçersiz girdi için garip davranışa neden olur, aslında Santa bunu bodrum katına çıkarmazsa, diğer hareketlerden sonra gizemli bir şekilde orada ışınlandığını varsayar.



3

Grep + AWK, 51 Bayt

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

grepKomut yeni bir satıra her bir karakteri yerleştirir.


3

Pyth, 13 bayt

f!hsm^_1Cd<zT

açıklama

              - 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)

Burada deneyin

Eski algoritma, 15 bayt

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

Açıklama:

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

Burada deneyin

Kullanımı dışında karakter izin Ya (ve ), 9 bayt (girişine ön işleme hareketli)

f!.v+<zT1

açıklama

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

Burada deneyin


3

JavaScript (ES6), 58 bayt

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

()İlk karakter a olana kadar bir çift eşleşen s yinelemeli olarak kaldırarak çalışır ). Uyarı: Yeterli )s içermeyen dizelerde bunu denemeyin . Misal:

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

Bu noktada cevabın 13 olması için toplamda 12 karakterin silindiğini görür.


Bunun yerine cevabınıza bu yorumu yazabilirsiniz.
mbomb007

3

MATL , 12 11 bayt

Dennis'in hesaplama dizisi -1'e yükseltilmesi fikri kullanılarak 1 bayt kaydedildi

1_j^Ys0<f1)

Çevrimiçi deneyin!

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 Bayt

0q{~_}%1#)

Burada deneyin.

Martin sayesinde iki bayt kurtardı.

Açıklama:

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 bayt

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

Diğer karakterleri yok sayar. Kullanır promptve alert.


2

Perl, 34 + 1 = 35 bayt

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

Bazı ipuçları için Dennis'e teşekkürler.

-pBayrağı ile çalıştırın . Perl 5.10'da çalışır, ancak sonraki sürümlerin burada bir alana ihtiyacı vardır:++ while

Eski, çözülmemiş sürüm:

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

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

Zemin , falsey değeri olarak sonlandığımız şekilde ibaşlar . Sonlandırılmazsa, ilk karakterin kaldırılması ve kat sayısının o karaktere göre güncellenmesi için bir özyineli olarak ekleyin.1i0


2

Javascript, 57 bayt

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

Oldukça basit, sadece giriş üzerinden yinelenir, eğer '(' eğer 'decs') '. İlk negatifte döner.



1

C, 73 bayt

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

STDIN üzerinde giriş bekliyor; hayır dışındaki karakterler (ve )(biz cevap ulaşana kadar en az) girişi görünebilir. Giriş ASCII olmalıdır .

STDOUT'ta cevap verir.

İçin ASCII arasında 1 bitlik farkını kullanır (ve ).

/* 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);
}

Güzel biçimlendirilmiş sürüm:


Bir bayt kaydetmek f=c=0için döngüyü başlatmaya taşıyabilir misiniz for(f=c=0;f!=...?
AdmBorkBork

@TimmyD onları global yapmak daha iyi, böylece otomatik olarak başlatılacaklar.
Cole Cameron

1

PowerShell, 75 65 62 bayt

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

Tüm girdi karakterleri arasında geçiş yapmak için Parenthifiable ikili sayılarında olduğu gibi benzer bir teknik kullanır ve her biri için her zaman için çalışan bir $cbekçiyi tutar , ardından negatif olup olmadığımızı test eder (yani bodrum katındayız).+1(-1)

Düzenleme - dizinleri yerine gerçek karakterler üzerinde yineleme yaparak 10 bayt kaydetti
Düzenleme 2 - modulo için eşitlik kontrolünü değiştirerek 3 ek bayt kaydetti, böylece döküm dolaylı


1

Mathematica, 62 55 bayt

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

Tüm uzun fonksiyon isimleri! Simmons'ın CJam cevabına benzer şekilde çalışır.


1

Befunge 25 bayt

Çıktılar tekli olarak. Bu sizi birinci katta başlatır ve 0'a kadar devam eder.

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

1

Raket (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)))))

Ungolfed

(λ (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 karakter

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

İngilizcede:

  • ¯1*')'=⍵: -1 olduğunda = girdi) ")", 1 aksi takdirde;
  • +\: akan toplam;
  • 1⍳⍨¯1=: ilk -1'in dizinini bul.

1

Lua, 92 89 87 Bayt

Komut satırı argümanını alır.

Düzenleme: Kaydedilen 3 Bayt

Düzenleme: 2 bayt kaydedildi ve kenar durumlarda oluşabilecek bir hatayı düzeltti, şimdi çıkış kodu ile çıktı

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

Ungolfed

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 bayt

Gereksiz parantezler kaldırılarak 2 bayt kaydedildi.

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

Kullanımı:

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

0

Perl, 40 + 1 = 41 bayt

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

-pBayrağı gerektirir :

$ 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

Geçerli girdi olduğunu varsayar.

Nasıl çalışır:

                                           # -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 bayt

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

İlk argüman olarak girdi alır

açıklama

(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 bayt

özyinelemeli bir çözüm

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

mini golf için bu çözüme benzer

Noel Baba'nın her zaman bodruma ulaştığını varsayabiliriz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.