ข้อเท็จจริงเพิ่มเติม!


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
แฟคทอเรียลแฟคทอเรียลก็สามารถแบ่งด้วยเหตุผลได้หรือไม่?
Martin Ender

6
คำจำกัดความของ "คู่แฟคทอเรียล" เหมาะสำหรับ ...
Erik the Outgolfer

4
@Erik มันเป็นความจริงสองทางเลือก ;-)
Stewie Griffin

1
@StewieGriffin BTW มันเป็นบิตส่อเสียดน้อยที่->0! 1
Erik the 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()

7

Huskขนาด 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

ผมใช้ช่วงจากมากไปน้อยและพับด้านซ้ายตั้งแต่-และ/ใช้เวลาขัดแย้งของพวกเขาในการสั่งซื้อกลับในแกลบ


Indexing into a list of functionsis woah ...
Erik the Outgolfer

ฉันกำลังคิดถึงแฮสเค็ลล์และจากนั้นฉันก็เห็นสิ่งนี้ ... ดูเหมือนจะเป็นเครื่องมือที่เหมาะสมสำหรับงานอย่างแท้จริง +1
อ้างถึง

นี่คือสิ่งที่ Husk ทำขึ้นเพื่อ: D
Leo

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*rn<1&e<3?1:r

1
คุณสามารถสร้างe nและiยังdoubleเพื่อหลีกเลี่ยงการประกาศว่าสำหรับการวิจัยเพื่อประหยัด 4 ไบต์
LiefdeWen

1
@LiefdeWen หรือfloatเพื่อบันทึกไบต์อื่น
Kevin Cruijssen

4

Perl 5 , 62 ไบต์

61 รหัสไบต์ + 1 -pสำหรับ

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

ขอบคุณ@GB ที่ชี้ให้เห็นถึงความผิดพลาดในส่วนของฉัน!

ลองออนไลน์! (ใช้-lสำหรับการอ่าน)


4
0! ควรเป็น 1 ไม่ใช่ 0
GB

@GB นั่นไม่สมเหตุสมผลเลย ... แก้ไขเป็น +5!
Dom Hastings

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
}

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 ไบต์ขอบคุณ@Felipe Nardi Batista !



ฉันอัปเดตชุดทดสอบ Tio
Mr. Xcoder

-3 ไบต์
Mr. Xcoder

โอ้ใช่แน่นอนไม่ได้เห็นว่า
นาย Xcoder


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.

การใช้.Uบันทึกไบต์
Erik the Outgolfer

2

05AB1E , 27 ไบต์

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

ลองออนไลน์!


คุณรู้ไหมว่าทำไม„.»ไม่ทำงาน
Riley

@Riley »เป็นส่วนหนึ่งของสตริงการบีบอัดที่ยังไม่เสร็จดังนั้นจึงเกิดข้อผิดพลาดและตามปกติใน 05AB1E ข้อผิดพลาดจะถูกละเว้น
Erik the Outgolfer

ฉันพยายามที่จะทำ"*+-/"èUแล้วหลังจากใช้Lติดตามด้วย.»Xแต่ก็ถือว่าXเป็นสตริงไม่ใช่คำสั่งและ.»X.Vแม้จะชนะ
Magic Octopus Urn

@MagicOctopusUrn Xไม่ได้พิสูจน์ X.Vมีสองคำสั่ง
Erik the Outgolfer

@EriktheOutgolfer ใช่ แต่ฉันหวังว่ามันจะวิวัฒนาการก่อนประมวลผลการพับ หวังว่าไม่คาดหวัง :( อาจจะมีคำสาบานว่า "ใช้อักขระตัวเดียวเป็นคำสั่งในห่วงโซ่ย้อม" หรืออะไรทำนองนั้น
Magic Octopus Urn

2

Ruby , 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 's คำตอบ

คำอธิบาย:

ลองที่นี่

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
ฉันได้เห็นคำตอบที่คล้ายกันที่อื่น ... : ลืมเก็บ -DI ที่สั้นกว่าfloat double
ชาร์ลี

@CarlosAlejo ใช่ฉันสังเกตคำตอบของคุณหลังจาก 141 byte คำตอบเริ่มต้นของฉัน การเปลี่ยนfloat q=s.length()-(s=s.replace("!","")).length(),n=new Float(s)เป็นคำตอบปัจจุบันช่วยฉันได้ 5 ไบต์ :) ลืมที่จะเพิ่มส่วน " bytes บันทึกขอบคุณ " ฉันสังเกตเห็นตอนนี้ .. ขออภัยเกี่ยวกับเรื่องนี้
Kevin Cruijssen

โอ้ไม่เป็นไรฉันดีใจที่คุณชอบคำตอบของฉัน :-)
Charlie

2

เยลลี่ ,  24 23 26  25 ไบต์

