Hechos adicionales!

17

En matemáticas, el "hecho" factorial acortado de un entero no negativo n , denotado por n! , es el producto de todos los enteros positivos menores o iguales que n . Por ejemplo, 5! es 1 * 2 * 3 * 4 * 5 = 120

El factorial de 0 es 1 , según la convención para un producto vacío.


Estos son los hechos habituales a los que estamos acostumbrados. Agreguemos algunas alternativas:

  1. El factorial (definido anteriormente)
  2. El doble factorial: n !! = 1 + 2 + ... + n
  3. El factorial triple: n !!! = 1 - (2 - (3 - (... - n))) ...)
  4. El factorial cuádruple: n !!!! = 1 / (2 / (3 ... / n))) ...) . Nota: Esta es una división de punto flotante, no una división entera.

Desafío

Tome una entrada entera no negativa n , seguida directamente por entre 1 y 4 signos de exclamación. La entrada se verá (exactamente) así: 0! , 5 !! , 132 !!! o 4 !!!! . En este desafío, no puede asumir un formato de entrada flexible, lo siento.

Salida

La salida debe ser el resultado, en cualquier formato conveniente. ¡El resultado del factorial cuádruple debe tener al menos 2 dígitos después del punto decimal, excepto 0! = 0 .

Casos de prueba:

0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
---
0!! = 0
1!! = 1
2!! = 3
3!! = 6
4!! = 10
5!! = 15
6!! = 21
7!! = 28
8!! = 36
9!! = 45
10!! = 55
---
0!!! = 0
1!!! = 1
2!!! = -1
3!!! = 2
4!!! = -2
5!!! = 3
6!!! = -3
7!!! = 4
8!!! = -4
9!!! = 5
10!!! = -5
---
0!!!! = 0
1!!!! = 1
2!!!! = 0.5
3!!!! = 1.5
4!!!! = 0.375
5!!!! = 1.875
6!!!! = 0.3125
7!!!! = 2.1875
8!!!! = 0.27344
9!!!! = 2.4609
10!!!! = 0.24609

La solución más corta en cada idioma gana.

Stewie Griffin
fuente
2
¿Puede el factorial cuádruple también ser una división racional?
Martin Ender
66
La definición de "El doble factorial" encaja ...
Erik the Outgolfer
44
@Erik, es un hecho doble alternativo ;-)
Stewie Griffin
1
@StewieGriffin Por cierto, es un poco astuto que 0!-> 1.
Erik the Outgolfer
55
El título debería ser Hechos alternativos
Trauma digital

Respuestas:

7

JavaScript (ES6), 88 bytes

s=>eval(([a,b]=s.split(/\b/),g=k=>+a?k-a?k+'_*+-/'[b.length]+`(${g(k+1)})`:k:+!b[1])(1))

Casos de prueba

Formateado y comentado

s =>                                // given the input string s,
  eval(                             // evaluate as JS code:
    ( [a, b] = s.split(/\b/),       //   a = integer (as string) / b = '!' string
      g = k =>                      //   g = recursive function taking k as input
        +a ?                        //     if a is not zero:
          k - a ?                   //       if k is not equal to a:
            k + '_*+-/'[b.length] + //         append k and the operation symbol
            `(${g(k + 1)})`         //         append the result of a recursive call
          :                         //       else:
            k                       //         just append k and stop recursion
        :                           //     else:
          +!b[1]                    //       return 1 for multiplication / 0 otherwise
    )(1)                            //   initial call to g() with k = 1
  )                                 // end of eval()
Arnauld
fuente
7

Casco , 15 bytes

§!ëΠΣF-F/#'!oṫi

Pruébalo en línea!

Explicación

Indexación en una lista de funciones: las alegrías de usar un lenguaje funcional.

§!ëΠΣF-F/#'!oṫi  Implicit input, say x = "6!!!"
              i  Convert to integer (parses the leading sequence of digits): 6
            oṫ   Descending range to 1: y = [6,5,4,3,2,1]
  ë              Four-element list containing the functions
   Π             product,
    Σ            sum,
     F-          left fold with subtraction (gives 0 for empty list), and
       F/        left fold with division (gives 0 for empty list).
 !               1-based index into this list with
         #'!     count of !-characters in input: gives F-
§                Apply to y and print implicitly: -3

Utilizo un rango descendente y pliegues izquierdos, -y /tomo sus argumentos en orden inverso en Husk.

