Quando Babbo Natale entra nel seminterrato? (AOC Giorno 1)


20

Sto riproducendo la seconda parte del primo giorno di Advent of Code, con il permesso del creatore.

Babbo Natale sta cercando di consegnare regali in un grande condominio, ma non riesce a trovare il piano giusto: le indicazioni che ha ottenuto sono un po 'confuse. Comincia al piano terra (piano 0) e quindi segue le istruzioni un personaggio alla volta.

Una parentesi aperta (, significa che dovrebbe salire di un piano, e una parentesi chiusa ), che dovrebbe scendere di un piano.

Il condominio è molto alto e il seminterrato è molto profondo; non troverà mai i piani superiori o inferiori.

Dato un set di istruzioni, trova la posizione del primo personaggio che lo fa entrare nel seminterrato (piano -1).

Come esempi:

l'ingresso gli )fa entrare nel seminterrato nella posizione 1 del personaggio.

l'ingresso gli ()())fa entrare nel seminterrato nella posizione 5 del personaggio.

Una lunga ingresso viene data qui che dovrebbe produrre la soluzione 1797.

Questo è il golf del codice, quindi vince la soluzione più breve!


Dobbiamo usare quei caratteri esatti?
Blu,

1
@muddyfish Nelle sfide originali gli input venivano dati in una forma specifica e così spesso una parte chiave della sfida era l'analisi degli input; mentre non voglio che questo diventi un "problema camaleontico", penso che lo spirito dell'originale sia che l'input dovrebbe essere una stringa di parentesi. Mi rendo conto che questo privilegia alcune lingue rispetto ad altre, ma vorrei invitare gli elettori a tenerne conto quando assegnano i voti alle soluzioni.
A Simmons,

Molto strettamente correlato ai numeri binari Parenthifiable ... Non mi sento abbastanza forte da essere un duplicato, quindi lascerò un commento.
AdmBorkBork,

@TimmyD Capisco cosa intendi, ma sento che questa domanda è abbastanza diversa che le risposte della concorrenza non saranno in grado di trarre troppo da quella domanda!
A Simmons,

1
Sto provando a risolverlo in SMBF (fondamentalmente BF), e questo linguaggio fa SUCCHI di debug ... ugh.
mbomb007,

Risposte:


17

Gelatina, 8 7 byte

O-*+\i-

Grazie a @ Sp3000 per giocare a golf a 1 byte!

Provalo online!

Come funziona

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 byte

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

Questa soluzione intelligente è stata trovata da hallvabo, xsot, mitchs e whatisgolf su questo problema nel golf di Anarchy . Se invece qualcuno di voi desidera pubblicarlo, lo rimuoverò.

Il trucco è lasciare che il parser di Python faccia il lavoro. La funzione input()tenta di valutare una stringa di input e genera un errore sulla prima parentesi senza pari. Questo errore, quando rilevato, ha forma

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

che include il numero di carattere in cui si è verificato l'errore.


7

Python, 79 77 byte

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

Probabilmente esiste un modo migliore per farlo, ma sono senza idee. Anche questo è il mio primo post su codegolf.

Grazie a @Erwan. per giocare a golf fuori 2 byte.


Benvenuti nel sito! Questo è un bel primo post. :)
Alex A.

puoi sostituirlo [0:g]con[:g]
Erwan,

e questa sostituzione Salva 1 byte penso -2*ord(z)+81da2*(z<')')-1
Erwan

5

Python 3, 59

Salvato 3 byte grazie a grc.

Non mi piace molto fare l'indicizzazione manuale delle stringhe in Python. Sembra così sbagliato.

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

5

C, 55 byte

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

Provalo qui .

Modifica: non sono sicuro del motivo per cui ho lasciato una variabile inutilizzata lì dentro ...


5

CJam, 10 byte

0l'_*:~1#)

o

0l'_*~]1#)

o (crediti a Dennis)

Wl+'_*:~1#

Provalo qui.

Spiegazione

Come già notato da A Simmons, ()è una scelta fortunata per CJam poiché questi sono rispettivamente gli operatori di decremento / incremento. Ciò significa che se stiamo iniziando da zero stiamo cercando il passaggio in cui Babbo Natale raggiunge il primo piano.

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

Labirinto , 18 byte

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

Provalo online! Questa risposta è stata il risultato della collaborazione con @ MartinBüttner.

Spiegazione

Il solito primer Labyrinth (dico "solito", ma in realtà lo riscrivo ogni volta):

  • Labyrinth è un linguaggio 2D basato su stack, con esecuzione che inizia dal primo carattere valido (qui in alto a sinistra). Ad ogni incrocio, dove ci sono due o più possibili percorsi che il puntatore dell'istruzione deve prendere, la parte superiore dello stack viene controllata per determinare dove andare dopo. Il negativo è girare a sinistra, zero è andare avanti e il positivo è girare a destra.
  • Lo stack è senza fondo e pieno di zeri, quindi spuntare da uno stack vuoto non è un errore.
  • Le cifre nel codice sorgente non inviano il numero corrispondente, ma fanno apparire la parte superiore dello stack e spingono n*10 + <digit>. Ciò consente di creare facilmente grandi numeri. Per iniziare un nuovo numero, utilizzare _, che spinge zero.

Questo codice è un po 'strano poiché, a fini di golf, il ciclo principale combina due attività in una. Per la prima metà del primo passaggio, ecco cosa succede:

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

Ora che lo stack è stato inizializzato con un -1 in cima, l'elaborazione effettiva può iniziare. Ecco cosa fa il ciclo principale.

