Diferenciación simbólica 1: Gone Coefishin '
Tarea
Escriba un programa que tome un polinomio en x de stdin (1 <deg (p) <128) y lo diferencie. El polinomio de entrada será una cadena de la siguiente forma:
"a + bx + cx^2 + dx^3 +" ...
donde el coeficiente de cada término es un número entero (-128 <a <128). Cada término está separado por un espacio, a + y otro espacio; los términos lineales y constantes aparecen como arriba (es decir, no x^0
o x^1
). Los términos aparecerán en orden creciente y se omiten las potencias con coeficiente cero . Todos los términos con coeficiente 1 o -1 muestran ese coeficiente explícitamente.
Su salida debe tener exactamente la misma forma. Tenga en cuenta que los coeficientes en la salida pueden ser tan grandes como 127 * 127 == 16129.
Ejemplos
"3 + 1x + 2x^2" ==> "1 + 4x"
"1 + 2x + -3x^2 + 17x^17 + -1x^107" ==> "2 + -6x + 289x^16 + -107x^106"
"17x + 1x^2" ==> "17 + 2x"
Puntuación
Su puntaje es la longitud de su programa en bytes, multiplicado por tres si usa una biblioteca incorporada o una que hace álgebra simbólica.
Respuestas:
Retina ,
534342414035 bytesPara contar, cada línea va en un archivo separado, pero puede ejecutar lo anterior como un solo archivo invocando Retina con la
-s
bandera.Esto espera que los números en la cadena de entrada se den en unario y producirán resultados en el mismo formato. P.ej
en lugar de
Explicación
El código describe una única sustitución de expresiones regulares, que es básicamente 4 sustituciones comprimidas en una. Tenga en cuenta que solo una de las ramas llenará el grupo,
$2
por lo que si cualquiera de las otras tres coincide, la coincidencia simplemente se eliminará de la cadena. Entonces podemos ver los cuatro casos diferentes por separado:Si es posible llegar a un espacio desde el comienzo de la cadena sin encontrar uno,
x
eso significa que el primer término es el término constante y lo eliminamos. Debido a la codicia de+
, esto también coincidirá con el más y el segundo espacio después del término constante. Si no hay un término constante, esta parte simplemente nunca coincidirá.Esto coincide con un
x
seguido de un espacio, es decir, elx
del término lineal (si existe), y lo elimina. Podemos estar seguros de que hay un espacio después, porque el grado del polinomio siempre es al menos 2.Esto realiza la multiplicación del coeficiente por el exponente. Esto coincide con un solo
1
en el coeficiente y lo reemplaza por todo el exponente correspondiente a través de la búsqueda anticipada.Esto reduce todos los exponentes restantes al hacer coincidir el final
1
(asegurado por la búsqueda anticipada). Si es posible hacer coincidir^11
(y un límite de palabra), lo eliminamos, lo que se encarga de mostrar el término lineal correctamente.Para la compresión, notamos que la mayoría de las condiciones no se afectan entre sí.
(\^1)?
no coincidirá si la anticipación en el tercer caso es verdadera, por lo que podemos juntar esos dos comoAhora ya tenemos el lookahead necesario para el segundo caso y los otros nunca pueden ser verdaderos cuando coinciden
x
, por lo que simplemente podemos generalizar1
a\w
:El primer caso realmente no tiene nada en común con los demás, por lo que lo mantenemos separado.
fuente
CJam,
4341 bytes¡Gracias a @ jimmy23013 por señalar un error y jugar dos bytes!
Pruébelo en línea en el intérprete de CJam .
Cómo funciona
fuente
Perl,
6463 bytesCódigo 62b + 1 línea de comando (-p)
No es sorprendente por el momento, pero continuaré tratando de acortarlo.
Ejemplo de uso:
Gracias Denis por -1b
fuente
Julia, 220 bytes
No hay expresiones regulares!
Esto crea una función lambda que acepta una cadena y devuelve una cadena. Las entrañas imitan lo que sucede cuando se evalúa el código de Julia: una cadena se analiza en símbolos, expresiones y llamadas. De hecho, podría intentar escribir una función de diferenciación simbólica completa de Julia y enviarla para que sea parte de Julia.
Ungolfed + explicación:
fuente
C,
204162 bytesBásicamente analiza cada término e imprime el término diferenciado en secuencia. Bastante sencillo.
fuente
JavaScript ES6, 108 bytes
Fragmento de ES5:
fuente
Python 2, 166 bytes
Chico, esto parece más largo de lo que debería ser.
La función
d
toma un término no constantet
y devuelve su derivada. La razón por la quedef
la función en lugar de usar una lambda es para poder asignar el exponente menos 1 ae
, que luego se usa otras cuatro veces. Lo principal y molesto es tener que lanzar de un lado a otro entre cadenas e ints, aunque el operador de backtick de Python 2 ayuda con eso.Luego dividimos la entrada en términos y recurrimos
d
a cada uno que contiene"x"
, eliminando así el término constante. Los resultados se vuelven a unir e imprimir.fuente
CJam,
62575549 bytesBueno, Dennis lo avergonzó antes de que me diera cuenta de que el sitio estaba funcionando nuevamente. Pero aquí está mi creación de todos modos:
La última versión guarda algunos bytes con accesos directos sugeridos por @Dennis (use variables y divídalas en el espacio en lugar de
+
).Pruébalo en línea
fuente
_({'^a\}{;}?
es 1 byte más largo que:T({T'^a\}&
.~
bloque restante y puede eliminar ese también.x
. Encontré algunas mejoras más mientras estaba en ello. Principalmente, debido a que ahora tengo los valores en variables, puedo recordarlos donde realmente los necesito, ahorrando algo de manipulación de la pila. También tuve un parásitoa
que debería haberse eliminado cuando optimicé la generación de salida antes.Pyth, 62 bytes
Solución bastante fea, usando algunas sustituciones de expresiones regulares.
fuente
Python 3, 176 bytes
De hecho, la molestia principal es tener que convertir entre cadenas e ints. Además, si se requería un término constante, el código solo tendría 153 bytes.
fuente
Python 2, 229 bytes
fuente
Python 2, 174 bytes
Desafortunadamente, el truco de DLosc para cambiar el nombre del método de división y realizar la diferenciación en una función específica no acorta mi código ...
fuente