Distribuyendo Números

11

En este desafío, estará utilizando distribuir un producto sobre sumas y diferencias de números, como se explica aquí .

ingrese la descripción de la imagen aquí

Ejemplos

  Input      |     Output
-------------|-------------
23(12+42)    | (23*12)+(23*42)
9(62-5)      | (9*62)-(9*5)
4(17+8-14)   | (4*17)+(4*8)-(4*14)
15(-5)       | -(15*5)
2(3)         | (2*3)
8(+18)       | +(8*18)
8(-40+18)    | -(8*40)+(8*18)

Especificación

La entrada será una cadena de la forma n(_), con un solo entero positivo sin signo nseguido de una expresión entre paréntesis _. Esta expresión _consistirá en sumas y diferencia de uno o más términos enteros positivos separados por signos +y -. El primer término puede estar precedido por un +signo, un -signo o por ningún signo.

En la salida, el número inicial ndebe distribuirse para multiplicar cada uno de los términos. Cada término de adebe multiplicarse na la izquierda por para producir la expresión entre paréntesis (n*a), y estos nuevos términos deben combinarse con +y -signos exactamente de la misma manera que los términos originales.

Entradas inválidas

Estos son ejemplos de entradas que no tiene que manejar.

3(5 plus 3)
6(5 13)
(5+8)(6+6)
(5+3)8

Victorioso

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

Downgoat
fuente
Se me ocurre que la expresión regular es realmente adecuada para este problema. Si no está de acuerdo con las soluciones reg-ex, puede prohibirlo, aunque es posible que la gente ya esté trabajando en ello.
xnor
¿Se permiten bibliotecas?
orlp
@orlp Hasta cierto punto, lo que se discutió en meta .
Downgoat
Caso interesante:8(-40+18)
BrainSteel

Respuestas:

2

Pip, 28 bytes