+  3  2 ไบต์ปรับปรุงเพื่อแก้ไขหลังจากแปลความหมายผิด :(

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

โปรแกรมเต็มรูปแบบ (ลิงก์แบบ monadic พร้อมลิงก์ตัวช่วยอ้างอิงโดยตำแหน่งโปรแกรม)

ลองออนไลน์! หรือดูชุดทดสอบ

อย่างไร?

× - 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!ล้มเหลว
Erik the Outgolfer

โอ้ฮ่าฮ่า - ฉันได้อ่านความคิดเห็นของคุณภายใต้ OP ผิด - ฉันคิดว่าพวกเขาทำ 0! กำหนดเป็น 0 ซึ่งจะผิด
Jonathan Allan

ทั้งหมดได้รับการแก้ไขแล้ว :)
Jonathan Allan

TIO แย่เกินไปที่จะใช้งานไม่ได้ในขณะนี้ดังนั้นฉันจึงไม่สามารถทดสอบได้ว่ายังไม่ถูกต้องหรือไม่ :(: P ยังเลวร้ายเกินไปที่คุณจะไม่สามารถใช้/. ในรายการที่ว่างเปล่า D: แก้ไข: เห็นได้ชัดว่าถูกต้องสำหรับ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แต่ไม่ใช่รหัสเครื่องธรรมดาได้?

ลองกับ:

#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 คุณพูดถูก แก้ไขแล้ว.
Cristian Lupascu

ฉันคิดว่าคุณยังสามารถวาง parens รอบread nและf=ไม่จำเป็นต้องตามกฎของเรา
Zgarb

@Zgarb ใช่อีกครั้ง :) ขอบคุณ!
Cristian Lupascu

เปลี่ยนกลับไปใช้ฟังก์ชั่นและการใช้ชื่อบันทึกไบต์ที่สอง:lex f s|[(n,b)]<-lex s=read n!(length b-1)
nimi

@nimi ว้าวขอบคุณมาก! ฉันยังใหม่กับแฮสเค็ลล์ที่ฉันไม่รู้lexด้วยซ้ำ ที่น่ากลัว! :) ฉันไม่เห็นวิธีที่ช่วยประหยัดไบต์ - ฉันได้รับ 99 ไบต์หลังจากนี้
Cristian Lupascu

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 ไบต์

แรงบันดาลใจจากการแก้ปัญหาของ lstefano

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

ลองออนไลน์!

{} ฟังก์ชั่นที่ไม่ระบุชื่อโดยมีการโต้แย้ง :

0:: หากมีข้อผิดพลาดเกิดขึ้น:

  0 กลับศูนย์

 ตอนนี้ลอง:

  ⍵∩⎕D จุดตัดของการโต้แย้งและชุดของD igits (ลบเครื่องหมายอัศเจรีย์)

   ดำเนินการนั้น (เปลี่ยนเป็นตัวเลข)

  ɩ ndices ว่า

  ()/ insert (APL เชื่อมโยงถูกต้องตามความจำเป็น) ฟังก์ชันต่อไปนี้ระหว่างคำศัพท์:

   ⍵~⎕D อาร์กิวเมนต์ที่ไม่มีD igits (ออกจากเครื่องหมายอัศเจรีย์)

   นับว่า (เช่นกี่เครื่องหมายอัศเจรีย์)

  '×+-⌹'⊃⍨ ใช้สิ่งนั้นเพื่อเลือกจากรายการสัญลักษณ์ *

   ดำเนินการ (เปลี่ยนสัญลักษณ์เป็นฟังก์ชั่น)


(การหารเมทริกซ์) ใช้แทน÷(การหารปกติ) เพื่อทำให้เกิดข้อผิดพลาดในรายการว่าง


สิ่งที่ไม่::ทำใน DFN หรือไม่?
Zacharý

มันเป็นยามข้อผิดพลาด หาก ณ เวลาใด ๆ หลังจากตั้งค่าตัวป้องกันข้อผิดพลาดข้อผิดพลาดกับตัวเลขใด ๆ (0 = 1 … 999, 1000 = 1001 …) ทางด้านซ้ายของสิ่งที่::เกิดขึ้นจากนั้นค่าทางด้านขวาของ::จะถูกส่งกลับทันที
2560

ฉันไม่เคยรู้เรื่องนั้นเลยขอบคุณ!
Zacharý


0

Dyalog APL อย่างน้อย 29 ตัวอักษร

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

นิพจน์นั้นถูกต้องที่สุด มันผ่านทุกกรณีทดสอบยกเว้น0!!!!ที่ให้1แทนที่จะเป็นสิ่งที่จำเป็น0และนั่นเป็นเพราะใน APL การลดเวกเตอร์เปล่าควรจะคืนค่าองค์ประกอบที่เป็นกลางสำหรับฟังก์ชั่นที่ใช้ในการลด สำหรับความฉลาดทางที่ 1 ในขณะนี้ฉันไม่มีเวลาลองแก้ไข แต่ฉันจะทิ้งไว้ที่นี่ในวันที่ฝนตก


ฝนกำลังตก: {0::0⋄(⍎'×+-⌹'⊃⍨≢⍵~⎕D)/⍳⍎⍵∩⎕D} ลองออนไลน์!
Adám

เจ๋งมาก! ฉันไม่รังเกียจเลยถ้าคุณอ้างว่ามันเป็นทางออกของคุณเนื่องจากความแตกต่างนั้นมีมากกว่าความคล้ายคลึงกัน
lstefano



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

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)))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.