Wann betritt der Weihnachtsmann den Keller? (AOC Tag 1)

20

Ich reproduziere den zweiten Teil des ersten Tags des Advent of Code mit Genehmigung des Erstellers.

Der Weihnachtsmann versucht, Geschenke in einem großen Wohnhaus auszuliefern, findet aber nicht die richtige Etage - die Anweisungen sind ein wenig verwirrend. Er beginnt im Erdgeschoss (Etage 0) und folgt dann den Anweisungen einzeln.

Eine öffnende Klammer (bedeutet, dass er eine Etage höher gehen soll, und eine schließende Klammer )bedeutet, dass er eine Etage tiefer gehen soll.

Das Wohnhaus ist sehr hoch und der Keller ist sehr tief; Er wird niemals die oberen oder unteren Stockwerke finden.

Suchen Sie anhand einer Reihe von Anweisungen die Position des ersten Zeichens, das ihn veranlasst, den Keller zu betreten (Etage -1).

Als Beispiele:

Durch die Eingabe )betritt er den Keller an Position 1 des Charakters.

Durch die Eingabe ()())betritt er den Keller an Position 5 des Charakters.

Ein langer Eingang gegeben hier , dass die Lösung 1797 ergeben sollte.

Das ist Codegolf, also gewinnt die kürzeste Lösung!

Ein Simmons
quelle
Müssen wir genau diese Zeichen verwenden?
Blue
1
@muddyfish In den ursprünglichen Herausforderungen wurden die Eingaben in einer bestimmten Form gegeben und so oft bestand ein wesentlicher Teil der Herausforderung darin, die Eingaben zu analysieren. Ich möchte zwar nicht, dass dies zu einem "Chamäleon-Problem" wird, aber ich denke, der Geist des Originals ist, dass die Eingabe eine Reihe von Klammern sein sollte. Mir ist klar, dass dies einige Sprachen gegenüber anderen privilegiert, aber ich fordere die Wähler auf, dies bei der Vergabe von Gegenstimmen für Lösungen zu berücksichtigen.
Ein Simmons
Sehr eng verwandt mit parenthifizierbaren Binärzahlen ... Ich fühle mich nicht so stark, dass es ein Betrug ist, also hinterlasse ich stattdessen nur einen Kommentar.
AdmBorkBork
@TimmyD Ich verstehe, was Sie meinen, aber ich glaube, diese Frage ist so unterschiedlich, dass die Antworten von Mitbewerbern nicht zu viel aus dieser Frage ziehen können!
Ein Simmons
1
Ich versuche, dies in SMBF (im Grunde BF) zu lösen, und diese Sprache saugt zum Debuggen ... ugh.
mbomb007

Antworten:

17

Gelee, 8 7 Bytes

O-*+\i-

Vielen Dank an @ Sp3000 für das Golfen ab 1 Byte!

Probieren Sie es online!

Wie es funktioniert

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.
Dennis
quelle
16

Python 2, 44 Bytes

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

Diese clevere Lösung wurde von Hallvabo, Xsot, Mitchs und Whatisgolf für dieses Problem beim Anarchy Golf gefunden . Wenn jemand von euch es stattdessen posten möchte, werde ich es entfernen.

Der Trick ist, Pythons Parser die Arbeit machen zu lassen. Die Funktion input()versucht, eine Eingabezeichenfolge auszuwerten, und löst beim ersten nicht übereinstimmenden Paren einen Fehler aus. Dieser Fehler hat, wenn er abgefangen wird, Form

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

Dies beinhaltet die Zeichennummer, an der der Fehler aufgetreten ist.

xnor
quelle
7

Python 79 77 Bytes

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

Es gibt wahrscheinlich einen besseren Weg, dies zu tun, aber mir fehlen die Ideen. Auch dies ist mein erster Beitrag über Codegolf.

Vielen Dank an @Erwan. zum Golfen ab 2 Bytes.

drobilc
quelle
Willkommen auf der Seite! Dies ist ein sehr schöner erster Beitrag. :)
Alex A.
Sie können [0:g]durch[:g]
Erwan
und dieser Ersatz speichern 1 Byte ich denke , -2*ord(z)+81durch2*(z<')')-1
Erwan
5

Python 3, 59

3 Bytes gespart dank grc.

Ich mag es nicht, in Python manuell Zeichenfolgen zu indizieren. Es fühlt sich so falsch an.

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

C 55 Bytes

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

Probieren Sie es hier aus .

Edit: Ich bin mir nicht sicher, warum ich eine unbenutzte Variable dort belassen habe ...

Cole Cameron
quelle
5

CJam, 10 Bytes

0l'_*:~1#)

oder

0l'_*~]1#)

oder (Dank an Dennis)

Wl+'_*:~1#

