¿Cuándo entra Santa en el sótano? (AOC Día 1)

20

Estoy reproduciendo la segunda parte del primer día de Adviento de Código, con permiso del creador.

Santa está tratando de entregar regalos en un gran edificio de apartamentos, pero no puede encontrar el piso correcto; las instrucciones que recibió son un poco confusas. Comienza en la planta baja (planta 0) y luego sigue las instrucciones de un personaje a la vez.

Un paréntesis de apertura (significa que debe subir un piso y un paréntesis de cierre )significa que debe bajar un piso.

El edificio de apartamentos es muy alto y el sótano es muy profundo; nunca encontrará los pisos superiores o inferiores.

Dado un conjunto de instrucciones, encuentre la posición del primer personaje que lo hace entrar al sótano (piso -1).

Como ejemplos:

la entrada )hace que ingrese al sótano en la posición de personaje 1.

la entrada ()())hace que ingrese al sótano en la posición 5 del personaje.

Aquí se proporciona una entrada larga que debería dar la solución 1797.

Este es el código de golf, por lo que gana la solución más corta.

Un simmons
fuente
¿Tenemos que usar esos caracteres exactos?
Azul
1
@muddyfish En los desafíos originales, las entradas se daban de forma específica y, con frecuencia, una parte clave del desafío era analizar las entradas; Si bien no quiero que esto se convierta en un "problema de camaleón", creo que el espíritu del original es que la entrada debe ser una cadena de paréntesis. Me doy cuenta de que esto privilegia algunos idiomas sobre otros, pero pediría a los votantes que lo tengan en cuenta al otorgar votos a las soluciones.
Un Simmons
Muy estrechamente relacionado con los números binarios Parenthifiable ... No me siento lo suficientemente fuerte como para que sea un engaño, así que solo dejaré un comentario.
AdmBorkBork
@TimmyD ¡Entiendo lo que quieres decir, pero creo que esta pregunta es lo suficientemente diferente como para que las respuestas competitivas no puedan extraer demasiado de esa pregunta!
Un Simmons
1
Estoy tratando de resolver esto en SMBF (básicamente BF), y este lenguaje apesta a depurar ... ugh.
mbomb007

Respuestas:

17

Jalea, 8 7 bytes

O-*+\i-

¡Gracias a @ Sp3000 por jugar golf en 1 byte!

Pruébalo en línea!

Cómo funciona

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
fuente
16

Python 2, 44 bytes

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

Hallvabo, xsot, mitchs y whatisgolf encontraron esta solución inteligente en este problema en Anarchy golf . Si alguno de ustedes quiere publicarlo, lo eliminaré.

El truco es dejar que el analizador de Python haga el trabajo. La función input()intenta evaluar una cadena de entrada y arroja un error en el primer par sin emparejar. Este error, cuando se detecta, tiene forma

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

que incluye el número de carácter donde se produjo el error.

xnor
fuente
7

Python, 79 77 bytes

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

Probablemente haya una mejor manera de hacer esto, pero no tengo ideas. También esta es mi primera publicación en codegolf.

Gracias a @Erwan. para jugar golf en 2 bytes.

drobilc
fuente
Bienvenido al sitio! Esta es una muy buena primera publicación. :)
Alex A.
puede reemplazar [0:g]por[:g]
Erwan
y esta sustitución ahorro 1 bytes creo -2*ord(z)+81por2*(z<')')-1
Erwan
5

Pitón 3, 59

Guardado 3 bytes gracias a grc.

Realmente no me gusta hacer indexación manual de cadenas en Python. Se siente tan mal.

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

C, 55 bytes

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

Pruébalo aquí .

Editar: No estoy seguro de por qué dejé una variable no utilizada allí ...

Cole Cameron
fuente
5

CJam, 10 bytes

0l'_*:~1#)

o

0l'_*~]1#)

o (créditos a Dennis)

Wl+'_*:~1#

Pruébalo aquí.

Explicación

Como A Simmons ya señaló, ()es una elección afortunada para CJam ya que esos son los operadores de decremento / incremento, respectivamente. Eso significa que si comenzamos desde cero, estamos buscando el paso en el que Santa llega al piso 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.
Martin Ender
fuente
4

Laberinto , 18 bytes

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

Pruébalo en línea! Esta respuesta fue el resultado de colaborar con @ MartinBüttner.

Explicación

La cartilla habitual de Labyrinth (digo "usual", pero en realidad lo reescribo cada vez):

  • Labyrinth es un lenguaje 2D basado en pila, cuya ejecución comienza desde el primer carácter válido (aquí arriba a la izquierda). En cada cruce, donde hay dos o más rutas posibles para que el puntero de instrucción tome, la parte superior de la pila se verifica para determinar a dónde ir después. Negativo es girar a la izquierda, cero es avanzar y positivo es girar a la derecha.
  • La pila no tiene fondo y está llena de ceros, por lo que saltar de una pila vacía no es un error.
  • Los dígitos en el código fuente no empujan el número correspondiente; en su lugar, resaltan la parte superior de la pila y empujan n*10 + <digit>. Esto permite la acumulación fácil de grandes números. Para comenzar un nuevo número, use _, que empuja a cero.

Este código es un poco extraño ya que, para fines de golf, el bucle principal combina dos tareas en una. Para la primera mitad de la primera pasada, esto es lo que sucede:

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

Ahora que la pila se ha inicializado con un -1 en la parte superior, puede comenzar el procesamiento real. Esto es lo que hace el bucle principal.

,               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

El último duplicado agrega un elemento a la pila para cada iteración que realizamos. Esto es importante porque, cuando llegamos a cero y avanzamos en el NOP, hacemos:

