Tìm nhân tố!


74

Tạo chương trình hoặc hàm ngắn nhất tìm giai thừa của một số nguyên không âm.

Giai thừa, đại diện với !được định nghĩa như vậy

n!:={1n=0n(n1)!n>0

Trong tiếng Anh đơn giản, giai thừa của 0 là 1 và giai thừa của n, trong đó n lớn hơn 0 gấp n lần nhân tử của một nhỏ hơn n.

Mã của bạn nên thực hiện đầu vào và đầu ra bằng một phương thức tiêu chuẩn.

Yêu cầu:

  • Không sử dụng bất kỳ thư viện tích hợp nào có thể tính giai thừa (điều này bao gồm mọi hình thức eval)
  • Có thể tính giai thừa cho các số lên tới 125
  • Có thể tính giai thừa cho số 0 (bằng 1)
  • Hoàn thành trong vòng một phút cho các số lên tới 125

Bài nộp ngắn nhất sẽ thắng, trong trường hợp hòa, câu trả lời có nhiều phiếu nhất tại thời điểm đó sẽ thắng.


10
Có bao nhiêu câu trả lời cho trước thực sự có thể tính toán tới 125! không tràn số nguyên? Đó không phải là một trong những yêu cầu sao? Các kết quả dưới dạng xấp xỉ theo cấp số nhân có được chấp nhận không (ví dụ 125! = 1.88267718 × 10 ^ 209)?
Ami

6
@SHiNKiROU, ngay cả golfscript cũng có thể quản lý 125! ít hơn 1/10 giây và đó là ngôn ngữ được giải thích!
gnibbler

5
@ugoren giải pháp hai ký tự cho câu hỏi khác sử dụng chức năng giai thừa tích hợp. Điều đó không được phép trong phiên bản thử thách này.
Michael Stern

4
Hoàn thành trong một phút dường như là một yêu cầu rất phụ thuộc vào phần cứng. Hoàn thành trong một phút trên phần cứng gì?
sergiol

4
@sergiol Thật đáng kinh ngạc, đó không phải là vấn đề trong 2 năm qua, tôi nghi ngờ hầu hết các ngôn ngữ có thể thực hiện được trong vòng một phút.
Kevin Brown

Câu trả lời:


66

Golfscript - 12 ký tự

{,1\{)*}/}:f

Bắt đầu với Golfscript - Factorial từng bước

Đây là một cái gì đó cho những người đang cố gắng học golf. Điều kiện tiên quyết là sự hiểu biết cơ bản về golfscript và khả năng đọc tài liệu về golfscript.

Vì vậy, chúng tôi muốn thử chơi golf công cụ mới của chúng tôi . Luôn luôn tốt khi bắt đầu với một cái gì đó đơn giản, vì vậy chúng tôi bắt đầu với giai thừa. Đây là một nỗ lực ban đầu, dựa trên một mã giả mệnh lệnh đơn giản:

# pseudocode: f(n){c=1;while(n>1){c*=n;n--};return c}
{:n;1:c;{n 1>}{n c*:c;n 1-:n;}while c}:f

Khoảng trắng rất hiếm khi được sử dụng trong golfscript. Thủ thuật đơn giản nhất để thoát khỏi khoảng trắng là sử dụng các tên biến khác nhau. Mỗi mã thông báo có thể được sử dụng như một biến (xem trang cú pháp ). Tokens hữu ích để sử dụng như là các biến là các ký tự đặc biệt như |, &, ?- nói chung là bất cứ điều gì không được sử dụng ở những nơi khác trong các mã. Chúng luôn được phân tích cú pháp dưới dạng mã thông báo ký tự đơn. Ngược lại, các biến như nsẽ yêu cầu một khoảng trắng để đẩy một số vào ngăn xếp sau. Các số về cơ bản là các biến preinitialized.

Như mọi khi, sẽ có những tuyên bố mà chúng ta có thể thay đổi, mà không ảnh hưởng đến kết quả cuối cùng. Trong golfscript, tất cả mọi thứ để đánh giá đúng trừ 0, [], "", và {}(xem này ). Ở đây, chúng ta có thể thay đổi điều kiện thoát vòng lặp thành đơn giản {n}(chúng ta lặp một thời gian bổ sung và chấm dứt khi n = 0).

