Дополнительные факты!

17

В математике факториал, сокращенный «факт» неотрицательного целого числа n , обозначается через n! , является произведением всех натуральных чисел, меньших или равных n . Например, 5! это 1 * 2 * 3 * 4 * 5 = 120

Факториал 0 равен 1 , в соответствии с соглашением для пустого продукта.


Это обычные факты, к которым мы привыкли. Давайте добавим несколько альтернатив:

  1. Факториал (определенный выше)
  2. Двойной факториал: n !! = 1 + 2 + ... + n
  3. Тройной факториал: n !!! = 1 - (2 - (3 - (... - n))) ...)
  4. Четырехкратный факториал: n !!!! = 1 / (2 / (3 ... / n))) ...) . Примечание. Это деление с плавающей запятой, а не целочисленное деление.

Вызов

Возьмем неотрицательный целочисленный ввод n , за которым непосредственно следуют от 1 до 4 восклицательных знаков. Вход будет выглядеть (точно) так: 0! , 5 !! , 132 !!! или 4 !!!! , К сожалению, вы не можете использовать гибкий формат ввода.

Выход

Результат должен быть результатом в любом удобном формате. Результат четырехкратного факториала должен иметь как минимум 2 цифры после десятичной точки, кроме 0 !!!! = 0 .

Тестовые случаи:

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

Самое короткое решение на каждом языке выигрывает.

Стьюи Гриффин
источник
2
Может ли четырехкратный факториал быть рациональным делением?
Мартин Эндер
6
Определение «двойного факториала» не подходит ...
Эрик Аутгольфер
4
@ Эрик, это альтернативный двойной факт ;-)
Стьюи Гриффин
1
@StewieGriffin Кстати, это немного подло, что 0!-> 1.
Эрик Outgolfer
5
Название должно быть Альтернативные факты
Цифровая травма

Ответы:

7

JavaScript (ES6), 88 байт

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

Контрольные примеры

Отформатировано и прокомментировано

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
источник
7

Шелуха , 15 байт

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

Попробуйте онлайн!

объяснение

Индексирование в список функций: радости использования функционального языка.

§!ëΠΣ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

Я использую нисходящий диапазон и левые сгибы, так как -и /принимаю их аргументы в обратном порядке в Husk.

Zgarb
источник
Indexing into a list of functionsэто вау ...
Эрик Outgolfer
Я думал о Хаскелле, а потом я вижу это ... Похоже, действительно правильный инструмент для работы. +1
17
Это то, для чего был создан Husk: D
Лев
6

C # (.NET Core) , 134 130 128 байтов

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;}

Попробуйте онлайн!

Лучшая часть игры в гольф кода - это то, что вы изучаете, пытаясь решить задачи. В этом я узнал, что в C # вы можете обрезать другие символы, кроме пробелов, из строк.

  • 4 байта сохранены благодаря LiefdeWen!
  • 2 байта сохранены, потому что мне не нужно вычитать 1 в s.Split('!').Length, просто установите ограничения в e>4?i/r:e>3?i-r:e>2?i+r:i*rи n<1&e<3?1:r.
Чарли
источник
1
Вы можете сделать, e nа iтакже doubleне объявлять его для r, чтобы сохранить 4 байта.
LiefdeWen
1
@LiefdeWen Или floatсохранить еще один байт.
Кевин Круйссен
4

Perl 5 , 62 байта

61 байт код + 1 для -p.

