Temukan faktorial!

74

Buat program atau fungsi terpendek yang menemukan faktorial dari integer non-negatif.

Faktorial, diwakili dengan !didefinisikan sebagai demikian

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

Dalam bahasa Inggris biasa faktorial 0 adalah 1 dan faktorial n, di mana n lebih besar dari 0 adalah n kali faktorial satu kurang dari n.

Kode Anda harus melakukan input dan output menggunakan metode standar.

Persyaratan:

  • Tidak menggunakan perpustakaan bawaan yang dapat menghitung faktorial (ini termasuk segala bentuk eval)
  • Dapat menghitung faktorial untuk angka hingga 125
  • Dapat menghitung faktorial untuk angka 0 (sama dengan 1)
  • Selesai dalam waktu kurang dari satu menit untuk angka hingga 125

Pengajuan terpendek menang, dalam kasus seri, jawabannya dengan suara terbanyak pada saat menang.

Kevin Brown
sumber
10
Berapa banyak jawaban yang diberikan yang dapat menghitung hingga 125! tanpa integer overflow? Bukankah itu salah satu persyaratannya? Apakah hasil sebagai perkiraan eksponensial dapat diterima (mis. 125! = 1.88267718 × 10 ^ 209)?
Ami
6
@SHiNKiROU, bahkan skrip golf dapat mengelola 125! kurang dari 1/10 detik dan itu dan ditafsirkan bahasa!
gnibbler
5
@ugoren solusi dua karakter untuk pertanyaan lain menggunakan fungsi faktorial bawaan. Itu tidak diizinkan dalam versi tantangan ini.
Michael Stern
4
Selesai dalam waktu kurang dari satu menit tampaknya merupakan persyaratan yang sangat bergantung pada perangkat keras. Selesai kurang dari satu menit pada perangkat keras apa?
sergiol
4
@sergiol Luar biasa yang tidak menjadi masalah dalam 2 tahun terakhir, saya menduga sebagian besar bahasa dapat menyelesaikannya dalam waktu kurang dari satu menit.
Kevin Brown

Jawaban:

66

Golfscript - 12 karakter

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

Memulai dengan Golfscript - Faktorial selangkah demi selangkah

Ini ada sesuatu untuk orang-orang yang mencoba belajar skrip golf. Prasyarat adalah pemahaman dasar tentang skrip golf, dan kemampuan untuk membaca dokumentasi skrip golf.

Jadi kami ingin mencoba skrip golf alat baru kami . Itu selalu baik untuk memulai dengan sesuatu yang sederhana, jadi kita mulai dengan faktorial. Berikut ini adalah upaya awal, berdasarkan kodesemu imperatif sederhana:

# 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

Spasi sangat jarang digunakan dalam skrip golf. Trik termudah untuk menyingkirkan spasi putih adalah dengan menggunakan nama variabel yang berbeda. Setiap token dapat digunakan sebagai variabel (lihat halaman sintaks ). Token berguna untuk digunakan sebagai variabel karakter khusus seperti |, &, ?- umumnya apa pun tidak digunakan di tempat lain dalam kode. Ini selalu diuraikan sebagai token karakter tunggal. Sebaliknya, variabel seperti nakan membutuhkan ruang untuk mendorong nomor ke tumpukan setelahnya. Angka pada dasarnya adalah variabel yang diinisialisasi.

Seperti biasa, akan ada pernyataan yang bisa kita ubah, tanpa mempengaruhi hasil akhirnya. Dalam golfscript, semuanya mengevaluasi untuk benar kecuali 0, [], "", dan {}(lihat ini ). Di sini, kita dapat mengubah kondisi keluar loop menjadi sederhana {n}(kita loop waktu tambahan, dan berakhir ketika n = 0).