DQaUnxWa^'(xR`\d+`'(.n.`*&)`

Explicación:

                              a is first cmdline arg (implicit)
DQa                           Remove (DeQueue) the closing paren from a
   UnxWa^'(                   Unify n and x with a split on open paren--Python equivalent
                                n,x=a.split("(")
                              n is thus the number to be distributed, and x is the
                                addition/subtraction expression
           xR                 In x, replace...
             `\d+`            ... regex matching numbers...
                  '(.n.`*&)`  ... with the replacement pattern (n*&), where n is the
                                appropriate number and & substitutes the complete match
                              Print result (implicit)

Los objetos de Patrón de Pip siguen principalmente la sintaxis de expresiones regulares de Python, pero el &patrón de reemplazo se toma prestado de sed.

Lea más sobre Pip en el repositorio de Github

DLosc
fuente
9

JavaScript 65 bytes

s=>(q=s.split(/[()]/))[1].replace(/(\D?)(\d+)/g,`$1(${q[0]}*$2)`)

Esto tomará la entrada. Obtenga el + o -, luego los dígitos, luego reemplácelos en el orden correcto.

Explicación

s=>   // Function with argument "s"
  (q= // Set q to...
    s.split(/[()]/) // Splits on parenthesis, returns array
  )
  [1] // Gets second match or text inside brackets
  .replace(/ // Replaces string 
     (\D?)  // Try to match a non-digit, the +-/* (group 1)
     (\d+)  // Then match one or more digits (group 2)
  /,
      // $1 is group 1 and $2 is group 2 q[0] is the text before the parenthesis 
  `$1(${q[0]}*$2)`
  ) 

Uso

Esto solo funciona en Firefox y Safari Nightly ¿ quizás Edge? porque usa las funciones de ES6. Puedes ejecutarlo de la siguiente manera:

var t = s => (q = s.split (/ [()] /)) [1] .replace (/ (\ D?) (\ d +) / g, `$ 1 ($ {q [0]} * $ 2) `)

t ( "5 (-6 + 7 + 3-8 + 9)" ); // - (5 * 6) + (5 * 7) + (5 * 3) - (5 * 8) + (5 * 9)

fuente
(.?)(\d+)está roto. Esto falla en la 23(12+42)producción 1(23*2)+(23*42).
orlp
@orlp He solucionado eso
Este código solo funcionará en Firefox b / c de la función de flecha, pero está bien
MayorMonty
@SpeedyNinja También funciona en Edge. Para Chrome / Opera, debe habilitar las "características experimentales de JavaScript".
rink.attendant.6
\D?podría ser usado en lugar de[+-]?
edc65
6

Python 2.7, 110 108 bytes

import re
p=re.findall('([+-]?)(\d+)',raw_input())
print"".join("%s(%s*%s)"%(e[0],p[0][1],e[1])for e in p[1:])

El programa toma la entrada de stdin, busca coincidencias contra - ([+-]?)(\d+)regex y crea la cadena de salida.
Probándolo

<< 23(12+42)
>> (23*12)+(23*42)

<< 9(62-5)
>> (9*62)-(9*5)

<< 4(17+8-14)
>> (4*17)+(4*8)-(4*14)

<< 15(-5)
>> -(15*5)

<< 2(3)
>> (2*3)

<< 8(+18)
>> +(8*18)

<< 8(-40+18)
>> -(8*40)+(8*18)
Kamehameha
fuente
4

Retina , 40 bytes

+`(\d+)\((\D)?(\d+)
$2($1*$3)$1(
\d+..$
<empty line>

Cada línea debe ir a su propio archivo, pero puede ejecutar el código como un archivo con la -sbandera. P.ej:

>echo -n "8(-40+18)"|retina -s distributing_numbers
-(8*40)+(8*18)

Las primeras dos líneas empujan el multiplicador al lado de cada número en la forma esperada:

8(-40+18)
-(8*40)8(+18)
-(8*40)+(8*18)8()

Las dos últimas líneas eliminan la parte final innecesaria:

-(8*40)+(8*18)8()
-(8*40)+(8*18)
randomra
fuente
3

sed, 105 bytes

Solo quería ver si esto se puede hacer con sed.
Quizás un poco vieja escuela, pero funciona.

$ cat distnum.sed
s@\([0-9]*\)(\([0-9]*\)\([+-]*\)\([0-9]*\)\([+-]*\)\([0-9]*\))@(\1*\2)\3(\1*\4)\5(\1*\6)@
s@([0-9]*\*)@@g

$ cat distnum.txt
23(12+42)
9(62-5)
4(17+8-14)
15(-5)
2(3)
8(+18)
8(-40+18)

$ sed -f distnum.sed distnum.txt
(23*12)+(23*42)
(9*62)-(9*5)
(4*17)+(4*8)-(4*14)
-(15*5)
(2*3)
+(8*18)
-(8*40)+(8*18)
LukStorms
fuente
2

REGXY , 45 bytes

Utiliza REGXY, un lenguaje basado en la sustitución de expresiones regulares.

/(\d+)\((\D)?(\d+)/\2(\1*\3)\1(/
//
/\d+\(.//
Jarmex
fuente
¿Cómo funciona el //trabajo? Supongo que se desplaza hacia arriba hasta que la cadena cambia, pero no puedo encontrar en la página de esolang por qué.
randomra
Es un abuso un poco descarado de la vaguedad en las especificaciones del idioma, pero lo he explicado aquí: codegolf.stackexchange.com/questions/52946/…
Jarmex
1
Todavía no entiendo por qué no //crea un bucle infinito, ya nothingque siempre coincidirá, por lo que siempre volvemos a la primera línea.
randomra
¿Sabes qué? En realidad no tengo idea de por qué. Tiene toda la razón, pensarlo ahora no tiene sentido lógico, pero definitivamente compila y se ejecuta en el intérprete proporcionado. Incluso mirar el Perl compilado que genera me confunde, porque parece aún más claro que debería ser un bucle infinito: pastebin.com/9q7M0tpZ
Jarmex
2

Perl, 36 bytes

Código de 35 bytes + línea de comando de 1 byte

($a,$_)=split/[()]/;s/\d+/($a*$&)/g

Uso:

echo "4(17+8-14)" | perl -p entry.pl
Jarmex
fuente
1

Pyth, 39 38 bytes

Una terrible solución de expresiones regulares:

P:eJcz\("([+-]?)(\d+)"X"\\1(_*\\2)"3hJ
orlp
fuente
Parece que no puedo ejecutar esto en el intérprete en línea .
BrainSteel
@BrainSteel Funciona en el intérprete fuera de línea, parece ser un problema con heroku.
orlp
@orlp No es un problema con heroku. Las importaciones dinámicas están deshabilitadas en modo seguro, para reducir la probabilidad de un hack, y el módulo re realiza una importación dinámica. Por lo tanto, no se puede usar en modo seguro, incluso en línea.
isaacg
1

Ruby, 94 bytes

gets.scan(/(\d+)\(([[-+]?\d+]+)/){|a,b|b.scan(/([-+]?)(\d+)/).map{|c,d|$><<"#{c}(#{a}*#{d})"}}
JWT
fuente
1

CJam, 50 bytes

l__'(#_@<'*+@@)>);'+/'-f/\ff{1$'(@@++')+L?}'-f*'+*

Pruébalo en línea

CJam no tiene soporte para expresiones regulares, ni nada más allá de la búsqueda y división de cadenas que es muy conveniente para analizar expresiones. Entonces hay algo de trabajo involucrado aquí.

Explicación:

l__   Get input and push 2 copies for splitting.
'(#   Find index of '(.
_     Copy index, will be used twice.
@<    Get one copy of input to top, and slice to get first multiplier.
'*+   Append '* to first multiplier.
@@    Get another copy of input and '( index to top.
)>    Increment and slice to get everything after '(.
);    Remove trailing ').
'+/   Split at '+.
'-f/  Split each part at '-.
\     Swap first multiplier to top.
ff{   Apply block to nested list of second multipliers.
  1$    Copy term. Will use this copy as condition to skip empty second multipliers
        that result from unary + or -.
  '(    Opening parentheses.
  @@    Get first and second multiplier to top.
  ++    Concatenate it all.
  ')+   Concatenate closing parentheses.
  L     Push empty string for case where term is skipped.
  ?     Ternary if to pick term or empty string.
}     End of loop over list of second multipliers.
'-f*  Join sub-lists with '-.
'+*   Join list with '+.
Reto Koradi
fuente
1

gawk - 60 58

$0=gensub(/(.*\()?(+|-)?([0-9]+))?/,"\\2("$0+0"*\\3)","G")

Uf ... no he trabajado con expresiones regulares en mucho tiempo.

Cabbie407
fuente
1

Perl 5, 70 60 55 44 Bytes + 1 penalización

Una solución perl que solo usa división y 1 expresión regular.
También calcula las entradas más largas.

($a,$_)=split/[()]/;s/(\D?)(\d+)/$1($a*$2)/g

Prueba

$ echo "8(9-10+11-12+13-14)"|perl -p distnums.pl   
(8*9)-(8*10)+(8*11)-(8*12)+(8*13)-(8*14)

Una versión que toma un parámetro

($a,$_)=split/[()]/,pop;s/(\D?)(\d+)/$1($a*$2)/g;print

Una versión que solo usa expresiones regulares.

s/(\d+)\((.*)\)/$2:$1/;s/(\D?)(\d+)(?=.*:(\d+)).*?/$1($3*$2)/g;s/:.*//

Éste funciona a través de un grupo de captura dentro de una búsqueda anticipada positiva y una coincidencia perezosa. Probablemente habría usado una mirada positiva hacia atrás si Perl 5 lo admitiera, pero desgraciadamente. Me tomó un tiempo darme cuenta de que esto es posible con regex.

LukStorms
fuente
1
Hola Luk, es posible que pueda guardar algunos caracteres utilizando la -popción de línea de comando (creo que esto es +1 char vs 9 para ,<>y ;print) ya splitque funcionará $_de forma predeterminada (que será lo que sea que esté <>) y la impresión también se incluye en el bucle ! ¡Espero que ayude!
Dom Hastings
1
¡Gracias! Eso ayudo. La opción -p simplemente no pasó por mi mente. Probablemente ya que es algo que rara vez se usa fuera de un contexto de golf. ¿Por qué crees que es +1 char? Este desafío no menciona nada sobre las penalizaciones por usar interruptores.
LukStorms
No puedo encontrar la publicación ahora, pero esta meta menciona la puntuación de las banderas de Perl.
Dom Hastings
1
¡Lo malo es que se me ocurrió y publiqué una solución muy similar para usted, que en realidad es solo una versión un poco más de golf! Básicamente, ni siquiera necesita capturar el [+ -] porque de todos modos los deja intactos en la sustitución: codegolf.stackexchange.com/a/57117/26977
Jarmex
Eso es genial. Gracias a ti, Perl supera incluso las soluciones Pyth / Cjam en este desafío. De todos modos, no debería haberme preocupado por las entradas no válidas después de que esa división eliminó los corchetes.
LukStorms
1

Retina , 50 51 43 bytes

Creo que este puede ser mi primer programa de Retina. Si no, es mi primer programa Retina que es tan complejo (no tan complejo, en realidad). Cada línea va en su propio archivo.

+`(\d+)\((\D?)(\d+)
$1($'$2($1*$3)
.+?\)
$'

En realidad no probé esto con Retina, lo probé usando un probador de reemplazo de expresiones regulares varias veces, pero debería funcionar.

Descripción para el primer ejemplo:

Como hay un número par de archivos, Retina usa el modo de reemplazo. El primer reemplazo (primeros dos archivos) elimina un número que se distribuirá y agrega ese par de distribución (23*12)al final, dando 23(+42)(23*12). +`al principio le dice a Retina que reemplace repetidamente hasta que el patrón no coincida, y dado que esto coincide nuevamente, el patrón reemplaza esto con 23()(23*12)+(23*42). Esto ya no coincide, por lo que los siguientes 2 archivos se usan para el próximo reemplazo. Esta vez, simplemente elimina el 23(). Esto funciona bien: dado que los productos se agregan hasta el final, no tengo que hacer nada extraño si un número no tiene un signo, ya que el único que puede estar sin un signo es el primer número.

EDITAR: $'en reemplazo representa el resto de la cadena después del partido, por lo que puedo eliminar los (.*)s finales .

mbomb007
fuente
0

k, 98 bytes

No muy golfizado.

{,/(*x){(s#y),("*"/:(x;(s:(*y)in"+-")_y))/:$"()"}/:1_x@:&~~#:'x:((0,&~x in .Q.n)_x){x_'x?'y}/"()"}

Dividir en no dígitos, eliminar parens, eliminar cadenas vacías, luego mantener xconstante como la primera cadena, combinar *con cada cadena restante y, paréntesis y mover el signo al principio si está presente; aplanar la salida en una sola cadena.

Aaron Davies
fuente