Zgarb
fuente
Indexing into a list of functionsis woah ...
Erik the Outgolfer
Estaba pensando en Haskell, y luego veo esto ... Verdaderamente parece ser la herramienta adecuada para el trabajo. +1
callejones del
Para esto se hizo Husk: D
Leo
6

C # (.NET Core) , 134 130 128 bytes

s=>{double e=s.Split('!').Length,n=int.Parse(s.Trim('!')),i=n,r=n;for(;--i>0;)r=e>4?i/r:e>3?i-r:e>2?i+r:i*r;return n<1&e<3?1:r;}

Pruébalo en línea!

La mejor parte del golf de código son las cosas que aprende al tratar de resolver los desafíos. En este, he aprendido que en C # puede recortar otros caracteres además de espacios en blanco de las cadenas.

  • ¡4 bytes guardados gracias a LiefdeWen!
  • 2 bytes guardados porque no necesito restar 1 a s.Split('!').Length, solo arregle los límites en e>4?i/r:e>3?i-r:e>2?i+r:i*ry n<1&e<3?1:r.
Charlie
fuente
1
Puede hacer e ny itambién doubleevitar declararlo para que r guarde 4 bytes.
LiefdeWen
1
@LiefdeWen O floatpara guardar otro byte.
Kevin Cruijssen
4

R , 113 111 bytes

function(s){z=strtoi((n=strsplit(s,'!')[[1]])[1])
n=length(n)
`if`(z,Reduce(c('*','+','-','/')[n],1:z,,T),n<2)}

¡Prueba algunos casos de prueba!

sin golf:

function(s){
  n <- strsplit(s,"!")[[1]]          # split on "!"
  z <- strtoi(n[1])                  # turn to integer
  n <- length(n)                     # count number of "!"
  FUN <- c(`*`,`+`,`-`,`/`)[[n]]     # select a function
  right <- TRUE                      # Reduce (fold) from the right
  if( z > 0)                         # if z > 0
    Reduce(FUN, 1:z,,right)          # return the value
  else    
    (n < 2)                          # 1 if n = 1, 0 if n > 1
}
Giuseppe
fuente
el(strsplit(s,"!")) ahorra 1 byte
bouncyball
4

Python3, 124 130 121 119 bytes

En este punto, creo que la recursividad es la clave para ahorrar más bytes.

s=input()
l=s.count('!')
v=int(s[:-l])+1
print(eval((" *+-/"[l]+"(").join(map(str,range(1,v)))+")"*(v-2)or"0")+(l<2>v))

Pruebe los casos de prueba en ¡ Pruébelo en línea!

-9 bytes gracias a @ Mr.Xcoder !

-2 bytes gracias a @Felipe Nardi Batista !

Yytsi
fuente
¡Falla por 6! . Debería ser 720.
Sr. Xcoder
Actualicé la suite de prueba Tio.
Sr. Xcoder
-3 bytes .
Sr. Xcoder
Oh sí, claro, no lo
vi
2
He aquí el ES6
Erik the Outgolfer
3

Pyth , 34 30 bytes

+uv++H@"/*+-"/Q\!G_tUK.vQKq"0!

Pruébalo en línea!

Explicación

+uv++H@"/*+-"/Q\!G_tUK.vQKq"0!"Q    Implicit: append "Q
                                    Implicit: read input to Q
                      .vQ           Evaluate Q as Pyth code. This evaluates the integer,
                                    any !'s are parsed as unary NOT for the next expression
                                    and discarded.
                     K              Save the result to K.
                    U               Get a list [0, 1, ..., K-1].
                   t                Drop the first item to get [1, 2, ..., K-1].
                  _                 Reverse to get [K-1, K-2, ..., 1].
 u                       K          Starting from G = K, for H in [K-1, K-2, ..., 1] do:
             /Q\!                     Count the !'s in Q.
      @"/*+-"                         Get the correct operator.
    +H                                Prepend the current H.
   +             G                    Append the previous value G.
  v                                   Evaluate as Python code.
                          q"0!"Q    See if Q == "0!".
+                                   If so, add 1.
PurkkaKoodari
fuente
El uso.U guarda un byte.
Erik the Outgolfer
2

05AB1E , 27 bytes

þL"/*+-"¹'!¢©è".»"ì.VD_нi®Θ

Pruébalo en línea!

