Terminar paréntesis perezosos

17

Los paréntesis en mi teclado están desgastados y quiero evitar usarlos tanto como sea posible. Su desafío es equilibrar una línea que contiene paréntesis agregándolos antes y después de cada línea.

Esto es similar a los paréntesis automáticos y al cierre de cadena de TI-Basic (es decir Output(1, 1, "Hello, World!). ¡También ahorra bytes preciosos de un programa!

Entrada de ejemplo:

This line has no parentheses
alert(Math.max(1, 2
1+1)*2).toString()
function() { alert('Hello, World!'); })(

Ejemplo (posible) de salida:

This line has no parentheses
alert(Math.max(1, 2))
((1+1)*2).toString()
(function() { alert('Hello, World!'); })()

Especificación:

  • Para cada línea de entrada,

    • Agregue tantos paréntesis abiertos al principio y cierre los paréntesis al final de la línea como sea necesario para equilibrar los paréntesis en la línea

      • La definición de "equilibrio" es:

        • La misma cantidad de (y )en la línea

        • Para cada subcadena que comienza desde el principio de la cadena, esta subcadena no debe tener más paréntesis de cierre que paréntesis de apertura

          • Por ejemplo, (foo))(barno está equilibrado porque (foo))tiene más paréntesis de cierre que paréntesis de apertura
    • Puede agregar paréntesis innecesarios adicionales si lo desea, si acorta su código

    • No necesita preocuparse por los literales de cadena ni nada de eso, suponga que todos los paréntesis necesitan equilibrio

  • Salida de cada línea con paréntesis balanceados

Este es el , por lo que el código más corto en bytes ganará.

Pomo de la puerta
fuente
¿Usted apenas está preocupado con ()parens, o hacer otros soportes {}, [], <>, etc necesidad de tener en cuenta también?
Trauma digital
@ Digital Trauma No, solo (y ).
Pomo de la puerta
¿Tienes algún caso de prueba?
Peter Taylor
1
@Peter Sí, están ahí en el post ...
Pomo

Respuestas:

21

GolfScript, 23 bytes

n/{"()"1/{.2$\-,*}%*n}/

La escapatoria que estoy explotando es la decisión de que:

Puede agregar paréntesis innecesarios adicionales si lo desea, si acorta su código

Básicamente, para cada línea, este código cuenta el número de caracteres en la línea que no están entre paréntesis de apertura, y antepone esa cantidad de paréntesis de apertura adicionales a la línea, y luego hace lo mismo para cerrar los paréntesis. Esto es increíblemente ineficiente, pero asegura que todos los paréntesis en la línea de salida estén equilibrados.

Por ejemplo, dada la entrada:

This line has no parentheses
alert(Math.max(1, 2
1+1)*2).toString()
function() { alert('Hello, World!'); })(

este programa generará:

((((((((((((((((((((((((((((This line has no parentheses))))))))))))))))))))))))))))
(((((((((((((((((alert(Math.max(1, 2)))))))))))))))))))
(((((((((((((((((1+1)*2).toString())))))))))))))))
(((((((((((((((((((((((((((((((((((((function() { alert('Hello, World!'); })()))))))))))))))))))))))))))))))))))))

PD. También puede probar este código en línea .

Ilmari Karonen
fuente
44
Esto me recuerda cuando solía programar en Lisp ... Algunos bits de código perdidos en un mar de paréntesis.
Taconut
7

Perl, 32 = 31 + 1 o 73 = 72 + 1 (paréntesis minimizados)

32 = 31 + 1: con paréntesis innecesarios adicionales

Ediciones:

  • Solución, los paréntesis ahora cuentan y///.
  • Variable innecesaria $aeliminada.
$_="("x y/)//.s|$|")"x y/(//|er

Se usa con el interruptor de tiempo de ejecución -p(+1 byte).

Archivo de prueba input.txt:

This line has no parentheses
alert(Math.max(1, 2
1+1)*2).toString()
function() { alert('Hello, World!'); })(
(foo))(bar
)))(((
((
))

Línea de comando:

perl -p script.pl <input.txt

o

perl -pe '$_="("x y/)//.s|$|")"x y/(//|er' <input.txt

Resultado:

This line has no parentheses
alert(Math.max(1, 2))
(((1+1)*2).toString())
(((function() { alert('Hello, World!'); })()))
(((foo))(bar))
((()))((()))
(())
(())

Sin golf:

El algoritmo es simple, solo agregue la contraparte para cada paréntesis encontrado.

$_ =                     # $_ is provided as input by switch `-p` and
                         # it is printed afterwards as output.
                         # y/X// is used to count the character 'X' in $_
    '(' x y/)//          # add opening parentheses for each closing parentheses
    . s|$|')' x y/(//|er # go right before the end of line and insert
                         # closing parentheses for each opening parentheses
                         # in the original string

73 = 72 + 1: agregar un número mínimo de paréntesis

Este script solo agrega el número mínimo de paréntesis para obtener un resultado equilibrado.

$a=y/()//cdr;1while$a=~s/\(\)//g;$_=$a=~y/)(/(/dr.$_;s|$|$a=~y/()/)/dr|e

Se usa con el interruptor de tiempo de ejecución -p(+1 byte).

perl -pe "$a=y/()//cdr;1while$a=~s/\(\)//g;$_=$a=~y/)(/(/dr.$_;s|$|$a=~y/()/)/dr|e" <input.txt

Resultado:

This line has no parentheses
alert(Math.max(1, 2))
((1+1)*2).toString()
(function() { alert('Hello, World!'); })()
((foo))(bar)
((()))((()))
(())
(())

Sin golf:

$a = y/()//cdr;            # filter parentheses and store in $a
1 while $a =~ s/\(\)//g;   # remove matching parentheses
$_ = $a =~ y/)(/(/dr . $_; # add missing opening parentheses at start of string
s|$|$a=~y/()/)/dr|e        # insert missing closing parentheses at end of string

81 = 80 + 1: agregar un número mínimo de paréntesis

Este es un método antiguo para agregar el número mínimo de paréntesis para una salida balanceada.

my($l,$r);s/[()]/($&eq")"&&($r&&$r--||++$l))||$r++/ger;$_="("x$l.$_;s/$/")"x$r/e

Utiliza Perl 5.14 (debido al modificador de sustitución no destructivo) y el interruptor de tiempo de ejecución -p(+1 byte).

perl -p script.pl <input.txt

Resultado:

This line has no parentheses
alert(Math.max(1, 2))
((1+1)*2).toString()
(function() { alert('Hello, World!'); })()
((foo))(bar)
((()))((()))
(())
(())

Sin golf:

# The while loop is added by option "-p".
LINE:
while (<>) {

    # $_ contains the current line
    my ($l, $r); # initializes $l and $r (to undef/kind of indirect 0)
    # Modifiers for the following substitution of $_:
    # /g: process all parentheses
    # /e: evaluate code
    # /r: does not change the original input string $_ (Perl 5.14)
    s/[()]/
        # $& contains the matched parentheses
        # $r is a balance level counter; at the end $r contains
        #    the number of needed closing parentheses
        # $l is the number of needed opening parentheses;
        #    if $r would go negative, then an opening parentheses
        #    is missing and $l is increases and $r remains zero.
        (  
            $& eq ")" &&   # case ")"
            ($r && $r--    # close a parentheses group and update balance counter
                || ++$l)   # or update $l if an opening parentheses is needed
        )
        || $r++            # case "(": increase balance counter
    /ger;
    $_ = "(" x $l . $_;    # add opening parentheses at the begin of line
    s/$/")" x $r/e         # add closing parentheses before the line end

# the remainder is added by run-time switch "-p"
} continue {
    print or die "-p destination: $!\n";
}
Heiko Oberdiek
fuente
2
Wow, eso casi parece golfscript ;-)
Digital Trauma
@HeikoOberdiek ¿Qué perl estás usando para la primera versión? No parece funcionar en 18.1 debido a que '('x/\)/gsiempre es igual a '(' ...
Mouq
@Mouq: Gracias, arreglado ahora usando en y///lugar de m//gcontar los paréntesis.
Heiko Oberdiek
4

Python 2.7 3: 62 60 58 bytes

while 1:s=input();c=s.count;print('('*c(')')+s+')'*c('('))

No super golf, pero ya sabes. Es posible que pueda exprimir algunos bytes más si realmente lo intento.

Para cada línea, salidas (* el número de) en la línea, luego la línea, luego )* el número de (en la línea. Si entiendo las reglas correctamente, esto siempre proporcionará una salida válida.

Sale lanzando una excepción, como resultado de la forma en que ingresé. (La entrada es siempre una parte difícil de estos problemas). Si esto no es aceptable, me costará unos pocos bytes solucionarlo, aunque todavía no estoy seguro de cuántos.

Salida de ejemplo:

This line has no parentheses
alert(Math.max(1, 2))
(((1+1)*2).toString())
(((function() { alert('Hello, World!'); })()))
metro subterráneo
fuente
Esto no parece tomar entrada de varias líneas, es decir, las impresiones se intercalan con líneas de entrada. Pero buena idea de algoritmo, no pensé en eso;)
Pomo de la puerta
python2 balanced_parenthesis.py < input.txt 2>/dev/nullobtiene el resultado que escribí, pero si desea una entrada de varias líneas mientras lo hace de forma interactiva, me costará unos pocos bytes. Dame un segundo, resolveré algo ...
undergroundmonorail
Ah, está bien, no importa entonces. ¡Que funcionará!
Pomo de la puerta
guardar 2 caracteres:while 1:s=raw_input();c=s.count;print'('*c(')')+s+')'*c('(')
Justin
@qui Oh, wow. Estuve tan cerca de descubrirlo, pero no me di cuenta de que podías hacerlo c=s.count. Pensé que tenía que hacer c=s, s.c(). ¡Gracias!
undergroundmonorail
1

Pure Bash, 72 bytes

Utiliza el mismo algoritmo que la respuesta de @ undergroundmonorail:

while read a;do
o=${a//[!(]}
c=${a//[!)]}
echo ${c//)/(}$a${o//(/)}
done

Salida:

$ ./lazyparens.sh < input.txt
This line has no parentheses
alert(Math.max(1, 2))
(((1+1)*2).toString())
(((function() { alert('Hello, World!'); })()))
$ 
Trauma digital
fuente