Như với việc chơi golf bất kỳ ngôn ngữ nào, nó giúp biết các chức năng có sẵn. May mắn là danh sách rất ngắn cho golfscript. Chúng tôi có thể thay đổi 1-để (cứu nhân vật khác. Hiện tại mã trông như thế này: (chúng ta có thể sử dụng 1thay vì |ở đây nếu chúng ta muốn, điều này sẽ làm giảm việc khởi tạo.)

{:n;1:|;{n}{n|*:|;n(:n;}while|}:f

Điều quan trọng là sử dụng ngăn xếp tốt để có được các giải pháp ngắn nhất (thực hành thực hành thực hành). Nói chung, nếu các giá trị chỉ được sử dụng trong một đoạn mã nhỏ, có thể không cần lưu trữ chúng thành các biến. Bằng cách loại bỏ biến sản phẩm đang chạy và chỉ cần sử dụng ngăn xếp, chúng ta có thể tiết kiệm được khá nhiều ký tự.

{:n;1{n}{n*n(:n;}while}:f

Đây là một cái gì đó khác để suy nghĩ. Chúng tôi sẽ loại bỏ biến nkhỏi ngăn xếp ở cuối thân vòng lặp, nhưng sau đó đẩy nó ngay sau đó. Trong thực tế, trước khi vòng lặp bắt đầu, chúng tôi cũng loại bỏ nó khỏi ngăn xếp. Thay vào đó, chúng ta nên để nó trên ngăn xếp và chúng ta có thể giữ điều kiện vòng lặp trống.

{1\:n{}{n*n(:n}while}:f

Có lẽ chúng ta thậm chí có thể loại bỏ hoàn toàn biến. Để làm điều này, chúng ta sẽ cần phải giữ biến trên ngăn xếp mọi lúc. Điều này có nghĩa là chúng ta cần hai bản sao của biến trên ngăn xếp ở cuối kiểm tra điều kiện để chúng ta không bị mất sau khi kiểm tra. Điều đó có nghĩa là chúng ta sẽ có một dự phòng 0trên ngăn xếp sau khi vòng lặp kết thúc, nhưng điều đó rất dễ khắc phục.

Điều này dẫn chúng ta đến whilegiải pháp vòng lặp tối ưu của chúng tôi !

{1\{.}{.@*\(}while;}:f

Bây giờ chúng tôi vẫn muốn làm cho điều này ngắn hơn. Mục tiêu rõ ràng nên là từ while. Nhìn vào tài liệu, có hai lựa chọn thay thế khả thi - mở ralàm . Khi bạn có lựa chọn các tuyến đường khác nhau, hãy thử và cân nhắc lợi ích của cả hai. Mở ra là "khá nhiều vòng lặp", vì vậy, theo ước tính, chúng tôi sẽ cắt giảm 5 ký tự whilexuống còn 4 /. Đối với do, chúng tôi cắt giảm while3 ký tự và hợp nhất hai khối, có thể lưu một hoặc hai ký tự khác.

Thực sự có một nhược điểm lớn khi sử dụng dovòng lặp. Vì kiểm tra điều kiện được thực hiện sau khi phần thân được thực thi một lần, giá trị của 0sẽ sai, vì vậy chúng ta có thể cần một câu lệnh if. Bây giờ tôi sẽ nói với bạn rằng mở ra ngắn hơn (một số giải pháp dođược cung cấp ở cuối). Hãy tiếp tục và thử nó, mã chúng tôi đã yêu cầu thay đổi tối thiểu.

{1\{}{.@*\(}/;}:f

Tuyệt quá! Giải pháp của chúng tôi bây giờ là siêu ngắn và chúng tôi đã hoàn thành, phải không? Không. Đây là 17 ký tự và J có 12 ký tự. Đừng bao giờ thừa nhận thất bại!


Bây giờ bạn đang suy nghĩ với ... đệ quy

Sử dụng đệ quy có nghĩa là chúng ta phải sử dụng cấu trúc rẽ nhánh. Thật không may, nhưng như giai thừa có thể được thể hiện một cách đệ quy ngắn gọn, điều này có vẻ như là một sự thay thế khả thi cho phép lặp.

# pseudocode: f(n){return n==0?n*f(n-1):1}
{:n{n.(f*}1if}:f # taking advantage of the tokeniser

Chà điều đó thật dễ dàng - nếu chúng ta đã thử đệ quy trước đó, chúng ta thậm chí có thể không nhìn vào việc sử dụng một whilevòng lặp! Tuy nhiên, chúng tôi chỉ có 16 ký tự.


Mảng

Mảng thường được tạo theo hai cách - sử dụng ký tự []ký tự hoặc với ,hàm. Nếu được thực hiện với một số nguyên ở đầu ngăn xếp, ,trả về một mảng có độ dài đó với mảng [i] = i.

Để lặp lại qua các mảng, chúng ta có ba tùy chọn:

  1. {block}/: đẩy, chặn, đẩy, chặn, ...
  2. {block}%: [đẩy, chặn, đẩy, chặn, ...] (điều này có một số sắc thái, ví dụ: các giá trị trung gian được xóa khỏi ngăn xếp trước mỗi lần đẩy)
  3. {block}*: đẩy, đẩy, chặn, đẩy, chặn, ...

Tài liệu golfscript có một ví dụ về việc sử dụng {+}*để tổng hợp nội dung của một mảng. Điều này cho thấy chúng ta có thể sử dụng {*}*để có được sản phẩm của một mảng.

{,{*}*}:f

Thật không may, nó không đơn giản như vậy. Tất cả các yếu tố được tắt bởi một ( [0 1 2]thay vì [1 2 3]). Chúng tôi có thể sử dụng {)}%để khắc phục vấn đề này.

{,{)}%{*}*}:f

Cũng không hẳn. Điều này không xử lý chính xác bằng không. Chúng ta có thể tính toán (n + 1)! / (N + 1) để khắc phục điều này, mặc dù chi phí này quá nhiều.

{).,{)}%{*}*\/}:f

Chúng ta cũng có thể thử xử lý n = 0 trong cùng một nhóm với n = 1. Đây là thực tế rất ngắn để làm, hãy thử và làm việc ngắn nhất bạn có thể.

Không tốt lắm là sắp xếp, ở 7 ký tự : [1\]$1=. Lưu ý rằng kỹ thuật sắp xếp này có các mục đích hữu ích, chẳng hạn như áp đặt các ranh giới trên một số (ví dụ: `[0 \ 100] $ 1 =)
Đây là người chiến thắng, chỉ có 3 ký tự:.! +

Nếu chúng ta muốn có số nhân và số nhân trong cùng một khối, chúng ta nên lặp lại trên mọi phần tử trong mảng. Vì chúng tôi không xây dựng một mảng, điều này có nghĩa là chúng tôi nên sử dụng {)*}/, điều này đưa chúng tôi đến giai đoạn triển khai bản golf ngắn nhất của giai thừa! Với độ dài 12 ký tự, điều này được gắn với J!

{,1\{)*}/}:f


Giải pháp thưởng

Bắt đầu với một ifgiải pháp đơn giản cho một dovòng lặp:

{.{1\{.@*\(.}do;}{)}if}:f

Chúng ta có thể vắt kiệt một vài thứ trong số này. Một chút phức tạp, vì vậy bạn sẽ phải thuyết phục bản thân những công việc này. Hãy chắc chắn rằng bạn hiểu tất cả những điều này.

{1\.!!{{.@*\(.}do}*+}:f
{.!{1\{.@*\(.}do}or+}:f
{.{1\{.@*\(.}do}1if+}:f

Một cách khác tốt hơn là tính toán (n + 1)! / (N + 1), loại bỏ sự cần thiết cho một ifcấu trúc.

{).1\{.@*\(.}do;\/}:f

Nhưng dogiải pháp ngắn nhất ở đây cần một vài ký tự để ánh xạ 0 đến 1 và mọi thứ khác cho chính nó - vì vậy chúng tôi không cần bất kỳ phân nhánh nào. Loại tối ưu hóa này là cực kỳ dễ bỏ lỡ.

{.!+1\{.@*\(.}do;}:f

Đối với bất kỳ ai quan tâm, một vài giải pháp đệ quy thay thế có cùng độ dài như trên được cung cấp tại đây:

{.!{.)f*0}or+}:f
{.{.)f*0}1if+}:f
{.{.(f*}{)}if}:f

* lưu ý: Tôi thực sự chưa kiểm tra nhiều đoạn mã trong bài đăng này, vì vậy hãy thông báo nếu có lỗi.


8
Thật thú vị, dường như là một lỗi trong phần đánh dấu spoiler khi bạn sử dụng mã trong một spoiler ... Bất cứ ai cũng quan tâm đề cập đến điều này trên Meta?
Ivo Flipse

5
Tôi thấy thật thú vị khi golfscript - một ngôn ngữ chơi gôn - cho phép các tên biến nhiều chữ cái và "trừng phạt" bạn vì đã sử dụng 1 chữ cái với khoảng trắng cần thiết
Cyoce 4/2/2016

44

Haskell, 17

f n=product[1..n]

2
Tôi không biết Haskell ... Nhưng liệu tính toán này có phải là 0
Vua

11
@ Vua: vâng, nó sẽ. [1..0] ==> []product [] ==> 1
JB

5
Tôi cho rằng điều này sử dụng "thư viện tích hợp" mà vấn đề cấm. Tuy nhiên, phương pháp khác f 0=1;f n=n*f$n-1là 17 ký tự.
everalmatt

5
@eternalmatt: đó là một phần của những hạn chế đối với tôi. Cả hai productvà, nói, (*)hoặc (-)"có thể tính giai thừa", và tất cả chúng đều được xác định thông qua Khúc dạo đầu. Tại sao một người sẽ được mát mẻ mà không phải là người khác?
JB

2
@YoYoYonnY: Tôi cũng đếm 17 ký tự, để dễ đọc (chủ quan). IMHO nó ổn trong các ý kiến.
JB

41

Con trăn - 27

Chỉ đơn giản vậy thôi:

f=lambda x:0**x or x*f(x-1)

22
Thủ thuật hay : 0**x.
Alexandru

Thế còn math.factorial? Nó không phải là một tích hợp, phải không?

1
@JackBates được tính là tích hợp, vì bạn không viết mã để tính giai thừa.
FlipTack

1
Bất cứ ai có thể cho tôi biết những gì lừa phía sau 0**x?
Pavitra

1
@Pavitra: 0 0 = 1, và đó là điều đầu tiên đánh giá để nó được trả về. Đối với bất kỳ n nào khác, 0 n = 0, do đó toán hạng đầu tiên của hoặc là falsey, sao cho toán hạng thứ hai được đánh giá.
Mega Man

29

APL (4)

×/∘⍳

Hoạt động như một chức năng ẩn danh:

    ×/∘⍳ 5
120

Nếu bạn muốn đặt tên cho nó, 6 ký tự:

f←×/∘⍳

Tôi không nói APL, chuyện gì đang xảy ra ở đây vậy?
Michael Stern

@MichaelStern: tạo một vectơ chỉ mục, nghĩa ⍳51 2 3 4 5. ×là (rõ ràng) nhân, /là giảm, và là thành phần chức năng. Vì vậy, ×/∘⍳là một hàm lấy một đối số xvà đưa ra tích của các số [1..x].
bến tàu

Ah, cách tiếp cận tương tự như trong giải pháp Mathicala của @Yves Klett. Rất đẹp.
Michael Stern

@NBZ: Điều đó chưa tồn tại vào năm 2011 khi câu hỏi này được viết, cũng như năm 2012 khi tôi viết câu trả lời này. Xe lửa chỉ được thêm vào trong Dyalog 14.0 xuất hiện vào năm 2014.
bến tàu

19

J (12)

Một định nghĩa chuẩn trong J:

f=:*/@:>:@i.

Chưa đến 1 giây cho 125!

Ví dụ:

 f 0
 1
 f 5
 120
  f 125x
 1882677176888926099743767702491600857595403
 6487149242588759823150835315633161359886688
 2932889495923133646405445930057740630161919
 3413805978188834575585470555243263755650071
 31770880000000000000000000000000000000

tại sao không chỉ * />: i. ?
Andbdrew

Bởi vì OP yêu cầu một chức năng và điều tốt nhất chúng ta có thể làm trong J là xác định một động từ.
Eelvex

2
Không có lý do gì nó không thể là một chức năng ẩn danh phải không? Giống như ([:*/1+i.)cho 10 điểm, hoặc thậm chí 8 là dấu ngoặc đơn chỉ cần thiết để gọi hàm, không phải cho định nghĩa.
jpjacobs

trong tác phẩm mới nhất, f 125xnhững gì hiện xlàm gì? Nó có phải là một loại số đặc biệt?
Cyoce

@Cyoce, vâng, đó là số nguyên chính xác mở rộng .
Eelvex

17

Golfscript - 13 ký tự (SYM)

định nghĩa hàm !

{),()\{*}/}:!             # happy robot version \{*}/ 

phiên bản thay thế 13 char

{),()+{*}*}:! 

toàn bộ phiên bản chương trình là 10 ký tự

~),()+{*}*

kiểm tra mất ít hơn 1/10 giây:

đầu vào:

0!

đầu ra

1

đầu vào

125!

đầu ra

188267717688892609974376770249160085759540364871492425887598231508353156331613598866882932889495923133646405445930057740630161919341380597818883457558547055524326375565007131770880000000000000000000000000000000

1
+1 cho mục nhập golf tượng trưng! Tôi ước tôi có thể nâng cao hơn một lần. :-D
Chris Jester-Young

@ ChrisJester-Young Tôi sẽ làm điều đó cho bạn.
Cyoce

13

Perl 6: 13 ký tự

$f={[*]1..$_}

[*]giống như Haskell product1..$_là đối số đếm từ 1 đến $_, đối số.


2
Không được phép không sử dụng khoảng trắng sau [*]nữa (thông báo lỗi "Hai thuật ngữ liên tiếp").
Konrad Borowski

Bạn không cần thiết lập một biến, một khối mã trần là một câu trả lời chấp nhận được vì nó hoàn toàn tạo thành một hàm. Ngoài ra điều này vẫn làm việc cho 0?
Phil H

10

Matlab, 15

f=@(x)prod(1:x)

Các trường hợp thử nghiệm

>> f(0)
ans =
     1
>> f(4)
ans =
    24
>> tic,f(125),toc
ans =
  1.8827e+209
Elapsed time is 0.000380 seconds.

10

Python, 28 byte

f=lambda x:x/~x+1or x*f(x-1)

(dựa trên giải pháp của Alexandru)


9

MATL , 2 byte

:p

Giải thích:

:    % generate list 1,2,3,...,i, where i is an implicit input
p    % calculate the product of of all the list entries (works on an empty list too)

Hãy thử trực tuyến!


10
: O
Andras Deak

Tôi sẽ đăng chính xác điều này :-) Bạn có thể muốn sửa đổi liên kết để bao gồm mã và một ví dụ đầu vào
Luis Mendo

Khi bạn chỉ huy, chúa của tôi.
flawr

4
@AndrasDeak, Không, sẽ xuất ra tất cả các số từ 1 đến i ...
YoYoYonnY

8

Ruby - 21 ký tự

f=->n{n>1?n*f[n-1]:1}

Kiểm tra

irb(main):009:0> f=->n{n>1?n*f[n-1]:1}
=> #<Proc:0x25a6d48@(irb):9 (lambda)>
irb(main):010:0> f[125]
=> 18826771768889260997437677024916008575954036487149242588759823150835315633161
35988668829328894959231336464054459300577406301619193413805978188834575585470555
24326375565007131770880000000000000000000000000000000

8

Java, 85 ký tự

BigInteger f(int n){return n<2?BigInteger.ONE:new BigInteger(""+n).multiply(f(n-1));}

1
Điều này bỏ lỡ việc nhập: import java.math.*;(vì vậy, +19 byte).
Olivier Grégoire

Điểm công bằng. ............
st0le

7

PostScript, 26 ký tự

/f{1 exch -1 1{mul}for}def

Thí dụ:

GS> 0 f =
1
GS> 1 f =
1
GS> 8 f =
40320

Bản thân hàm chỉ mất 21 ký tự; phần còn lại là liên kết nó với một biến. Để lưu một byte, người ta cũng có thể liên kết nó với một chữ số, như vậy:

GS> 0{1 exch -1 1{mul}for}def
GS> 8 0 load exec =
40320

1
Ghostscript không thể xử lý 125!; bất cứ điều gì ngoài 34! đi ra như 1.#INF. (Tôi đã sử dụng stock GNU Ghostscript 9.0.7 được biên dịch cho Windows x64.)
Ross Presser

7

JavaScript, 25

function f(n)!n||n*f(n-1)

Cà phê, 19

f=(n)->!n||n*f(n-1)

Trả về truetrong trường hợp n = 0, nhưng JavaScript sẽ gõ kiểu đó thành 1.


Bạn không cần một returncâu lệnh trong hàm JavaScript?
Justin Morgan

Cập nhật: Khói thánh, bạn không cần a return! Nhưng tại sao không?
Justin Morgan

Đó là JavaScript 1.8 ( developer.mozilla.org/en/new_in_javascript_1.8 ). Tiết lộ đầy đủ, nó chỉ hoạt động trên Firefox!
Casey Chu

1
Thật tuyệt, tôi không biết về việc bỏ qua câu lệnh return cho JavaScript 1.8. Ngoài ra, bạn có thể đảm bảo 1 thay vì đúng cho trường hợp n = 0 với cùng mã dài: function f(n)n?n*f(--n):1
Briguy37

10
ES6, 17: f=n=>!n||n*f(n-1)Lấy cái đó đi, CoffeeScript!
Ry-

6

Ruby - 30 29 ký tự

def f(n)(1..n).inject 1,:*end

Kiểm tra

f(0) -> 1
f(5) -> 120

1
Bạn có thể đặt endtrực tiếp sau :*mà không cần một dòng mới hoặc dấu chấm phẩy.
sepp2k

1
Không cần chuyển 1 đến cuộc gọi #inject. (1..10).inject :*# => 3628800
Dogbert

1
@Dogbert, còn về cái gì f(0)?
Nemo157

@ Nemo157, à! quên mất điều đó
Dogbert

4
Ngắn hơn để sử dụng cú pháp lambda 1.9 : f=->n{(1..n).inject 1,:*}. Gọi nó với f[n].
Michael Kohl

6

F #: 26 ký tự

Không có chức năng sản phẩm sẵn có trong F #, nhưng bạn có thể tạo một chức năng với một nếp gấp

let f n=Seq.fold(*)1{1..n}

6

C #, 20 hoặc 39 ký tự tùy theo quan điểm của bạn

Là một phương thức ví dụ truyền thống (39 ký tự; được thử nghiệm ở đây ):

double f(int x){return 2>x?1:x*f(x-1);}

Là một biểu thức lambda (20 ký tự, nhưng xem từ chối trách nhiệm; đã thử nghiệm ở đây ):

f=x=>2>x?1:x*f(x-1);

Chúng tôi phải sử dụng double125! == 1.88 * 10 209 , cao hơn nhiều so với ulong.MaxValue.

Tuyên bố miễn trừ trách nhiệm về số lượng nhân vật của phiên bản lambda:

Nếu bạn đệ quy trong lambda C #, rõ ràng bạn phải lưu trữ lambda trong một biến có tên để nó có thể tự gọi nó. Nhưng không giống như (ví dụ) JavaScript, lambda tự tham chiếu phải được khai báo và khởi tạo trên một dòng trước đó. Bạn không thể gọi hàm trong cùng một câu lệnh mà bạn khai báo và / hoặc khởi tạo biến.

Nói cách khác, điều này không hoạt động :

Func<int,double> f=x=>2>x?1:x*f(x-1); //Error: Use of unassigned local variable 'f'

Nhưng điều này không :

Func<int,double> f=null;            
f=x=>2>x?1:x*f(x-1);  

Không có lý do chính đáng cho hạn chế này, vì fkhông bao giờ được chỉ định tại thời điểm nó chạy. Sự cần thiết của Func<int,double> f=null;dòng là một sự giải thích của C #. Cho dù điều đó làm cho nó công bằng để bỏ qua nó trong số lượng nhân vật là tùy thuộc vào người đọc.

CoffeeScript, 21 19 ký tự cho thật

f=(x)->+!x||x*f x-1

Đã thử nghiệm tại đây: http://jsfiddle.net/0xjdm971/


6

Brachylog , 7 6 byte

Bằng cách tạo một phạm vi và nhân nó

Xe tăng -1 byte cho các lò nướng có ý tưởng sử dụng hàm max ()

;1⌉⟦₁×

Giải trình

;1          --  If n<1, use n=1 instead (zero case)
  ⟦₁        --      Construct the range [1,n]
    ×       --      return the product of said range

Hãy thử trực tuyến!


Brachylog , 10 9 byte

đệ quy

≤1|-₁↰;?×

Giải trình

            --f(n):
≤1          --  if n ≤ 1: return 1
|           --  else:
 -₁↰        --      f(n-1)
    ;?×     --            *n

Hãy thử trực tuyến!


1
Điều này làm việc cho 6 byte. Lấy đầu vào là một singleton được cho phép theo mặc định.
trứng

@ovs cảm ơn. Nhưng sử dụng ;thay vì ,cho phép chỉ là một đầu vào số thông thường. -1byte anyway
Kroppeb

5

C (39 ký tự)

double f(int n){return n<2?1:n*f(n-1);}

3
Đẹp. Nhưng có thể lưu một số ký tự: double f(n){return!n?1:n*f(n-1);}- 33 ký tự.
ugoren

2
f(125)sẽ tràn
jkabrg

4

D: 45 ký tự

T f(T)(T n){return n < 2 ? 1 : n * f(n - 1);}

Dễ đọc hơn:

T f(T)(T n)
{
    return n < 2 ? 1 : n * f(n - 1);
}

Một bộ làm mát (mặc dù phiên bản dài hơn) là một bộ templatized thực hiện tất cả tại thời gian biên dịch ( 64 ký tự ):

template F(int n){static if(n<2)enum F=1;else enum F=n*F!(n-1);}

Dễ đọc hơn:

template F(int n)
{
    static if(n < 2)
        enum F = 1;
    else
        enum F = n * F!(n - 1);
}

Các mẫu Eponymous khá dài dòng, vì vậy bạn thực sự không thể sử dụng chúng trong mã golf rất tốt. D đã đủ dài dòng về số lượng nhân vật khá kém đối với môn đánh gôn (mặc dù nó thực sự rất tốt trong việc giảm kích thước chương trình tổng thể cho các chương trình lớn hơn). Mặc dù đó là ngôn ngữ yêu thích của tôi, vì vậy tôi cho rằng tôi cũng có thể thử và xem tôi có thể làm nó tốt như thế nào ở môn đánh gôn, ngay cả khi những người thích GolfScript bị ràng buộc với kem.


3
lấy ra khoảng trắng và bạn có thể giảm xuống còn 36 ký tự
ratchet freak

@Cyoce Bạn có thể giải thích?
YoYoYonnY

Chào mừng đến với trang web, @ user272735. Lưu ý rằng chúng tôi không chỉnh sửa các giải pháp của mọi người để cải thiện ở đây. Thay vào đó, chúng tôi để lại ý kiến ​​đề xuất những cải tiến đó, như ratchet freak đã làm ở trên.
Xù xì

4

PowerShell - 36

Ngây thơ:

filter f{if($_){$_*(--$_|f}else{1}}

Kiểm tra:

> 0,5,125|f
1
120
1,88267717688893E+209

4

Scala, 39 ký tự

def f(x:BigInt)=(BigInt(1)to x).product

Hầu hết các ký tự đều đảm bảo rằng BigInts được sử dụng để đáp ứng yêu cầu về giá trị lên tới 125.


Một số tùy chọn ngắn hơn:(x:Int)=>(BigInt(1)to x).product def f(x:Int)=(BigInt(1)to x).product def f(x:BigInt)=(x.to(1,-1)).product def f(x:BigInt)=(-x to-1).product.abs
LRLucena

4

Javascript, ES6 17

f=n=>n?n*f(n-1):1

ES6:

  • Chức năng mũi tên

ES6 trẻ hơn thử thách này nếu tôi nhớ chính xác và do đó không đủ điều kiện.
lirtosiast

Có smth lạ với toán tử có điều kiện. Tại sao có hai dấu hai chấm?
Qwertiy

@Qwertiy Bạn nói đúng, đó là một lỗi đánh máy, cảm ơn.
Afonso Matos

4

PowerShell, 42 byte

(đã lưu 2 ký tự bằng bộ lọc thay vì chức năng )

filter f($x){if(!$x){1}else{$x*(f($x-1))}}

Đầu ra:

PS C:\> f 0
1
PS C:\> f 5
120
PS C:\> f 1
1
PS C:\> f 125
1.88267717688893E+209

1
Bây giờ cách này đã cũ, nhưng ... Có thể lưu thêm 1 ký tự bằng cách đảo ngược if / other : filter f($x){if($x){$x*(f($x-1))}else{1}}. Và nó có thể được giảm xuống còn 36 ký tự nếu được gọi thông qua đường ống vì đó là bộ lọc (ví dụ 125|f):filter f{if($_){$_*($_-1|f)}else{1}}
Andrew

4

Vợt (sơ đồ) 40 35 29 byte

Tính 0! là 1 và tính 125! trong 0 giây theo bộ đếm thời gian. Phương pháp đệ quy thường xuyên

(define(f n)(if(= n 0)1(* n(f(- n 1)))))

Phiên bản mới để đánh bại lisp phổ biến: nhân tất cả các yếu tố của danh sách (giống như giải pháp Haskell)

(λ(n)(apply *(build-list n add1)))

Phiên bản mới hơn để đánh bại giải pháp sơ đồ khác và tính toán giải pháp vợt khác bằng cách sử dụng Foldl thay vì áp dụng và sử dụng phạm vi thay vì danh sách xây dựng

(λ(n)(foldl * n(range 1 n)))

4

Lưỡi liềm Mornington , 1827 1698 chars

Tôi cảm thấy muốn học một ngôn ngữ mới ngày hôm nay, và đây là điều tôi đã đạt được ... (Tại sao tôi làm điều này với chính mình?) Mục này sẽ không giành được bất kỳ giải thưởng nào, nhưng nó đánh bại tất cả 0 câu trả lời khác cho đến nay bằng cách sử dụng cùng ngôn ngữ!

Take Northern Line to Bank
Take Central Line to Holborn
Take Piccadilly Line to Heathrow Terminals 1, 2, 3
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Parsons Green
Take District Line to Bank
Take District Line to Parsons Green
Take District Line to Acton Town
Take District Line to Hammersmith
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Parsons Green
Take District Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take Circle Line to Bank
Take Circle Line to Temple
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Bank
Take District Line to Upney
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Upney
Take District Line to Bank
Take Circle Line to Embankment
Take Circle Line to Embankment
Take Northern Line to Angel
Take Northern Line to Moorgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Mornington Crescent

Hãy thử trực tuyến!

Tất cả những ai đi du lịch vòng quanh London đều hiểu điều đó ngay lập tức, vì vậy tôi chắc chắn rằng tôi không cần phải giải thích đầy đủ.

Hầu hết các công việc khi bắt đầu là trong việc xử lý trường hợp 0. Sau khi khởi tạo sản phẩm ở mức 1, tôi có thể sử dụng số đó để tính max (đầu vào, 1) để có đầu vào mới, tận dụng thực tế là 0! = 1! Sau đó, vòng lặp chính có thể bắt đầu.

(EDIT: Toàn bộ các chuyến đi đã được lưu bằng cách tước 1 từ "Thiết bị đầu cuối Heathrow 1, 2, 3" thay vì tạo ra nó bằng cách chia 7 (Chị em) cho chính nó. Tôi cũng sử dụng một phương pháp rẻ hơn để tạo -1 trong bước tiếp theo.)

Giảm giá là đắt ở Mornington Crescent (mặc dù rẻ hơn so với bản thân Tube). Để làm cho mọi thứ hiệu quả hơn, tôi tạo -1 bằng cách lấy KHÔNG của 0 được phân tích cú pháp và lưu trữ trong Hammersmith trong phần lớn vòng lặp.


Tôi đã đặt một số công việc quan trọng vào việc này, nhưng vì đây là nỗ lực đầu tiên của tôi khi chơi golf ở Mornington Crescent (thực tế là nỗ lực đầu tiên của tôi trong bất kỳ ngôn ngữ nào ), tôi hy vọng tôi đã bỏ lỡ một vài điều tối ưu ở đây và đó. Nếu bạn quan tâm đến việc lập trình bằng ngôn ngữ này cho chính mình (và tại sao bạn lại không?), IDE bí truyền - với chế độ gỡ lỗi và cửa sổ xem - là điều bắt buộc!


3

Befunge - 2x20 = 40 ký tự

0\:#v_# 1#<\$v *\<
    >:1-:#^_$>\:#^_$

Đây là một chức năng trong đó nó là một khối mã độc lập không sử dụng gói. Bạn phải đặt đối số lên trên cùng của ngăn xếp sau đó nhập từ trên cùng bên trái sang phải, hàm sẽ thoát từ dưới cùng bên phải sang phải với kết quả trên đỉnh của ngăn xếp.

Ví dụ để tính giai thừa của 125

555**   0\:#v_# 1#<\$v *\<
            >:1-:#^_$>\:#^_$    .@

Kiểm tra 0

0   0\:#v_# 1#<\$v *\<
        >:1-:#^_$>\:#^_$    .@

Tôi biết điều này khá cũ, nhưng tôi nghĩ rằng điều này có phần ngắn hơn và nhanh hơn: &:!#@_>:# 1# -# :# _$>\# :#* _$.@(nơi & nên được thay thế bằng đầu vào). Đó là 32 ký tự / byte
FliiFe

3

J - 6 ký tự

*/>:i.

Điều này có tính không? Tôi biết nó rất giống với ví dụ J trước đó, nhưng nó ngắn hơn một chút :)

Tôi là người mới bắt đầu với J, nhưng cho đến nay nó vẫn rất vui!


3

Trong C (23 ký tự)

Điều này lạm dụng "tính năng" GCC làm cho phép gán cuối cùng được tính là trả lại nếu không có lợi nhuận nào được chỉ định.

f(a){a=a>0?f(a-1)*a:1;}

Trong C, 28 ký tự

f(a){return a>0?f(a-1)*a:1;}

+1 cho "tính năng" GCC. Tôi nghĩ GCC thậm chí còn cho phép giá trị trả về khối (Có thể nhớ làm điều gì đó như thế này)0 == ({printf("Hello, world!"); 0;});
YoYoYonnY

3

Kona ( 11 6)

*/1.+!

K hoạt động từ phải sang trái (đối với hầu hết các phần), vì vậy chúng tôi liệt kê x(tạo một danh sách / mảng các số từ 0đến x-1), thêm 1vào đó (danh sách phạm vi 0đến x), sau đó nhân tất cả các số với nhau. Nếu nó không phải là một yêu cầu để tính toán 125!, tôi có thể tiết kiệm thêm 1 byte bằng cách loại bỏ .bên cạnh 1. Trong mọi trường hợp, 125! được tính bằng mili giây:

  */1.+!125.
1.882677e+209

Bạn không cần nhiều thứ này. K có currying, vì vậy toàn bộ câu trả lời trở thành */1.+!: 6 byte.
kirbyfan64sos

@ kirbyfan64sos: Đúng và tôi sẽ chỉnh sửa nó. Tôi nghĩ khi tôi viết bài này ~ 18 tháng trước, tôi vẫn bị mắc kẹt trên mọi thứ phải có thể gọi được (nghĩa là chức năng).
Kyle Kanos
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.