Erik el Outgolfer
fuente
¿Sabes por qué „.»no funciona?
Riley
@Riley »es parte de una cadena comprimida inacabada, por lo que produce errores y, como suele ocurrir en 05AB1E, el error se ignora.
Erik the Outgolfer
Estaba tratando de hacerlo "*+-/"èUluego de usar el Lseguimiento con, .»Xpero se trata Xcomo una cadena, no como un comando, y .»X.Ves aún más extraño.
Urna de pulpo mágico
@MagicOctopusUrn Xno evalúa . X.VSon dos comandos.
Erik the Outgolfer
@EriktheOutgolfer, sí, pero esperaba que evaluara antes de procesar el pliegue. Esperando , no esperando :(. Podría haber jurado que había una "cadena de un solo uso como comando en la cadena diádica" o algo así.
Urna de pulpo mágico
2

Ruby , 83 80 79 bytes

->s{z=s.count ?!;s<?1?1+1<=>z:eval([*1..w=s.to_i]*(".0"+"_*+-/"[z]+?()+?)*~-w)}

Pruébalo en línea!

Explicación:

->s{
    # Get number of !
    z=s.count ?!

    # Special case: if the number is 0, then output 0 or 1 depending on z
    s<?1?1+1<=>z:

    # Otherwise build the full expression as a string and then evaluate it
    eval([*1..w=s.to_i]*(".0"+"_*+-/"[z]+?()+?)*~-w)
}
GB
fuente
2

Java 8, 141 136 134 bytes

s->{float q=s.split("!",-1).length,n=new Float(s.split("!")[0]),i=n,r=n;for(;--i>0;r=q<3?i*r:q<4?i+r:q<5?i-r:i/r);return n<1&q<3?1:r;}

-5 bytes (141 → 136) gracias a la respuesta C # de @CarlosAlejo .

Explicación:

Pruébalo aquí

s->{                                // Method with String parameter and float return-type
  float q=s.split("!",-1).length,   //  Amount of exclamation marks + 1
        n=new Float(s.split("!")[0]),
                                    //  The number before the exclamation marks
        i=n,                        //  Index (starting at `n`)
        r=n;                        //  Return sum (starting at `n`)
  for(;--i>0;                       //  Loop from `i-1` down to 1
    r=                              //   Change the result (`r`) to:
      q<3?                          //    If `q` is 2:
       i*r                          //     Multiply
      :q<4?                         //    Else if `q` is 3:
       i+r                          //     Addition
      :q<5?                         //    Else if `q` is 4:
       i-r                          //     Subtraction
      :                             //    Else (if `q` is 5):
       i/r                          //     Division
  );                                //  End of loop
  return n<1&q<3?                   //  Edge case if the input is `0!`:
          1                         //   Then return 1
         :                          //  Else:
          r;                        //   Return the result
}                                   // End of method
Kevin Cruijssen
fuente
1
He visto una respuesta similar en otro lugar ...: -DI sigo olvidando que floates más corto que double.
Charlie
@CarlosAlejo Sí, noté tu respuesta después de mi respuesta inicial de 141 bytes. Cambiar float q=s.length()-(s=s.replace("!","")).length(),n=new Float(s)a la respuesta actual me ahorró 5 bytes. :) Olvidé agregar una parte de " bytes guardados gracias a " que noté ahora. Lo siento.
Kevin Cruijssen
oh, no importa eso, me alegra que te haya gustado mi respuesta. :-)
Charlie
2

Jalea ,  24 23 26  25 bytes