Teste es hier.

Erläuterung

Wie A Simmons bereits bemerkte, ()ist CJam eine glückliche Wahl, da dies die Dekrement- / Inkrement-Operatoren sind. Das heißt, wenn wir bei Null beginnen, suchen wir nach der Stufe, bei der der Weihnachtsmann die erste Etage erreicht.

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.
Martin Ender
quelle
4

Labyrinth , 18 Bytes

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

Probieren Sie es online! Diese Antwort ergab sich aus der Zusammenarbeit mit @ MartinBüttner.

Erläuterung

Der übliche Labyrinth-Primer (ich sage "normal", aber das schreibe ich jedes Mal neu):

  • Labyrinth ist eine stapelbasierte 2D-Sprache, deren Ausführung mit dem ersten gültigen Zeichen beginnt (hier oben links). An jeder Kreuzung, an der es zwei oder mehr mögliche Pfade für den Befehlszeiger gibt, wird die Oberseite des Stapels überprüft, um zu bestimmen, wohin als nächstes gegangen werden soll. Negativ ist links abbiegen, Null ist vorwärts und positiv ist rechts abbiegen.
  • Der Stapel ist bodenlos und mit Nullen gefüllt, sodass das Abspringen von einem leeren Stapel kein Fehler ist.
  • Die Ziffern im Quellcode drücken nicht auf die entsprechende Zahl, sondern auf den oberen Bereich des Stapels n*10 + <digit>. Dies ermöglicht den einfachen Aufbau großer Zahlen. Verwenden Sie _, um eine neue Nummer zu beginnen , die Null drückt.

Dieser Code ist etwas seltsam, da die Hauptschleife zum Golfen zwei Aufgaben in einer vereint. Für die erste Hälfte des ersten Durchgangs passiert Folgendes:

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

Nachdem der Stack mit -1 initialisiert wurde, kann die eigentliche Verarbeitung beginnen. Hier ist, was die Hauptschleife macht.

,               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

Das letzte Duplikat fügt dem Stapel für jede von uns ausgeführte Iteration ein Element hinzu. Dies ist wichtig, da wir Folgendes tun, wenn wir beim NOP auf Null gehen und vorwärts gehen:

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

Oracle SQL 11.2, 160 159 Bytes

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;

Nicht golfen

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
Jeto
quelle
3

Retina ,22 21

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

Probieren Sie es online aus oder testen Sie den großen Testfall. (Die URL für den großen Testfall ist groß. Lassen Sie mich wissen, ob sie für Sie nicht funktioniert. In Chrome scheint sie in Ordnung zu sein.)

1 Byte gespart dank Martin!

Wir passen die ersten ausgeglichenen Klammern an und extrahieren sie. Dann zählen wir, wie oft die leere Zeichenfolge mit diesem Ergebnis übereinstimmt. Ich bin mir nicht sicher, ob dies der beste Weg ist, dies in Retina zu tun, besonders wenn der PCRE-Modus es kürzer macht, aber die Verwendung des $#_Ersatzes schien länger zu sein, weil ein Fehler aufgetreten ist und das Problem besteht, dass mehr als eine Übereinstimmung vorliegt.

Dieser Algorithmus verursacht ein merkwürdiges Verhalten bei ungültigen Eingaben. Er geht im Wesentlichen davon aus, dass der Weihnachtsmann sich nach den anderen Bewegungen auf mysteriöse Weise dorthin teleportiert, wenn er es nicht in den Keller schafft.

FryAmTheEggman
quelle
3

Grep + AWK, 51 Bytes

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

Der grepBefehl setzt jedes Zeichen in eine neue Zeile.

Robert Benson
quelle
3

Pyth, 13 Bytes

f!hsm^_1Cd<zT

Erläuterung

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

Probieren Sie es hier aus

Alter Algorithmus, 15 Bytes

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

Erläuterung:

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

Probieren Sie es hier aus

Oder wenn andere Zeichen als (und verwendet werden dürfen ), 9 Bytes (Verschieben der Vorverarbeitung zur Eingabe)

f!.v+<zT1

Erläuterung

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

Probieren Sie es hier aus

Blau
quelle
3

JavaScript (ES6), 58 Byte

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

Entfernt rekursiv ein Paar übereinstimmender ()s, bis das erste Zeichen a ist ). Warnung: Versuchen Sie dies nicht bei Saiten, die nicht genug )s haben. Beispiel:

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

Zu diesem Zeitpunkt wurden insgesamt 12 Zeichen gelöscht, sodass die Antwort 13 lautet.

Neil
quelle
Sie könnten diesen Kommentar stattdessen in Ihre Antwort einfügen.
mbomb007
3

MATL , 12 11 Bytes