$_=/^0!$/+eval join(qw{| *( +( -( /(}[s/!//g],1..$_).")"x--$_

Спасибо @GB за указание на промах с моей стороны!

Попробуйте онлайн! (это используется -lдля удобства чтения)

Дом Гастингс
источник
4
0! должно быть 1, а не 0
GB
@ GB Ну, это не имеет никакого смысла ... Исправлено на +5!
Дом Гастингс
4

R , 113 111 байт

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

Попробуйте несколько тестовых случаев!

ungolfed:

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
источник
el(strsplit(s,"!")) сохраняет 1 байт
bouncyball
4

Python3, 124 130 121 119 байт

На данный момент, я считаю, что рекурсия является ключом к дальнейшей экономии байтов.

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

Попробуйте тестовые случаи на Попробуйте онлайн!

-9 байт благодаря @ Mr.Xcoder !

-2 байта благодаря @ Филипе Нарди Батиста !

Yytsi
источник
Не в течение 6! , Это должно быть 720.
Мистер Xcoder
Я обновил тестовый набор Tio.
Мистер Кскодер
-3 байта .
Мистер Кскодер
Ах да, конечно, не
заметил
2
Вот ES6
Эрик Outgolfer
3

Pyth , 34 30 байт

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

Попробуйте онлайн!

объяснение

+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
источник
Использование.U сохраняет байт.
Эрик Outgolfer
2

05AB1E , 27 байт

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

Попробуйте онлайн!

Эрик Outgolfer
источник
Знаете „.»ли вы, почему не работает?
Райли
@Riley »является частью незаконченной сжатой строки, поэтому она выдает ошибку и, как обычно в 05AB1E, ошибка игнорируется.
Эрик Outgolfer
Я пытался сделать это "*+-/"èUпосле использования Lпродолжения, .»Xно он воспринимается Xкак строка, а не как команда, и .»X.Vдаже более странно.
Волшебная Урна Осьминога
@MagicOctopusUrn Xне оценивается . X.Vдве команды.
Эрик Аутгольфер
@EriktheOutgolfer, да, но я надеялся, что это пройдет, прежде чем обрабатывать фолд. Надеюсь , не ожидая :(. Мог бы поклясться, что было «использовать односимвольную строку как команду в двоичной цепочке» или что-то в этом роде.
Волшебная Урна Осьминога
2

Рубин , 83 80 79 байтов

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

Попробуйте онлайн!

Объяснение:

->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)
}
гигабайт
источник
2

Java 8, 141 136 134 байта

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 байт (141 → 136) благодаря ответу @CarlosAlejo на C # .

Объяснение:

Попробуй это здесь.

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
Кевин Круйссен
источник
1
Я видел аналогичный ответ где-то еще ...: -Я постоянно забываю, что floatкороче double.
Чарли
@CarlosAlejo Да, я заметил твой ответ после моего начального 141-байтового ответа. Переход float q=s.length()-(s=s.replace("!","")).length(),n=new Float(s)к текущему ответу сэкономил мне 5 байтов. :) Забыл добавить часть " Байты спасены благодаря ", которую я заметил сейчас. Извините.
Кевин Круйссен
о, не важно, я рад, что тебе понравился мой ответ. :-)
Чарли
2

Желе ,  24 23 26  25 байт

+  3  исправления 2 байта, чтобы исправить после неправильной интерпретации :(

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

Полная программа (монадическая ссылка со вспомогательными ссылками, на которые ссылается местоположение программы)

Попробуйте онлайн! или увидеть тестов .

Как?

× - 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)
Джонатан Аллан
источник
Терпит неудачу за 0!.
Эрик Outgolfer
О, ха-ха, - я прочитал ваш комментарий под ОП неправильно - я думал, что они сделали 0! определяется как 0, что было бы неправильно.
Джонатан Аллан
Все исправлено сейчас :)
Джонатан Аллан
Жаль, что TIO сломан прямо сейчас, так что я не могу проверить, если он все еще недействителен. :(: P Кроме того, очень плохо , что вы не можете использовать /. На пустой список D: EDIT: Видимо действительно для 0!, 0!!, 0!!!и 0!!!!+1.
Эрик Outgolfer
2

Самомодифицирующийся машинный код x86_64, 123 байта

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

Почему интерпретируемые языки могут динамически запускать код eval s, но не простым машинным кодом?

Попробуйте это с:

#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]));
    }
}

Монтаж:

_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

Пояснения будут добавлены позже. Основная идея заключается в том, чтобы изменить divss xmm0, xmm1инструкцию на 0x100000db0и заменить его mulss, addss,subss или в divssсоответствии с прилагаемым операндом. Небольшой трюк также используется для анализа входной строки.

Сборка генерируется с помощью:

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;
}
Йоанн
источник
2

Haskell, 105 102 98 96 байт

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)

Сохранено 9 байтов благодаря Zgarb и Nimi.

Попробуйте онлайн.

Кристиан Лупаску
источник
@ Zgarb Вы правы. Исправлена.
Кристиан Лупаску
Я думаю, что вы также можете бросить парэнс вокруг read n, и f=это не нужно в соответствии с нашими правилами .
Згарб
@ Zgarb Верно снова :). Благодарность!
Кристиан Лупаску
Переключение обратно к имени функции и используя lexсохраняет два байта: f s|[(n,b)]<-lex s=read n!(length b-1).
Ними
@nimi Ого, спасибо! Я так новичок в Хаскеле, что даже не знал lex. Это потрясающе! :) Я не вижу, как это экономит байты, хотя - я получаю 99 байтов после этого.
Кристиан Лупаску
1

Gaia , 26 25 байт

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

Попробуйте онлайн!

объяснение

ẋ                          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.
Бизнес Кот
источник
1

APL (Dyalog) , 30 байтов

Вдохновленный решением Истефано .

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

Попробуйте онлайн!

{} Анонимная функция, в которой аргумент представлен :

0:: если произойдет какая-либо ошибка:

  0 вернуть ноль

 сейчас попробуй:

  ⍵∩⎕D пересечение аргумента , а множество D igits (удаляет восклицательные)

   выполнить это (превращает его в число)

  В конце концов

  ()/ Вставить (при необходимости, APL ассоциативно справа) следующую функцию между терминами:

   ⍵~⎕D аргумент без D igits (листья восклицательные)

   подсчитать, что (то есть, сколько восклицательных знаков)

  '×+-⌹'⊃⍨ используйте это, чтобы выбрать из списка символов *

   выполнить (превращает символ в функцию)


(матричное разделение) используется вместо ÷(нормальное разделение), чтобы вызвать ошибку в пустом списке

Адам
источник
Что делает ::в DFN?
Захари
Это защита от ошибок . Если в какой-либо момент после установки защиты от ошибок произойдет ошибка с любым из чисел (0 = 1… 999, 1000 = 1001…) слева от ::случая, то ::сразу же будет возвращено значение справа от .
адам
Ну, я никогда не знал об этом, спасибо!
Захари
0

Dyalog APL, не менее 29 символов

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

Выражение почти верное. Он проходит все тестовые случаи, КРОМЕ 0!!!!для которых он дает 1вместо обязательного, 0и это потому, что в APL сокращение пустого вектора должно возвращать нейтральный элемент для функции, используемой для сокращения. Для фактора это 1. На данный момент у меня нет времени, чтобы попытаться это исправить, но я оставлю это здесь на черный день.

lstefano
источник
Идет дождь: {0::0⋄(⍎'×+-⌹'⊃⍨≢⍵~⎕D)/⍳⍎⍵∩⎕D} попробуйте онлайн!
17
Очень круто! Я совсем не против, если вы заявите, что это ваше решение, учитывая, что различия больше, чем сходство.
Стефано
0

Mathematica, 152 байта

(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
источник
0

Javascript, 111 163 байта

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

Читаемая версия

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
источник