+  3  2 bytes parcheando para arreglar después de una mala interpretación :(

×
+
_
÷
ṣ”!µḢVRṚȯL©Ị$®ŀ@/

Un programa completo (un enlace monádico con enlaces de ayuda referenciados por la ubicación del programa)

Pruébalo en línea! o ver un conjunto de pruebas .

¿Cómo?

× - Link 1, multiply: number, number

+ - Link 2, add: number, number

_ - Link 1, subtract: number, number

÷ - Link 1, divide: number, number

ṣ”!µḢVRṚȯL©Ị$®ŀ@/ - Main link: list of characters, a
ṣ”!               - split s at '!' characters
   µ              - monadic separation, call that b
    Ḣ             - head - pop and yield the digit list from b, modifying b
     V            - evaluate as Jelly code (get the number, say N)
      R           - range = [1,2,3,...,N]
       Ṛ          - reverse = [N,...,3,2,1]
            $     - last two links as a monad:
         L        -   length of modified b (number of '!' characters)
          ©       -   (copy to register)
           Ị      -   insignificant? (1 when just one '!', 0 when two or more)
        ȯ         - logical or (1 for "0!", 0 for "0!!...", the reversed-range otherwise)
                / - cumulative reduce by:
               @  -  with swapped arguments:
              ŀ   -    dyadic call of link at index:
             ®    -      recall value from register (number of '!' characters)
Jonathan Allan
fuente
Falla por 0!.
Erik the Outgolfer
Oh, jaja. Había leído mal tu comentario bajo el OP. ¡Pensé que habían hecho 0! definido como 0 que estaría mal.
Jonathan Allan
Todo arreglado ahora :)
Jonathan Allan
Lástima que TIO está roto en este momento, por lo que no puedo probar si aún no es válido. :(: P También es una pena que no se pueda usar /en una lista vacía. D: EDITAR: aparentemente válido para0! , 0!!, 0!!!y 0!!!!1.
Erik el Outgolfer
2

Código de máquina x86_64 auto modificable, 123 bytes

0f b6 0f 31 c0 eb 11 0f be c9 8d 04 80 8d 44 41 d0 0f b6 4f 01 48 ff c7 83 f9 21 75 ea b9 21 21 21 a1 33 0f 0f bc c9 81 c1 ff 07 00 00 c1 e9 03 0f b6 c9 89 ca 09 c2 74 35 55 48 89 e5 c7 45 fc 59 58 5c 5e 8a 4c 0d fc 88 0d 15 00 00 00 f3 0f 2a c8 83 f8 02 5d 7c 1f ff c8 0f 57 c0 f3 0f 2a c0 f3 0f 5e c1 83 f8 01 0f 28 c8 7f eb c3 f3 0f 10 05 03 01 00 00 c3 0f 28 c1 c3

¿Por qué los idiomas interpretados podrían ejecutar código dinámicamente con evals sofisticados , pero no con código de máquina simple?

Pruébalo con:

#include <stdio.h>
#include <sys/mman.h>
#include <errno.h>

char ff[] = "\x0f\xb6\x0f\x31\xc0\xeb\x11\x0f\xbe\xc9\x8d\x04\x80\x8d\x44\x41\xd0\x0f\xb6\x4f\x01\x48\xff\xc7\x83\xf9\x21\x75\xea\xb9\x21\x21\x21\xa1\x33\x0f\x0f\xbc\xc9\x81\xc1\xff\x07\x00\x00\xc1\xe9\x03\x0f\xb6\xc9\x89\xca\x09\xc2\x74\x35\x55\x48\x89\xe5\xc7\x45\xfc\x59\x58\x5c\x5e\x8a\x4c\x0d\xfc\x88\x0d\x15\x00\x00\x00\xf3\x0f\x2a\xc8\x83\xf8\x02\x5d\x7c\x1f\xff\xc8\x0f\x57\xc0\xf3\x0f\x2a\xc0\xf3\x0f\x5e\xc1\x83\xf8\x01\x0f\x28\xc8\x7f\xeb\xc3\xf3\x0f\x10\x05\x03\x01\x00\x00\xc3\x0f\x28\xc1\xc3";
int main()
{
    char* page = (char*)((unsigned long)((char*)ff) & (~0xfffLL));
    if (mprotect(page, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) {
        perror("mprotect");
        return -1;
    }
    float (*f)(char*) = (float (*)(char*))ff;
    char* testcases[] = { "0!","1!","2!","3!","4!","5!","6!","7!","8!","9!","10!",
                          "0!!","1!!","2!!","3!!","4!!","5!!","6!!","7!!","8!!","9!!","10!!",
                          "0!!!","1!!!","2!!!","3!!!","4!!!","5!!!","6!!!","7!!!","8!!!","9!!!","10!!!",
                          "0!!!!","1!!!!","2!!!!","3!!!!","4!!!!","5!!!!","6!!!!","7!!!!","8!!!!","9!!!!","10!!!!",
                        };
    for (int i = 0; i < 44; i++) {
        printf("%s -> %f\n", testcases[i], f(testcases[i]));
    }
}

Montaje:

_f:
100000d4f:  0f b6 0f    movzx   ecx, byte ptr [rdi]
100000d52:  31 c0   xor eax, eax
100000d54:  eb 11   jmp 17 <_f+18>
100000d56:  0f be c9    movsx   ecx, cl
100000d59:  8d 04 80    lea eax, [rax + 4*rax]
100000d5c:  8d 44 41 d0     lea eax, [rcx + 2*rax - 48]
100000d60:  0f b6 4f 01     movzx   ecx, byte ptr [rdi + 1]
100000d64:  48 ff c7    inc rdi
100000d67:  83 f9 21    cmp ecx, 33
100000d6a:  75 ea   jne -22 <_f+7>
100000d6c:  b9 21 21 21 a1  mov ecx, 2703302945
100000d71:  33 0f   xor ecx, dword ptr [rdi]
100000d73:  0f bc c9    bsf ecx, ecx
100000d76:  81 c1 ff 07 00 00   add ecx, 2047
100000d7c:  c1 e9 03    shr ecx, 3
100000d7f:  0f b6 c9    movzx   ecx, cl
100000d82:  89 ca   mov edx, ecx
100000d84:  09 c2   or  edx, eax
100000d86:  74 35   je  53 <_f+6E>
100000d88:  55  push    rbp
100000d89:  48 89 e5    mov rbp, rsp
100000d8c:  c7 45 fc 59 58 5c 5e    mov dword ptr [rbp - 4], 1583110233
100000d93:  8a 4c 0d fc     mov cl, byte ptr [rbp + rcx - 4]
100000d97:  88 0d 15 00 00 00   mov byte ptr [rip + 21], cl
100000d9d:  f3 0f 2a c8     cvtsi2ss    xmm1, eax
100000da1:  83 f8 02    cmp eax, 2
100000da4:  5d  pop rbp
100000da5:  7c 1f   jl  31 <_f+77>
100000da7:  ff c8   dec eax
100000da9:  0f 57 c0    xorps   xmm0, xmm0
100000dac:  f3 0f 2a c0     cvtsi2ss    xmm0, eax
100000db0:  f3 0f 5e c1     divss   xmm0, xmm1
100000db4:  83 f8 01    cmp eax, 1
100000db7:  0f 28 c8    movaps  xmm1, xmm0
100000dba:  7f eb   jg  -21 <_f+58>
100000dbc:  c3  ret
100000dbd:  f3 0f 10 05 03 01 00 00     movss   xmm0, dword ptr [rip + 259]
100000dc5:  c3  ret
100000dc6:  0f 28 c1    movaps  xmm0, xmm1
100000dc9:  c3  ret

Las explicaciones se agregarán más tarde. La idea básica es modificar la divss xmm0, xmm1instrucción en 0x100000db0y sustituirla por una mulss, addss, subsso divssde acuerdo con el operando suministrado. También se usa un pequeño truco para analizar la cadena de entrada.

Asamblea generada con:

float f (char* s)
{
    int x;
    for (x=0; *s != '!'; s++) {
        x=10*x + (*s-'0');
    }
    unsigned char op = (__builtin_ctz(*(unsigned int *)s ^ 0xa1212121)-1) >> 3;
    if (x == 0 && op == 0) {
        return 1;
    }
    unsigned int lookup = 0x5e5c5859;
    unsigned char new_code = ((unsigned char*)&lookup)[op];
    asm("movb %0, 0x15(%%rip)" : : "r" (new_code));
    float sum;
    for (sum = x--; x>0; x--) {
        sum = x / sum;
    }
    return sum;
}
yoann
fuente
2

Haskell 105102 98 96 bytes

0!3=0
x!y=foldr([(*),(+),(-),(/)]!!y)([1,0,0,1]!!y)[1..x]
f s|[(n,b)]<-lex s=read n!(length b-1)

Guardado 9 bytes gracias a Zgarb y nimi.

Pruébalo en línea.

Cristian Lupascu
fuente
@ Zgarb Tienes razón. Fijo.
Cristian Lupascu
Creo que también puede soltar a los padres read n, y f=es innecesario según nuestras reglas .
Zgarb
@Zgarb Derecha otra vez :). ¡Gracias!
Cristian Lupascu
Cambiar de nuevo a una función llamada y el uso de lexsalva dos bytes: f s|[(n,b)]<-lex s=read n!(length b-1).
nimi
@nimi Wow, gracias! Soy tan nuevo en Haskell que ni siquiera lo sabía lex. ¡Eso es genial! :) No veo cómo eso ahorra bytes, obtengo 99 bytes después de esto.
Cristian Lupascu
1