,               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

L'ultimo duplicato aggiunge un elemento allo stack per ogni iterazione che eseguiamo. Questo è importante perché, quando colpiamo zero e andiamo avanti al NOP, facciamo:

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

3

Oracle SQL 11.2, 160 159 byte

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

Provalo online o prova il grande test case. (L'URL è grande per il grande caso di test, fammi sapere se si rompe per te, sembra OK in Chrome.)

1 byte salvato grazie a Martin!

Abbiniamo il primo set di parentesi bilanciate e lo estraiamo, quindi contiamo il numero di volte in cui la stringa vuota corrisponderà a quel risultato. Non sono sicuro se questo è il modo migliore per farlo in Retina, in particolare se la modalità PCRE lo rende più breve, ma l'uso della $#_sostituzione sembra essere più lungo a causa di uno di errori e del problema di avere più di una partita.

Questo algoritmo provoca un comportamento strano per input non validi, presuppone essenzialmente che se Babbo Natale non arriva al seminterrato, si teletrasporta misteriosamente lì dopo gli altri movimenti.



3

Grep + AWK, 51 byte

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

Il grepcomando posiziona ogni personaggio su una nuova riga.


3

Pyth, 13 byte

f!hsm^_1Cd<zT

Spiegazione

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

Provalo qui

Vecchio algoritmo, 15 byte

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

Spiegazione:

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

Provalo qui

Oppure, se è consentito utilizzare caratteri diversi da (e ), 9 byte (spostamento della pre-elaborazione nell'input)

f!.v+<zT1

Spiegazione

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

Provalo qui


3

JavaScript (ES6), 58 byte

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

Funziona rimuovendo ricorsivamente una coppia di ()s corrispondenti fino a quando il primo carattere è a ). Avviso: non provarlo su stringhe che non ne hanno abbastanza) s. Esempio:

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

A questo punto vede che 12 caratteri sono stati eliminati in totale in modo che la risposta sia 13.


Puoi invece inserire quel commento nella tua risposta.
mbomb007,

3

MATL , 12 11 byte

1 byte salvato usando l'idea di Dennis di calcolare -1 elevata alla stringa di input

1_j^Ys0<f1)

Provalo 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

2

CJam, 12 10 byte

0q{~_}%1#)

Provalo qui.

Due byte salvati grazie a Martin.

Spiegazione:

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 byte

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

Ignora altri personaggi. Usi prompte alert.


2

Perl, 34 + 1 = 35 byte

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

Grazie a Dennis per alcuni suggerimenti.

Corri con la -pbandiera. Funziona in Perl 5.10, ma le versioni successive richiedono uno spazio qui:++ while

Versione precedente, non convertita:

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

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

Il piano iinizia in 1modo da terminare con iil valore di falso 0. Se non terminato, aggiungilo ricorsivamente per ottenere il primo carattere rimosso e il numero del piano aggiornato in base a quel personaggio.


2

Javascript, 57 byte

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

Abbastanza semplice, scorre solo sull'input, incs if '(' decs if ')'. Restituisce il primo negativo.


2

Rubino, 47 byte

Funzione anonima.

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

1

C, 73 byte

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

Si aspetta input su STDIN; nessun carattere diverso da (e )può apparire nell'input (almeno fino a quando non abbiamo raggiunto la risposta). L'ingresso deve essere ASCII.

Emette la risposta su STDOUT.

Utilizza la differenza di 1 bit tra ASCII per (e ).

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

Versione ben formattata:


Puoi spostare l' f=c=0inizializzazione del loop for(f=c=0;f!=...per salvare un byte?
AdmBorkBork,

@TimmyD è meglio renderli globali in modo che vengano inizializzati automaticamente.
Cole Cameron,

1

PowerShell, 75 65 62 byte

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

Utilizza una tecnica simile a quella dei numeri binari Parenthifiable per scorrere tutti i caratteri di input, mantenendo un $ccacciatore funzionante +1per ciascuno (e -1per ciascuno ), quindi verificando se abbiamo colpito il negativo (cioè, siamo nel seminterrato).

Modifica: salvati 10 byte ripetendo i caratteri effettivi anziché i loro indici
Modifica 2: salvati 3 byte aggiuntivi scambiando il controllo di uguaglianza per modulo, quindi il cast è implicito


1

Mathematica, 62 55 byte

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

Tutti i nomi delle funzioni lunghe! Funziona in modo simile alla risposta CJam di Simmons.


1

Befunge 25 byte

Uscite in unario. Questo ti avvia al primo piano e andrà fino a 0.

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

1

Racchetta (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 caratteri

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

In inglese:

  • ¯1*')'=⍵: -1 dove input = ")", 1 altrimenti;
  • +\: somma corrente;
  • 1⍳⍨¯1=: trova l'indice del primo -1.

1

Lua, 92 89 87 byte

Accetta un argomento da riga di comando.

Modifica: 3 byte salvati

Modifica: salvato 2 byte e corretto un bug che potrebbe verificarsi in casi limite, ora viene emesso tramite il suo codice di uscita

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 byte

2 byte salvati rimuovendo le parentesi non necessarie.

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

Uso:

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

0

Perl, 40 + 1 = 41 byte

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

Richiede la -pbandiera:

$ 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

Presuppone input validi.

Come funziona:

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

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

Accetta input come primo argomento

Spiegazione

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

una soluzione ricorsiva

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

è simile a questo soluzione per il mini golf

possiamo supporre che Babbo Natale raggiunga sempre il seminterrato

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.