Seperti halnya bermain golf bahasa apa pun, ada baiknya mengetahui fungsi yang tersedia. Untungnya daftar ini sangat pendek untuk skrip golf. Kita dapat mengubah 1-untuk (menyelamatkan karakter lain. Saat ini kodenya terlihat seperti ini: (kita bisa menggunakan 1alih-alih di |sini jika kita mau, yang akan menghilangkan inisialisasi.)

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

Penting untuk menggunakan tumpukan dengan baik untuk mendapatkan solusi terpendek (latihan praktik praktik). Secara umum, jika nilai hanya digunakan dalam segmen kode yang kecil, mungkin tidak perlu menyimpannya ke dalam variabel. Dengan menghapus variabel produk yang sedang berjalan dan hanya menggunakan tumpukan, kita dapat menyimpan cukup banyak karakter.

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

Ada hal lain untuk dipikirkan. Kami menghapus variabel ndari tumpukan di akhir badan loop, tetapi kemudian mendorongnya segera setelah itu. Bahkan, sebelum loop dimulai kami juga menghapusnya dari stack. Kita seharusnya membiarkannya di stack, dan kita bisa menjaga kondisi loop kosong.

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

Mungkin kita bahkan bisa menghilangkan variabel sepenuhnya. Untuk melakukan ini, kita harus menyimpan variabel di stack setiap saat. Ini berarti bahwa kita memerlukan dua salinan variabel pada tumpukan di akhir pemeriksaan kondisi sehingga kita tidak kehilangannya setelah pemeriksaan. Yang berarti bahwa kita akan memiliki redundan 0pada stack setelah loop berakhir, tetapi itu mudah diperbaiki.

Ini membawa kita ke whilesolusi loop optimal kami !

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

Sekarang kami masih ingin membuat ini lebih pendek. Target yang jelas harus menjadi kata while. Melihat dokumentasi, ada dua alternatif yang layak - buka dan lakukan . Ketika Anda memiliki pilihan rute yang berbeda untuk diambil, coba dan timbang manfaat keduanya. Buka lipatan adalah 'cukup banyak loop sementara', sehingga sebagai perkiraan kami akan memotong 5 karakter whiledengan 4 menjadi /. Adapun do, kami memotong while3 karakter, dan bisa menggabungkan dua blok, yang mungkin menyimpan satu atau dua karakter lain.

Sebenarnya ada kelemahan besar untuk menggunakan doloop. Karena pemeriksaan kondisi dilakukan setelah tubuh dieksekusi sekali, nilai 0akan salah, jadi kita mungkin perlu pernyataan if. Saya akan memberi tahu Anda sekarang bahwa lipatan lebih singkat (beberapa solusi dengan dodisediakan di akhir). Silakan dan coba, kode yang sudah kita miliki membutuhkan perubahan minimal.

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

Bagus! Solusi kami sekarang sangat singkat dan kami selesai di sini, kan? Nggak. Ini adalah 17 karakter, dan J memiliki 12 karakter. Jangan pernah mengakui kekalahan!


Sekarang Anda berpikir dengan ... rekursi

Menggunakan rekursi berarti kita harus menggunakan struktur percabangan. Sayangnya, tetapi karena faktorial dapat diekspresikan dengan ringkas secara rekursif, ini sepertinya merupakan alternatif yang layak untuk iterasi.

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

Yah itu mudah - seandainya kita mencoba rekursi sebelumnya kita mungkin bahkan tidak pernah melihat menggunakan whileloop Namun, kami hanya memiliki 16 karakter.


Array

Array umumnya dibuat dalam dua cara - menggunakan karakter [dan ], atau dengan ,fungsi. Jika dieksekusi dengan integer di bagian atas tumpukan, ,mengembalikan array dengan panjang itu dengan arr [i] = i.

Untuk iterating over array, kami memiliki tiga opsi:

  1. {block}/: push, block, push, block, ...
  2. {block}%: [push, block, push, block, ...] (ini memiliki beberapa nuansa, misalnya nilai menengah dihapus dari tumpukan sebelum setiap dorongan)
  3. {block}*: push, push, block, push, block, ...

Dokumentasi skrip golf memiliki contoh penggunaan {+}*untuk menjumlahkan isi dari suatu array. Ini menyarankan kita dapat menggunakan {*}*untuk mendapatkan produk dari array.

{,{*}*}:f

Sayangnya, itu tidak sesederhana itu. Semua elemen dimatikan oleh satu ( [0 1 2]bukan [1 2 3]). Kita dapat menggunakan {)}%untuk memperbaiki masalah ini.

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

Ya tidak cukup. Ini tidak menangani nol dengan benar. Kita dapat menghitung (n +1)! / (N +1) untuk memperbaiki ini, meskipun ini biayanya terlalu banyak.

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