Gaia , 26 25 bytes

ẋ)@d┅v;l“×+⁻÷”=“ₔ⊢”+e¤ḥ!∨

Pruébalo en línea!

Explicación

ẋ                          Split the input into runs of the same character.
 )                         Get the last one (the !'s).
  @                        Push an input (since there's none left, use the last one).
   d                       Parse as number (ignores the !'s).
    ┅v                     Get the reverse range: [n .. 1]
      ;                    Copy the ! string
       l“×+⁻÷”=            Get its length and index into this string of operators.
               “ₔ⊢”+       Append 'ₔ⊢' to the operator.
                    e      Eval the resulting string, which is "reduce by <operator> with
                            swapped arguments." Reducing an empty list gives 0.
                     ¤     Bring the !'s back to the top.
                      ḥ!   Remove the first character and check if it's empty.
                        ∨  Logical OR; turns 0 from 0! to 1, doesn't change anything else.
Gato de negocios
fuente
1

Jalea , 28 bytes

×
+
_
÷
³ċ”!
ḟ”!VRṚ¢ŀ@/¢Ị¤¹?

Pruébalo en línea!

Se me ocurrió la idea de separar los enlaces en líneas de la respuesta de Jonathan Allan para -2 bytes.

Erik el Outgolfer
fuente
1

APL (Dyalog) , 30 bytes

Inspirado en la solución de lstefano .

{0::0⋄(⍎'×+-⌹'⊃⍨≢⍵~⎕D)/⍳⍎⍵∩⎕D}

Pruébalo en línea!

{... } función anónima donde el argumento está representado por :

0:: Si ocurre algún error:

  0 devolver cero

 ahora intenta:

  ⍵∩⎕D la intersección del argumento y el conjunto de D igits (elimina los signos de exclamación)

   ejecutar eso (lo convierte en un número)

  d nices de eso

  (... )/ inserte (APL es asociativo correcto, según sea necesario) la siguiente función entre términos:

   ⍵~⎕D argumento sin D igits (deja signos de exclamación)

   cuenta eso (es decir, cuántos puntos de exclamación)

  '×+-⌹'⊃⍨ use eso para elegir de la lista de símbolos *

   ejecutar (convierte el símbolo en una función)


(división de matriz) se usa en lugar de ÷(división normal) para causar un error en una lista vacía

Adán
fuente
¿Qué hace ::en un dfn?
Zacharý
Es un error de guardia . Si en algún momento después de configurar la protección contra errores, se produce un error con cualquiera de los números (0 = 1 ... 999, 1000 = 1001 ...) a la izquierda de lo ::sucedido, entonces el valor a la derecha de la ::se devuelve inmediatamente.
Adám
Bueno, nunca supe de eso, ¡gracias!
Zacharý
0

Dyalog APL, al menos 29 caracteres

{(⍎i⊃'×+-÷')/⍳⍎⍵↓⍨-i←+/'!'=⍵}

La expresión es casi correcta. Pasa todos los casos de prueba, EXCEPTO 0!!!!para lo que da en 1lugar de lo requerido, 0y eso se debe a que en APL la reducción de un vector vacío debe devolver el elemento neutral para la función utilizada para reducir. Para el cociente que es 1. Por el momento no tengo tiempo para tratar de arreglarlo, pero lo dejaré aquí para un día lluvioso.

lstefano
fuente
Está lloviendo: ¡ {0::0⋄(⍎'×+-⌹'⊃⍨≢⍵~⎕D)/⍳⍎⍵∩⎕D} Pruébelo en línea!
Adám
¡Muy genial! No me importa en absoluto si lo reclamas como tu solución, dado que las diferencias son más que las similitudes.
lstefano
Hecho.
Adám
0

Mathematica, 152 bytes

(T=ToExpression;If[#=="0!!!!",0,s=T@StringCount[#,"!"];t=T@StringDrop[#,-s];{#!,i~Sum~{i,#},Sum[-i(-1)^i,{i,#}],N@Product[1/i^(-1)^i,{i,#}]}[[s]]&[t]])&
J42161217
fuente
0

Javascript, 111 163 bytes

s=>([a,b]=s.split(/\b/),c=b.length,a==0&c==1||eval((p=[...Array(+a+1).keys()].slice(1).join(c-1?c-2?c-3?'/(':'-(':'+':'*'))+')'.repeat((p.match(/\(/g)||[]).length)))

Versión legible

s=>([a,b]=s.split(/\b/),c=b.length,a==0&c==1||eval((p=
[...Array(+a+1).keys()].slice(1).join(c-1?c-2?c-3?'/(':'-
(':'+':'*'))+')'.repeat((p.match(/\(/g)||[]).length)))
SuperStormer
fuente