1 Byte, das mit Dennis 'Idee, -1 zu berechnen, in der Eingabezeichenfolge gespeichert wurde

1_j^Ys0<f1)

Probieren Sie es online!

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
Luis Mendo
quelle
2

CJam, 12 10 Bytes

0q{~_}%1#)

Probieren Sie es hier aus.

Zwei Bytes gespart dank Martin.

Erläuterung:

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
Ein Simmons
quelle
2

Javascript, 117 Bytes

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

Ignoriert andere Zeichen. Verwendet promptund alert.

Solomon Ucko
quelle
2

Perl, 34 + 1 = 35 Bytes

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

Danke an Dennis für ein paar Tipps.

Laufen Sie mit dem -p Flagge. Es funktioniert in Perl 5.10, aber spätere Versionen benötigen hier ein Leerzeichen:++ while

Ältere, nicht Golf spielende Version:

$_ = <>;                # 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
grc
quelle
2

Python, 44 Bytes

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

Der Boden ibeginnt bei, 1so dass wir imit dem Falsey-Wert enden 0. Wenn dies nicht der Fall ist, fügen Sie rekursiv eine hinzu, um das erste Zeichen zu entfernen und die Stockwerksnummer basierend auf diesem Zeichen zu aktualisieren.

xnor
quelle
2

Javascript, 57 Bytes

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

Ziemlich einfach, iteriert nur über die Eingabe, incs if '(' decs if ')'. Gibt beim ersten Negativ zurück.

SethWhite
quelle
2

Ruby, 47 Bytes

Anonyme Funktion.

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

C 73 Bytes

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

Erwartet die Eingabe von STDIN; Keine anderen Zeichen als (und) in der Eingabe erscheinen (zumindest bis wir die Antwort erreicht haben). Die Eingabe muss ASCII sein.

Gibt die Antwort auf STDOUT aus.

Verwendet die 1-Bit-Differenz zwischen ASCII für (und ).

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

Schön formatierte Version:

David Morris
quelle
Können Sie das f=c=0in die Initialisierung der Schleife verschieben for(f=c=0;f!=..., um ein Byte zu speichern?
AdmBorkBork
@TimmyD macht sie besser global, damit sie automatisch initialisiert werden.
Cole Cameron
1

PowerShell, 75 65 62 Byte

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

Verwendet eine ähnliche Technik wie auf Parenthifiable Binärzahlen in einer Schleife durch alle Eingabezeichen, ein Laufen zu halten $counter von +1für jeden (und -1für jeden) , dann testen , ob wir negativ getroffen haben (dh, wir sind im Keller).

Bearbeiten - Speichert 10 Bytes, indem die tatsächlichen Zeichen und nicht deren Indizes durchlaufen werden.
Bearbeiten 2 - Speichert 3 zusätzliche Bytes, indem die Gleichheitsprüfung gegen Modulo ausgetauscht wird, sodass das Casting implizit erfolgt

AdmBorkBork
quelle
1

Mathematica, 62-55 Bytes

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

Alle langen Funktionsnamen! Funktioniert ähnlich wie die CJam-Antwort von Simmons.

LegionMammal978
quelle
1

Befunge 25 Bytes

Ausgänge in unary. Dies startet Sie im ersten Stock und geht bis 0.

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

Schläger (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)))))
Sylwester
quelle
1

APL, 18 Zeichen

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

Auf Englisch:

  • ¯1*')'=⍵: -1 wobei input = ")", andernfalls 1;
  • +\: laufende Summe;
  • 1⍳⍨¯1=: finde den Index des ersten -1.
lstefano
quelle
1

Lua, 92 89 87 Bytes

Es wird ein Befehlszeilenargument benötigt.

Bearbeiten: 3 Bytes gespeichert

Bearbeiten: 2 Bytes gespeichert und ein Fehler behoben, der in Randfällen auftreten konnte, wird jetzt über den Exit-Code ausgegeben

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)
Katenkyo
quelle
1

k / kona , 23 21 Bytes

Durch Entfernen unnötiger Klammern werden 2 Byte gespart.

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

Verwendung:

k){1+(+\1 -1"()"?x)?-1} "())"
3
Simon Major
quelle
0

Perl, 40 + 1 = 41 Bytes

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

Benötigt die -pFlagge:

$ 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

Nimmt eine gültige Eingabe an.

Wie es funktioniert:

                                           # -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
undlrc
quelle
0

Javascript (ES6), 68 67 Bytes

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

Übernimmt die Eingabe als erstes Argument

Erläuterung

(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
reubn
quelle
0

Python (3.5), 78 71 62 Bytes

eine rekursive Lösung

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

es ist ähnlich wie diese Lösung für Minigolf

Wir können davon ausgehen, dass der Weihnachtsmann immer den Keller erreicht

Erwan
quelle