#               Push stack depth
(               Decrement
!               Output as num
@               Terminate
Sp3000
fuente
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;

Sin golf

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
fuente
3

retina ,22 21

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

Pruébelo en línea o pruebe el gran caso de prueba. (La URL es grande para el caso de prueba grande, avíseme si se rompe para usted, parece estar bien en Chrome).

¡1 byte guardado gracias a Martin!

Hacemos coincidir el primer conjunto de paréntesis equilibrados y lo extraemos, luego contamos el número de veces que la cadena vacía coincidirá con ese resultado. No estoy seguro de si esta es la mejor manera de hacer esto en Retina, particularmente si el modo PCRE lo hace más corto, pero usar el $#_reemplazo parece ser más largo debido a errores de apagado y el problema de tener más de una coincidencia.

Este algoritmo causa un comportamiento extraño para la entrada inválida, esencialmente supone que si Santa no llega al sótano, se teletransporta misteriosamente allí después de los otros movimientos.

FryAmTheEggman
fuente
3

Grep + AWK, 51 bytes

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

El grepcomando coloca a cada personaje en una nueva línea.

Robert Benson
fuente
3

Pyth, 13 bytes

f!hsm^_1Cd<zT

Explicación

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

Pruébalo aquí

Algoritmo antiguo, 15 bytes

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

Explicación:

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

Pruébalo aquí

O si se le permite usar caracteres que no sean (y ), 9 bytes (mover el preprocesamiento a la entrada)

f!.v+<zT1

Explicación

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

Pruébalo aquí

Azul
fuente
3

JavaScript (ES6), 58 bytes

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

Funciona eliminando recursivamente un par de ()s coincidentes hasta que el primer carácter sea a ). Advertencia: no intente esto en cadenas que no tienen suficiente )s. Ejemplo:

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

En este punto, ve que se eliminaron 12 caracteres en total, por lo que la respuesta es 13.

Neil
fuente
Podría poner ese comentario en su respuesta en su lugar.
mbomb007
3

MATL , 12 11 bytes

1 byte guardado usando la idea de Dennis de computar -1 elevado a la cadena de entrada

1_j^Ys0<f1)

Pruébalo en línea!

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
fuente
2

CJam, 12 10 Bytes

0q{~_}%1#)

Pruébalo aquí

Dos bytes guardados gracias a Martin.

Explicación:

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
Un simmons
fuente
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++;}

Ignora a otros personajes. Usos prompty alert.

Solomon Ucko
fuente
2

Perl, 34 + 1 = 35 bytes

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

Gracias a Dennis por algunos consejos.

Corre con la -pbandera. Funciona en Perl 5.10, pero las versiones posteriores necesitan un espacio aquí:++ while

Versión más antigua y sin golf:

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

Python, 44 bytes

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

El piso icomienza en 1para que terminemos isiendo el valor falsey 0. Si no se termina, agregue recursivamente uno al resultado con el primer carácter eliminado y el número de piso actualizado en función de ese carácter.

xnor
fuente
2

Javascript, 57 bytes

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

Bastante simple, solo itera sobre la entrada, incs if '(' decs if ')'. Retornos en primer negativo.

SethBlanco
fuente
2

Ruby, 47 bytes

Función anónima.

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

C, 73 bytes

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

Espera entrada en STDIN; no pueden aparecer caracteres distintos de (y )en la entrada (al menos hasta que hayamos alcanzado la respuesta). La entrada debe ser ASCII.

Emite la respuesta en STDOUT.

Utiliza la diferencia de 1 bit entre el ASCII para (y ).

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

Versión bien formateada:

David Morris
fuente
¿Se puede mover f=c=0a la inicialización del bucle for(f=c=0;f!=...para guardar un byte?
AdmBorkBork
@TimmyD es mejor hacerlos globales para que se inicialicen automáticamente.
Cole Cameron
1

PowerShell, 75 65 62 bytes

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

Utiliza una técnica similar a la de los números binarios Parenthifiable para recorrer todos los caracteres de entrada, manteniendo una $conza de +1cada uno (y -1para cada uno ), luego prueba si hemos dado negativo (es decir, estamos en el sótano).

Editar - salvado 10 bytes por iteración sobre los personajes reales en lugar de sus índices
Edición 2 - salvó 3 bytes adicionales mediante el canje de verificación de la igualdad para la fundición de módulo de manera implícita

AdmBorkBork
fuente
1

Mathematica, 62 55 bytes

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

¡Todos los nombres largos de funciones! Funciona de manera similar a la respuesta CJam de Simmons.

LegionMammal978
fuente
1

Befunge 25 bytes

Salidas en unario. Esto lo iniciará en el piso uno y continuará hasta 0.

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

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

Sin golf

(λ (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
fuente
1

APL, 18 caracteres

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

En inglés:

  • ¯1*')'=⍵: -1 donde input = ")", 1 de lo contrario;
  • +\: suma corriente;
  • 1⍳⍨¯1=: encuentra el índice del primer -1.
lstefano
fuente
1

Lua, 92 89 87 bytes

Toma un argumento de línea de comandos.

Editar: Guardado 3 Bytes

Editar: guardó 2 bytes y corrigió un error que podría ocurrir en casos extremos, ahora sale a través de su código de salida

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

Sin golf

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
fuente
1

k / kona , 23 21 bytes

2 bytes guardados eliminando paréntesis innecesarios.

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

Uso:

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

Perl, 40 + 1 = 41 bytes

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

Requiere la -pbandera:

$ 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

Asume una entrada válida.

Cómo funciona:

                                           # -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
andlrc
fuente
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

Toma entrada como primer argumento

Explicación

(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
fuente
0

Python (3.5), 78 71 62 bytes

una solución recursiva

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

es similar a esta solución para mini golf

podemos suponer que santa siempre llega al sótano

Erwan
fuente