Kami juga dapat mencoba menangani n = 0 dalam keranjang yang sama dengan n = 1. Ini sebenarnya sangat singkat untuk dilakukan, coba dan kerjakan sesingkat mungkin.

Tidak begitu baik adalah menyortir, pada 7 karakter: [1\]$1=. Perhatikan bahwa teknik penyortiran ini memang memiliki tujuan yang bermanfaat, seperti memaksakan batasan pada angka (mis. `[0 \ 100] $ 1 =)
Inilah pemenangnya, dengan hanya 3 karakter:. +

Jika kita ingin memiliki kenaikan dan perkalian di blok yang sama, kita harus mengulangi setiap elemen dalam array. Karena kita tidak membangun array, ini berarti kita harus menggunakan {)*}/, yang membawa kita ke implementasi skrip golf terpendek dari faktorial! Panjangnya 12 karakter, ini terkait dengan J!

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


Solusi bonus

Dimulai dengan ifsolusi langsung untuk satu doloop:

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

Kita bisa memeras beberapa tambahan dari ini. Agak rumit, jadi Anda harus meyakinkan diri sendiri bahwa ini berhasil. Pastikan Anda memahami semua ini.

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

Alternatif yang lebih baik adalah menghitung (n +1)! / (N +1), yang menghilangkan kebutuhan akan suatu ifstruktur.

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

Tetapi dosolusi terpendek di sini membutuhkan beberapa karakter untuk memetakan 0 ke 1, dan yang lainnya untuk dirinya sendiri - jadi kita tidak perlu bercabang. Optimalisasi semacam ini sangat mudah untuk dilewatkan.

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

Bagi siapa pun yang tertarik, beberapa solusi rekursif alternatif dengan panjang yang sama seperti di atas disediakan di sini:

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

* catatan: Saya belum benar-benar menguji banyak bagian kode dalam posting ini, jadi jangan ragu untuk memberi tahu jika ada kesalahan.

Nabb
sumber
8
Menarik, sepertinya ada bug dalam penurunan harga spoiler saat Anda menggunakan kode dalam spoiler ... Adakah yang mau menyebutkan ini di Meta?
Ivo Flipse
5
Saya merasa menarik bagaimana golfscript - bahasa golf - memungkinkan nama variabel multi-huruf dan "menghukum" Anda karena menggunakan 1 huruf dengan spasi yang diperlukan
Cyoce
44

Haskell, 17

f n=product[1..n]
JB
sumber
2
Saya tidak tahu Haskell ... Tetapi apakah ini akan menghitung faktorial untuk 0
The King
11
@ Raja: ya itu akan terjadi. [1..0] ==> []danproduct [] ==> 1
JB
5
Saya berpendapat ini menggunakan "built-in library" yang dilarang oleh masalah. Namun, metode lainnya f 0=1;f n=n*f$n-1adalah 17 karakter juga.
eternalmatt
5
@eternalmatt: bagian dari pembatasan itu tidak ditentukan oleh saya. Keduanya productdan, katakanlah, (*)atau (-)"dapat menghitung faktorial", dan semuanya ditentukan melalui Pendahuluan. Mengapa yang satu keren dan yang lainnya tidak?
JB
2
@YoYoYonnY: Saya menghitung 17 karakter juga, untuk keterbacaan yang kurang (subyektif). IMHO tidak apa-apa di komentar.
JB
41

Python - 27

Cukup sederhana:

f=lambda x:0**x or x*f(x-1)
0xKirill
sumber
22
Baik trik: 0**x.
Alexandru
Bagaimana dengan math.factorial? Itu bukan built-in, kan?
1
@JackBates yang dianggap sebagai builtin, karena Anda tidak menulis kode untuk menghitung faktorial.
FlipTack
1
Adakah yang bisa memberi tahu saya apa trik di baliknya 0**x?
Pavitra
1
@Pavitra: 0 0 = 1, dan ini adalah hal pertama yang mengevaluasi sehingga dikembalikan. Untuk n lain, 0 n = 0, maka operan pertama atau adalah falsey, sehingga operan kedua dievaluasi.
Mega Man
29

APL (4)

×/∘⍳

Berfungsi sebagai fungsi anonim:

    ×/∘⍳ 5
120

Jika Anda ingin memberi nama, 6 karakter:

f←×/∘⍳
marinus
sumber
Saya tidak berbicara APL, apa yang terjadi di sini?
Michael Stern
@MichaelStern: membuat vektor indeks, yaitu ⍳5adalah 1 2 3 4 5. ×adalah (jelas) bertambah banyak, /mengurangi, dan merupakan komposisi fungsi. Jadi, ×/∘⍳adalah fungsi yang mengambil argumen xdan memberikan produk angka [1..x].
marinus
Ah, pendekatan yang sama seperti pada solusi Mathematica @Yves Klett. Sangat bagus.
Michael Stern
@NBZ: Itu belum ada pada 2011 ketika pertanyaan ini ditulis, atau pada 2012 ketika saya menulis jawaban ini. Kereta hanya ditambahkan dalam Dyalog 14.0 yang keluar pada 2014.
marinus
19

J (12)

Definisi standar dalam J:

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

Kurang dari 1detik untuk 125!

Misalnya:

 f 0
 1
 f 5
 120
  f 125x
 1882677176888926099743767702491600857595403
 6487149242588759823150835315633161359886688
 2932889495923133646405445930057740630161919
 3413805978188834575585470555243263755650071
 31770880000000000000000000000000000000
Eelvex
sumber
mengapa tidak hanya * />: i. ?
Andbdrew
Karena OP meminta fungsi dan yang terbaik yang bisa kita lakukan dalam J adalah mendefinisikan kata kerja.
Eelvex
2
Tidak ada alasan itu tidak bisa menjadi fungsi anonim bukan? Seperti ([:*/1+i.)untuk 10 poin, atau bahkan 8 sebagai tanda kurung hanya diperlukan untuk memanggil fungsi, bukan untuk definisi.
jpjacobs
di yang terakhir, f 125xapa fungsinya x? Apakah ini nomor khusus?
Cyoce
@Cyoce, ya, bilangan bulat presisi diperluas .
Eelvex
17

Golfscript - 13 karakter (SYM)

mendefinisikan fungsi !

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

alternatif versi 13 char

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

seluruh versi program adalah 10 karakter

~),()+{*}*

testcases membutuhkan waktu kurang dari 1/10 detik:

memasukkan:

0!

keluaran

1

memasukkan

125!

keluaran

188267717688892609974376770249160085759540364871492425887598231508353156331613598866882932889495923133646405445930057740630161919341380597818883457558547055524326375565007131770880000000000000000000000000000000
gnibbler
sumber
1
+1 untuk entri golf simbolik! Saya berharap saya bisa lebih memilih sekali. :-D
Chris Jester-Young
@ ChrisJester-Young, saya akan melakukannya untuk Anda.
Cyoce
13

Perl 6: 13 karakter

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

[*]sama dengan Haskell product, dan 1..$_merupakan hitungan dari 1 hingga $_, argumen.

Ming-Tang
sumber
2
Tidak diperbolehkan untuk tidak menggunakan spasi [*]lagi (pesan kesalahan "Dua istilah dalam satu baris").
Konrad Borowski
Anda tidak perlu mengatur variabel, blok kode kosong adalah jawaban yang dapat diterima karena secara implisit membentuk fungsi. Apakah ini masih bekerja untuk 0?
Phil H
10

Matlab, 15

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

Uji Kasus

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

Python, 28 byte

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

(berdasarkan solusi Alexandru)

Ya ampun
sumber
9

MATL , 2 byte

:p

Dijelaskan:

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

Cobalah online!

cacat
sumber
10
: O
Andras Deak
Saya akan memposting persis ini :-) Anda mungkin ingin memodifikasi tautan untuk memasukkan kode dan contoh input
Luis Mendo
Seperti yang Anda perintahkan, tuanku.
flawr
4
@AndrasDeak, Tidak, itu akan menampilkan semua angka dari 1 hingga saya ...
YoYoYonnY
8

Ruby - 21 karakter

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

Uji

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
Dogbert
sumber
8

Java, 85 Karakter

BigInteger f(int n){return n<2?BigInteger.ONE:new BigInteger(""+n).multiply(f(n-1));}
st0le
sumber
1
Ini melewatkan impor: import java.math.*;(jadi, +19 byte).
Olivier Grégoire
Titik adil. ............
st0le
7

PostScript, 26 karakter

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

Contoh:

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

Fungsi itu sendiri hanya membutuhkan 21 karakter; sisanya untuk mengikatnya ke variabel. Untuk menyimpan byte, seseorang juga dapat mengikatnya ke digit, seperti:

GS> 0{1 exch -1 1{mul}for}def
GS> 8 0 load exec =
40320
KirarinSnow
sumber
1
Ghostscript tidak dapat menangani 125!; apapun yang melebihi 34! keluar sebagai 1.#INF. (Saya menggunakan stock GNU Ghostscript 9.0.7 yang dikompilasi untuk Windows x64.)
Ross Presser
7

JavaScript, 25

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

CoffeeScript, 19

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

Mengembalikan truedalam kasus n = 0, tetapi JavaScript akan mengetik-memaksa itu menjadi 1.

Casey Chu
sumber
Apakah Anda tidak memerlukan returnpernyataan dalam fungsi JavaScript?
Justin Morgan
Perbarui: Asap suci, Anda tidak perlu return! Namun mengapa tidak?
Justin Morgan
Ini JavaScript 1.8 ( developer.mozilla.org/id/new_in_javascript_1.8 ). Pengungkapan penuh, ini hanya bekerja di Firefox!
Casey Chu
1
Bagus, saya tidak tahu tentang meninggalkan pernyataan kembali untuk JavaScript 1.8. Juga, Anda dapat menjamin 1 sebagai ganti true untuk kasus n = 0 dengan kode panjang yang sama: function f(n)n?n*f(--n):1
Briguy37
10
ES6, 17: f=n=>!n||n*f(n-1)Ambil itu, CoffeeScript!
Ry-
6

Ruby - 30 29 karakter

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

Uji

f(0) -> 1
f(5) -> 120
Arnaud Le Blanc
sumber
1
Anda dapat menempatkan endlangsung setelah :*tanpa baris baru atau titik koma.
sepp2k
1
Tidak perlu meneruskan 1 ke panggilan #inject. (1..10).inject :*# => 3628800
Dogbert
1
@Dogbert, untuk apa f(0)?
Nemo157
@ Nemo157, ah! lupa tentang itu.
Dogbert
4
Yang lebih pendek untuk menggunakan 1,9 sintaks lambda: f=->n{(1..n).inject 1,:*}. Sebut saja dengan f[n].
Michael Kohl
6

F #: 26 karakter

Tidak ada fungsi produk bawaan di F #, tetapi Anda dapat membuatnya dengan lipatan

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

C #, 20 atau 39 karakter tergantung pada sudut pandang Anda

Sebagai metode contoh tradisional (39 karakter; diuji di sini ):

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

Sebagai ungkapan lambda (20 karakter, tetapi lihat penafian; diuji di sini ):

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

Kami harus menggunakan doublekarena 125! == 1.88 * 10 209 , yang jauh lebih tinggi dari ulong.MaxValue.

Penafian tentang jumlah karakter versi lambda:

Jika Anda rekursi dalam C # lambda, Anda jelas harus menyimpan lambda dalam variabel bernama sehingga dapat memanggil dirinya sendiri. Tetapi tidak seperti (misalnya) JavaScript, lambda referensi-diri harus dideklarasikan dan diinisialisasi pada baris sebelumnya. Anda tidak dapat memanggil fungsi dalam pernyataan yang sama di mana Anda mendeklarasikan dan / atau menginisialisasi variabel.

Dengan kata lain, ini tidak berhasil :

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

Tapi ini memang :

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

Tidak ada alasan yang baik untuk pembatasan ini, karena ftidak pernah dapat ditetapkan pada saat dijalankan. Perlunya Func<int,double> f=null;baris adalah kekhasan dari C #. Apakah itu membuatnya adil untuk mengabaikannya dalam hitungan karakter, tergantung pada pembaca.

CoffeeScript, 21 19 karakter nyata

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

Diuji di sini: http://jsfiddle.net/0xjdm971/

Justin Morgan
sumber
6

Brachylog , 7 6 byte

Dengan membuat rentang dan mengalikannya

Tangki -1 byte ke ovs memiliki ide untuk menggunakan fungsi max ()

;1⌉⟦₁×

Penjelasan

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

Cobalah online!


Brachylog , 10 9 byte

pengulangan

≤1|-₁↰;?×

Penjelasan

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

Cobalah online!

Kroppeb
sumber
1
Ini bekerja selama 6 byte. Mengambil input sebagai singleton diizinkan secara default.
Ovs
@ terima kasih. Tetapi menggunakan ;bukannya ,memungkinkan untuk hanya input numerik biasa. -1byte anyway
Kroppeb
5

C (39 karakter)

double f(int n){return n<2?1:n*f(n-1);}
migf1
sumber
3
Bagus. Tetapi dapat menyimpan beberapa karakter: double f(n){return!n?1:n*f(n-1);}- 33 karakter.
ugoren
2
f(125)akan meluap
jkabrg
4

D: 45 Karakter

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

Lebih jelas:

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

Pendingin (meskipun versi yang lebih panjang) adalah templatized yang mengerjakan semuanya pada waktu kompilasi ( 64 karakter ):

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

Lebih jelas:

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

Template Eponim cukup bertele-tele, jadi Anda tidak bisa menggunakannya dalam kode golf dengan sangat baik. D sudah cukup verbose dalam hal jumlah karakter menjadi agak buruk untuk kode golf (meskipun sebenarnya sangat baik mengurangi ukuran program keseluruhan untuk program yang lebih besar). Ini adalah bahasa favorit saya, jadi saya pikir saya mungkin juga mencoba dan melihat seberapa baik saya bisa melakukannya di golf kode, bahkan jika orang-orang seperti GolfScript terikat untuk memperbaikinya.

Jonathan M Davis
sumber
3
keluarkan ruang putih dan Anda bisa turun ke 36 karakter
ratchet freak
@Cyoce Bisakah Anda jelaskan?
YoYoYonnY
Selamat datang di situs ini, @ user272735. Perhatikan bahwa kami tidak mengedit solusi orang untuk melakukan perbaikan di sini. Sebagai gantinya, kami meninggalkan komentar yang menyarankan peningkatan itu, seperti yang dilakukan oleh ratchet freak di atas.
Shaggy
4

PowerShell - 36

Naif:

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

Uji:

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

Scala, 39 karakter

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

Sebagian besar karakter memastikan bahwa BigInts digunakan sehingga persyaratan untuk nilai hingga 125 terpenuhi.

Gareth
sumber
Beberapa opsi yang lebih pendek:(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:

  • Fungsi panah
Afonso Matos
sumber
ES6 lebih muda dari tantangan ini jika saya mengingat dengan benar dan karenanya tidak memenuhi syarat.
lirtosiast
Ada sesuatu yang aneh dengan operator bersyarat. Mengapa ada dua titik dua?
Qwertiy
@ Qwertiy Anda benar, itu salah ketik, terima kasih.
Afonso Matos
4

PowerShell, 42 byte

(disimpan 2 karakter menggunakan filter bukan fungsi )

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

Keluaran:

PS C:\> f 0
1
PS C:\> f 5
120
PS C:\> f 1
1
PS C:\> f 125
1.88267717688893E+209
Ty Auvil
sumber
1
Ini adalah cara lama sekarang, tapi ... Dapat menyimpan 1 karakter lainnya membalikkan jika / lain: filter f($x){if($x){$x*(f($x-1))}else{1}}. Dan itu dapat dikurangi lebih lanjut untuk 36 karakter jika itu disebut melalui pipa karena itu filter (misalnya 125|f):filter f{if($_){$_*($_-1|f)}else{1}}
Andrew
4

Racket (skema) 40 35 29 byte

Menghitung 0! menjadi 1, dan menghitung 125! dalam 0 detik sesuai dengan timer. Pendekatan rekursif reguler

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

Versi baru untuk mengalahkan lisp umum: mengalikan semua elemen daftar (sama dengan solusi Haskell)

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

Versi yang lebih baru untuk mengalahkan solusi skema lainnya dan menghitung solusi raket lainnya dengan menggunakan foldl alih-alih menerapkan dan menggunakan rentang alih-alih buildlist

(λ(n)(foldl * n(range 1 n)))
Kronismage
sumber
4

Mornington Crescent , 1827 1698 karakter

Saya merasa ingin belajar bahasa baru hari ini, dan inilah yang saya gunakan ... (Mengapa saya melakukan ini sendiri?) Entri ini tidak akan memenangkan hadiah apa pun, tetapi mengalahkan semua 0 jawaban lain sejauh ini menggunakan bahasa yang sama!

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

Cobalah online!

Siapa pun yang bepergian di London tentu akan mengerti hal itu secara instan, jadi saya yakin saya tidak perlu memberikan penjelasan lengkap.

Sebagian besar pekerjaan di awal adalah dalam menangani 0 case. Setelah menginisialisasi produk pada 1, saya dapat menggunakannya untuk menghitung maks (input, 1) untuk mendapatkan input baru, mengambil keuntungan dari fakta bahwa 0! = 1! Kemudian loop utama dapat dimulai.

(EDIT: Sejumlah besar perjalanan telah diselamatkan dengan melepaskan 1 dari "Terminal Heathrow 1, 2, 3" alih-alih menghasilkannya dengan membagi 7 (Sisters) dengan sendirinya. Saya juga menggunakan metode yang lebih murah untuk menghasilkan -1 dalam langkah selanjutnya.)

Pengurangan mahal di Mornington Crescent (meskipun lebih murah daripada Tube itu sendiri). Untuk membuat hal-hal lebih efisien, saya menghasilkan -1 dengan mengambil BUKAN dari 0 diurai dan menyimpannya di Hammersmith untuk sebagian besar loop.


Saya melakukan beberapa pekerjaan penting dalam hal ini, tetapi karena ini adalah upaya pertama saya bermain golf di Mornington Crescent (sebenarnya upaya pertama saya dalam bahasa apa pun ), saya berharap saya melewatkan beberapa optimisasi di sana-sini. Jika Anda tertarik untuk memprogram dalam bahasa ini sendiri (dan mengapa Anda tidak?), Esoteric IDE - dengan mode debug dan jendela arlojinya - adalah suatu keharusan!

Alevya
sumber
3

Befunge - 2x20 = 40 karakter

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

Ini adalah fungsi karena merupakan blok kode mandiri yang tidak menggunakan sampul. Anda harus menempatkan argumen di atas tumpukan kemudian masuk dari kiri kanan ke kanan, fungsi akan keluar dari kanan bawah ke kanan dengan hasil di atas tumpukan.

Misalnya untuk menghitung faktorial dari 125

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

Pengujian 0

0   0\:#v_# 1#<\$v *\<
        >:1-:#^_$>\:#^_$    .@
Nemo157
sumber
Saya tahu ini cukup lama, tapi saya pikir ini agak lebih pendek dan lebih cepat: &:!#@_>:# 1# -# :# _$>\# :#* _$.@(di mana & harus diganti dengan input). Ini 32 chars / byte
FliiFe
3

J - 6 karakter

*/>:i.

Apakah ini masuk hitungan? Saya tahu ini sangat mirip dengan contoh J sebelumnya, tetapi sedikit lebih pendek :)

Saya seorang pemula dengan J, tapi sejauh ini sangat menyenangkan!

Andbdrew
sumber
3

In C (23 Karakter)

Ini menyalahgunakan "fitur" GCC yang menjadikan tugas terakhir dianggap sebagai pengembalian jika tidak ada pengembalian yang ditentukan.

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

Dalam C yang tepat, 28 karakter

f(a){return a>0?f(a-1)*a:1;}
Kaslai
sumber
+1 untuk "fitur" GCC. Saya pikir GCC bahkan memungkinkan nilai blok kembali (Ingat bisa melakukan sesuatu seperti ini)0 == ({printf("Hello, world!"); 0;});
YoYoYonnY
3

Kona ( 11 6)

*/1.+!

K bekerja dari kanan ke kiri (sebagian besar), jadi kami menghitung x(membuat daftar / larik angka dari 0ke x-1), menambahkannya 1(rentang daftar 0ke x), lalu mengalikan semua angka bersama. Jika bukan persyaratan untuk menghitung 125!, saya bisa menghemat 1 byte lagi dengan menghilangkan .sebelah 1. Bagaimanapun, 125! dihitung dalam milidetik belaka:

  */1.+!125.
1.882677e+209
Kyle Kanos
sumber
Anda tidak perlu banyak ini. K memiliki kari, jadi seluruh jawaban menjadi */1.+!: 6 byte.
kirbyfan64sos
@ kirbyfan64sos: Benar & saya akan mengeditnya. Saya pikir ketika saya menulis ini ~ 18 bulan yang lalu, saya masih terjebak pada semuanya harus dapat dipanggil (yaitu, fungsi).
Kyle Kanos