ค้นหาแฟคทอเรียล!


74

สร้างโปรแกรมหรือฟังก์ชันที่สั้นที่สุดที่พบแฟกทอเรียลของจำนวนเต็มแบบไม่ลบ

แฟคทอเรียลที่แสดงด้วย!ถูกกำหนดเช่นนี้

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

ในภาษาอังกฤษธรรมดาแฟกทอเรียลของ 0 คือ 1 และแฟกทอเรียลของ n โดยที่ n มีค่ามากกว่า 0 คือ n คูณแฟคทอเรียลของหนึ่งน้อยกว่า n

รหัสของคุณควรดำเนินการอินพุตและเอาต์พุตโดยใช้วิธีมาตรฐาน

ที่ต้องการ:

  • ห้ามใช้ไลบรารีในตัวที่สามารถคำนวณแฟคทอเรียล (รวมถึงรูปแบบใด ๆ ของeval)
  • สามารถคำนวณแฟคทอเรียลสำหรับจำนวนสูงสุด 125
  • สามารถคำนวณแฟคทอเรียลสำหรับหมายเลข 0 (เท่ากับ 1)
  • เสร็จสิ้นภายในไม่กี่นาทีสำหรับตัวเลขสูงถึง 125

การส่งที่สั้นที่สุดจะเป็นผู้ชนะในกรณีที่เสมอคำตอบด้วยคะแนนมากที่สุดในเวลาที่ชนะ


10
จำนวนคำตอบที่ได้รับสามารถคำนวณได้มากถึง 125 รายการ! ไม่ล้นจำนวนเต็ม? นั่นไม่ใช่หนึ่งในข้อกำหนดใช่หรือไม่ ผลลัพธ์เป็นการประมาณแบบเอ็กซ์โปเนนเชียลที่ยอมรับได้ (เช่น 125! = 1.88267718 × 10 ^ 209)?
Ami

6
@SHiNKiROU แม้แต่ golfscript ก็สามารถจัดการได้ 125 คน! น้อยกว่า1 / 10th ของวินาทีและมันและตีความตีความภาษา!
gnibbler

5
@ugoren โซลูชันสองอักขระสำหรับคำถามอื่นใช้ฟังก์ชันแฟกทอเรียลในตัว ไม่ได้รับอนุญาตในการท้าทายเวอร์ชันนี้
Michael Stern

4
เสร็จภายในไม่กี่นาทีดูเหมือนว่าข้อกำหนดขึ้นอยู่กับฮาร์ดแวร์มาก เสร็จในไม่กี่นาทีสำหรับฮาร์ดแวร์อะไร?
sergiol

4
@sergiol เหลือเชื่อว่าไม่มีปัญหาในช่วง 2 ปีที่ผ่านมาฉันสงสัยว่าภาษาส่วนใหญ่สามารถทำได้ภายในไม่กี่นาที
Kevin Brown

คำตอบ:


66

Golfscript - 12 ตัวอักษร

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

เริ่มต้นใช้งาน Golfscript - Factorial ทีละขั้นตอน

นี่คือบางสิ่งบางอย่างสำหรับผู้ที่พยายามเรียนรู้ Golfscript สิ่งที่จำเป็นต้องมีคือความเข้าใจพื้นฐานของ Golfscript และความสามารถในการอ่านเอกสาร Golfscript

ดังนั้นเราจึงต้องการที่จะลองเครื่องมือใหม่ของเราgolfscript มันเป็นการดีเสมอที่จะเริ่มต้นด้วยสิ่งที่ง่ายดังนั้นเราจึงเริ่มต้นด้วยปัจจัย นี่เป็นความพยายามครั้งแรกโดยใช้พื้นฐานของ pseudocode ที่เรียบง่าย:

# 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

ช่องว่างถูกนำมาใช้บ่อยมากใน golfscript เคล็ดลับที่ง่ายที่สุดในการกำจัดช่องว่างคือการใช้ชื่อตัวแปรที่แตกต่างกัน โทเค็นทุกตัวสามารถใช้เป็นตัวแปรได้ (ดูหน้าไวยากรณ์ ) ราชสกุลที่มีประโยชน์ในการใช้เป็นตัวแปรที่มีตัวอักษรพิเศษเช่น|, &, ?- โดยทั่วไปสิ่งที่ไม่ใช้ที่อื่นในรหัส สิ่งเหล่านี้ถูกวิเคราะห์คำเป็นโทเค็นอักขระเดียวเสมอ ในทางตรงกันข้ามตัวแปรเช่นnจะต้องมีพื้นที่เพื่อผลักดันตัวเลขไปยังสแต็คหลังจาก ตัวเลขเป็นตัวแปรที่กำหนดค่าเริ่มต้นเป็นหลัก

และเช่นเคยจะมีแถลงการณ์ที่เราสามารถเปลี่ยนแปลงได้โดยไม่กระทบต่อผลลัพธ์สุดท้าย ใน golfscript ทุกอย่างตรวจสอบการจริงยกเว้น0, [], ""และ{}(ดูนี้ ) ที่นี่เราสามารถเปลี่ยนเงื่อนไขการออกจากลูปเป็นเพียง{n}(เราวนรอบเวลาเพิ่มเติมและสิ้นสุดเมื่อ n = 0)

เช่นเดียวกับการเล่นกอล์ฟในภาษาใด ๆ มันช่วยให้ทราบถึงฟังก์ชั่นที่มีอยู่ โชคดีที่รายการนี้สั้นมากสำหรับนักกอล์ฟ เราสามารถเปลี่ยน1-ไป(เพื่อบันทึกตัวอักษรอีก ในปัจจุบันรหัสมีลักษณะดังนี้: (เราสามารถใช้1แทนที่|นี่ถ้าเราต้องการซึ่งจะปล่อยการเริ่มต้น)

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

สิ่งสำคัญคือต้องใช้สแต็คอย่างดีเพื่อให้ได้วิธีแก้ปัญหาที่สั้นที่สุด (ฝึกฝึกหัด) โดยทั่วไปหากค่าถูกใช้เฉพาะในส่วนของรหัสขนาดเล็กอาจไม่จำเป็นต้องเก็บค่าไว้ในตัวแปร โดยการลบตัวแปรผลิตภัณฑ์ที่กำลังทำงานอยู่และเพียงแค่ใช้สแต็คเราสามารถบันทึกอักขระได้ค่อนข้างมาก

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

นี่คือสิ่งอื่นที่คิด เรากำลังลบตัวแปรnออกจากสแต็คที่ส่วนท้ายของตัวลูป แต่จากนั้นกดทันทีหลังจากนั้น ในความเป็นจริงก่อนที่ลูปจะเริ่มต้นเราก็ลบมันออกจากสแต็ก เราควรทิ้งไว้บนสแต็กแทนและเราสามารถทำให้สภาพลูปว่าง

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

บางทีเราสามารถกำจัดตัวแปรได้อย่างสมบูรณ์ ในการทำเช่นนี้เราจะต้องเก็บตัวแปรไว้ในสแต็กตลอดเวลา ซึ่งหมายความว่าเราต้องการสำเนาสองชุดของตัวแปรในสแต็กเมื่อสิ้นสุดการตรวจสอบสภาพดังนั้นเราจะไม่สูญเสียมันหลังจากการตรวจสอบ ซึ่งหมายความว่าเราจะมีข้อมูลซ้ำซ้อน0ในสแต็คหลังจากที่ลูปสิ้นสุดลง แต่นั่นก็แก้ไขได้ง่าย

นี่นำเราไปสู่whileโซลูชันลูปที่ดีที่สุดของเรา!

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

ตอนนี้เรายังต้องการทำให้สิ่งนี้สั้นลง whileเป้าหมายที่ชัดเจนควรจะเป็นคำว่า มองไปที่เอกสารมีสองทางเลือกที่ทำงานได้ - แฉและทำ เมื่อคุณมีทางเลือกต่าง ๆ ให้ลองและชั่งน้ำหนักประโยชน์ของทั้งคู่ แฉคือ 'สวยมากห่วงขณะที่' เพื่อให้เป็นประมาณการเราจะลดลง 5 ตัวอักษรwhile4 /เข้า ส่วนdoเราตัดwhile3 ตัวอักษรและรวมสองบล็อกเข้าด้วยกันซึ่งอาจช่วยตัวละครอีกหนึ่งหรือสองตัว

จริงๆแล้วมีข้อเสียเปรียบอย่างมากสำหรับการใช้doลูป เนื่องจากการตรวจสอบสภาพเสร็จสิ้นหลังจากที่ร่างกายถูกดำเนินการเพียงครั้งเดียวค่าของ0จะไม่ถูกต้องดังนั้นเราอาจจำเป็นต้องมีคำสั่ง if ฉันจะบอกคุณตอนนี้ว่าการตีแผ่จะสั้นกว่า (การแก้ปัญหาบางอย่างdoจะมีให้ในตอนท้าย) ไปข้างหน้าและลองใช้รหัสที่เรามีอยู่แล้วต้องการการเปลี่ยนแปลงเล็กน้อย

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

ที่ดี! ทางออกของเราสั้นมากและเราทำเสร็จแล้วใช่ไหม Nope นี่คือ 17 ตัวอักษรและ J มี 12 ตัวอักษร อย่ายอมรับความพ่ายแพ้!


ตอนนี้คุณกำลังคิดกับ ... การเรียกซ้ำ

การใช้การเรียกซ้ำหมายถึงเราต้องใช้โครงสร้างการแยกสาขา โชคไม่ดี แต่เนื่องจากแฟคทอเรียลสามารถแสดงซ้ำได้อย่างกระชับซ้ำซากนี่เป็นทางเลือกที่เหมาะสมสำหรับการทำซ้ำ

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

นั่นเป็นเรื่องง่าย - ถ้าเราลองเรียกใช้ซ้ำก่อนหน้านี้เราอาจไม่ได้ใช้whileลูป! ถึงกระนั้นเรามีเพียง 16 ตัวอักษร


อาร์เรย์

โดยทั่วไปอาร์เรย์จะถูกสร้างขึ้นในสองวิธี - การใช้[และ]ตัวละครหรือด้วย,ฟังก์ชั่น หากดำเนินการด้วยจำนวนเต็มที่ด้านบนของสแต็ก,ส่งคืนอาร์เรย์ของความยาวนั้นด้วย arr [i] = i

สำหรับการวนซ้ำอาร์เรย์เรามีสามตัวเลือก:

  1. {block}/: push, block, push, block, ...
  2. {block}%: [push, block, push, block, ... ] (มีความแตกต่างเล็กน้อยเช่นค่ากลางจะถูกลบออกจากสแต็กก่อนการกดแต่ละครั้ง)
  3. {block}*: push, push, block, push, block, ...

เอกสาร golfscript มีตัวอย่างของการใช้{+}*เพื่อรวมเนื้อหาของอาร์เรย์ สิ่งนี้ชี้ให้เห็นว่าเราสามารถใช้{*}*รับผลิตภัณฑ์ของอาร์เรย์ได้

{,{*}*}:f

น่าเสียดายที่มันไม่ง่ายอย่างนั้น องค์ประกอบทั้งหมดถูกปิดโดยหนึ่ง ( [0 1 2]แทน[1 2 3]) เราสามารถใช้{)}%เพื่อแก้ไขปัญหานี้

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

ไม่ค่อยดี สิ่งนี้ไม่จัดการศูนย์อย่างถูกต้อง เราสามารถคำนวณ (n + 1)! / (n + 1) เพื่อแก้ไขสิ่งนี้แม้ว่าค่าใช้จ่ายจะมากเกินไป

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

เราสามารถลองจัดการ n = 0 ในที่เก็บข้อมูลเดียวกันกับ n = 1 นี่เป็นเรื่องที่สั้นมากที่ต้องทำลองและพยายามย่อให้สั้นที่สุดเท่าที่จะทำได้

ไม่ดีดังนั้นจะเรียงลำดับที่ 7 [1\]$1=ตัวอักษร: โปรดทราบว่าเทคนิคการเรียงลำดับนี้มีจุดประสงค์ที่เป็นประโยชน์เช่นการกำหนดขอบเขตของตัวเลข (เช่น `[0 \ 100] $ 1 =)
นี่คือผู้ชนะที่มีเพียง 3 ตัวอักษร:.! +

ถ้าเราต้องการมีการเพิ่มและการคูณในบล็อกเดียวกันเราควรวนซ้ำทุกองค์ประกอบในอาร์เรย์ เนื่องจากเราไม่ได้สร้างอาร์เรย์หมายความว่าเราควรจะใช้{)*}/ซึ่งนำเราไปสู่การดำเนินการที่สั้นที่สุดของนักกอล์ฟ! ที่ความยาว 12 ตัวอักษรนี้จะเชื่อมโยงกับ J!

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


โซลูชั่นโบนัส

เริ่มต้นด้วยifวิธีแก้ปัญหาที่ตรงไปตรงมาสำหรับการdoวนซ้ำ:

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

เราสามารถบีบสิ่งนี้ออกมาได้สองสามอย่าง ซับซ้อนเล็กน้อยดังนั้นคุณจะต้องโน้มน้าวตัวเองให้ทำงานเหล่านี้ ตรวจสอบให้แน่ใจว่าคุณเข้าใจสิ่งเหล่านี้ทั้งหมด

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

ทางเลือกที่ดีกว่าคือการคำนวณ (n + 1)! / (n + 1) ซึ่งไม่จำเป็นต้องใช้ifโครงสร้าง

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

แต่doทางออกที่สั้นที่สุดที่นี่ใช้ตัวละครสองสามตัวเพื่อแมป 0 ถึง 1 และทุกอย่างอื่นเพื่อตัวของมันเอง - ดังนั้นเราจึงไม่จำเป็นต้องแยกสาขา การเพิ่มประสิทธิภาพประเภทนี้พลาดได้ง่ายมาก

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

สำหรับทุกคนที่สนใจโซลูชันแบบเรียกซ้ำทางเลือกสองสามทางที่มีความยาวเท่ากันกับด้านบนมีให้ที่นี่:

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

* หมายเหตุ: ฉันยังไม่ได้ทดสอบโค้ดหลายชิ้นในโพสต์นี้ดังนั้นโปรดแจ้งให้ทราบหากมีข้อผิดพลาด


8
น่าสนใจดูเหมือนว่าจะเป็นข้อผิดพลาดในการทำเครื่องหมายสปอยเลอร์เมื่อคุณใช้รหัสในสปอยเลอร์ ... ใครสนใจที่จะพูดถึงเรื่องนี้ใน Meta?
Ivo Flipse

5
ฉันพบว่ามันน่าสนใจว่า golfscript - ภาษาการเล่นกอล์ฟ - อนุญาตให้ใช้ชื่อตัวแปรหลายตัวอักษรและ "ลงโทษ" คุณสำหรับการใช้ 1 ตัวอักษรพร้อมช่องว่างที่จำเป็น
Cyoce

44

Haskell, 17

f n=product[1..n]

2
ฉันไม่รู้ Haskell ... แต่สิ่งนี้จะคำนวณแฟคทอเรียลสำหรับ 0
The King

11
@ ราชา: ใช่มันจะ [1..0] ==> []และproduct [] ==> 1
JB

5
ฉันจะโต้แย้งนี้ใช้ "ห้องสมุดในตัว" ว่าปัญหาห้าม อย่างไรก็ตามวิธีอื่น ๆf 0=1;f n=n*f$n-1ก็คือ 17 ตัวอักษรเช่นกัน
eternalmatt

5
@ eternalmatt: ข้อ จำกัด ส่วนนั้นไม่ได้ระบุให้ฉัน ทั้งสองproductและพูด(*)หรือ(-)"สามารถคำนวณแฟคทอเรียล" และพวกมันทั้งหมดถูกกำหนดผ่านพรีลูด ทำไมคนเราถึงใจเย็นและไม่ใช่คนอื่น
JB

2
@YoYoYonnY: ฉันนับ 17 ตัวอักษรเช่นกันสำหรับการอ่านน้อยลง (ส่วนตัว) IMHO มันดีในความคิดเห็น
JB

41

Python - 27

เพียงแค่:

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

22
0**xเคล็ดลับดี:
Alexandru

เกี่ยวกับmath.factorialอะไร มันไม่ใช่ในตัวใช่มั้ย

1
@ JackBates ที่นับว่าเป็น builtin เนื่องจากคุณไม่ได้เขียนรหัสเพื่อคำนวณแฟคทอเรียล
FlipTack

1
ทุกคนสามารถบอกฉันว่าเคล็ดลับที่อยู่เบื้องหลัง0**x?
Pavitra

1
@Pavitra: 0 0 = 1 และมันเป็นสิ่งแรกที่ประเมินเพื่อที่มันจะได้รับคืน สำหรับอื่น ๆ n, 0 n = 0 ดังนั้นตัวถูกดำเนินการแรกของหรือเป็นเท็จเช่นตัวถูกดำเนินการที่สองได้รับการประเมิน
Mega Man

29

APL (4)

×/∘⍳

ทำงานเป็นฟังก์ชั่นที่ไม่ระบุชื่อ:

    ×/∘⍳ 5
120

หากคุณต้องการตั้งชื่อตัวละคร 6 ตัว:

f←×/∘⍳

ฉันไม่พูด APL เกิดอะไรขึ้นที่นี่
Michael Stern

@MichaelStern: ทำให้ดัชนีเวกเตอร์คือเป็น⍳5 คือ (ชัด) คูณลดและเป็นองค์ประกอบของฟังก์ชั่น ดังนั้นเป็นฟังก์ชั่นที่ใช้อาร์กิวเมนต์และให้สินค้าของตัวเลข 1 2 3 4 5×/×/∘⍳x[1..x]
marinus

อาวิธีการเดียวกับในโซลูชัน Mathematica ของ @Yves Klett ดีมาก.
Michael Stern

@NBZ: ยังไม่มีในปี 2011 เมื่อมีการเขียนคำถามนี้และในปี 2012 เมื่อฉันเขียนคำตอบนี้ มีการเพิ่มเฉพาะรถไฟใน Dyalog 14.0 ซึ่งออกมาในปี 2014
marinus

19

J (12)

คำจำกัดความมาตรฐานใน J:

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

น้อยกว่า 1 วินาทีสำหรับ 125!

เช่น:

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

ทำไมไม่เพียง * />: ฉัน ?
Andbdrew

เนื่องจาก OP ขอฟังก์ชั่นและสิ่งที่ดีที่สุดที่เราสามารถทำได้ใน J คือการกำหนดคำกริยา
Eelvex

2
มันไม่มีเหตุผลที่ฟังก์ชั่นไม่ระบุชื่อใช่มั้ย เช่นเดียวกับ([:*/1+i.)10 คะแนนหรือแม้แต่ 8 เท่าในวงเล็บเป็นสิ่งจำเป็นสำหรับการเรียกใช้ฟังก์ชั่นเท่านั้นไม่ใช่เพื่อการกำหนด
jpjacobs

ในช่วงหนึ่งf 125xสิ่งที่ไม่xทำอะไร? มันเป็นหมายเลขชนิดพิเศษหรือไม่?
Cyoce

@Cyoce ใช่มันเป็นจำนวนเต็มความแม่นยำขยาย
Eelvex

17

Golfscript - 13 ตัวอักษร(SYM)

กำหนดฟังก์ชั่น !

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

เลือกรุ่นถ่าน 13 ตัว

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

เวอร์ชันโปรแกรมทั้งหมดคือ10 ตัวอักษร

~),()+{*}*

testcases ใช้เวลาน้อยกว่า 1/10 วินาที:

การป้อนข้อมูล:

0!

เอาท์พุต

1

อินพุต

125!

เอาท์พุต

188267717688892609974376770249160085759540364871492425887598231508353156331613598866882932889495923133646405445930057740630161919341380597818883457558547055524326375565007131770880000000000000000000000000000000

1
+1 สำหรับรายการกอล์ฟสัญลักษณ์! ฉันหวังว่าฉันจะโหวตได้มากกว่าหนึ่งครั้ง :-D
Chris Jester-Young

@ ChrisJester-Young ฉันจะทำเพื่อคุณ
Cyoce

13

Perl 6: 13 ตัวอักษร

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

[*]เหมือนกับ Haskell productและ1..$_นับจากข้อ 1 ถึง$_ข้อโต้แย้ง


2
ไม่อนุญาตให้ไม่ใช้ช่องว่างหลังจากนั้น[*]อีกต่อไป (ข้อความข้อผิดพลาด "สองคำในแถว")
Konrad Borowski

คุณไม่จำเป็นต้องตั้งค่าตัวแปรการบล็อกรหัสเปลือยเป็นคำตอบที่ยอมรับได้เนื่องจากมันจะสร้างฟังก์ชั่นโดยปริยาย มันยังใช้งานได้กับ 0 ด้วยหรือไม่
Phil H



9

MATL , 2 ไบต์

:p

อธิบาย:

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

ลองออนไลน์!


10
: O
Andras Deak

ฉันกำลังจะโพสต์สิ่งนี้ :-) คุณอาจต้องการแก้ไขลิงก์เพื่อรวมรหัสและตัวอย่างอินพุต
Luis Mendo

ในขณะที่คุณสั่งเจ้านายของฉัน
ข้อบกพร่อง

4
@AndrasDeak, ไม่, ที่จะแสดงตัวเลขทั้งหมดจาก 1 ถึง i ...
YoYoYonnY

8

Ruby - 21 ตัวอักษร

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

ทดสอบ

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 Chars

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

1
สิ่งนี้พลาดการนำเข้า: import java.math.*;(ดังนั้น, +19 ไบต์)
Olivier Grégoire

จุดยุติธรรม ............
2560

7

PostScript, 26 ตัวอักษร

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

ตัวอย่าง:

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

ฟังก์ชันใช้เวลาเพียง 21 ตัวอักษร ส่วนที่เหลือคือการผูกไว้กับตัวแปร หากต้องการบันทึกไบต์คุณสามารถผูกกับหลักได้เช่น:

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

1
Ghostscript ไม่สามารถจัดการ 125!; อะไรก็ได้ที่เกิน 34! 1.#INFออกมาเป็น (ฉันใช้สต็อก GNU Ghostscript 9.0.7 ซึ่งคอมไพล์แล้วสำหรับ x64 Windows)
Ross Presser

7

JavaScript, 25

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

CoffeeScript, 19

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

ส่งคืนtrueในกรณีของ n = 0 แต่ JavaScript จะพิมพ์ coerce เป็น 1 ต่อไป


คุณไม่ต้องการreturnคำสั่งในฟังก์ชั่น JavaScript หรือไม่?
จัสตินมอร์แกน

อัปเดต: ควันศักดิ์สิทธิ์คุณไม่ต้องการreturn! แต่ทำไมล่ะ
Justin Morgan

มันคือ JavaScript 1.8 ( developer.mozilla.org/th/new_in_javascript_1.8 ) การเปิดเผยอย่างสมบูรณ์ใช้ได้กับ Firefox เท่านั้น!
Casey Chu

1
ดีฉันไม่รู้เกี่ยวกับการออกจากคำสั่งการส่งคืนสำหรับ JavaScript 1.8 นอกจากนี้คุณสามารถรับประกัน 1 แทนของจริงสำหรับคดี n = 0 ด้วยรหัสความยาวเท่ากัน: function f(n)n?n*f(--n):1
Briguy37

10
ES6, 17: f=n=>!n||n*f(n-1)ทำอย่างนั้น CoffeeScript!
Ry-

6

Ruby - 30 29 ตัวอักษร

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

ทดสอบ

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

1
คุณสามารถใส่endได้โดยตรง:*โดยไม่ต้องขึ้นบรรทัดใหม่หรืออัฒภาค
sepp2k

1
ไม่จำเป็นต้องผ่าน 1 ไปยังการโทร #inject (1..10).inject :*# => 3628800
Dogbert

1
@Dogbert เกี่ยวกับf(0)อะไร
Nemo157

@ Nemo157 อ่า! ลืมเรื่องนั้นไป
Dogbert

4
ที่สั้นกว่าที่จะใช้ 1.9 f=->n{(1..n).inject 1,:*}ไวยากรณ์แลมบ์ดา: f[n]เรียกมันว่าด้วย
Michael Kohl

6

F #: 26 ตัวอักษร

ไม่มีฟังก์ชั่นผลิตภัณฑ์ inbuilt ใน F # แต่คุณสามารถสร้างได้ด้วยการพับ

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

6

C #, 20 หรือ 39 ตัวอักษรขึ้นอยู่กับมุมมองของคุณ

เป็นวิธีการแบบอินสแตนซ์ดั้งเดิม (39 ตัวอักษร; ทดสอบที่นี่ ):

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

เป็นนิพจน์แลมบ์ดา (20 ตัวอักษร แต่ดูที่การปฏิเสธสิทธิ์ทดสอบที่นี่ )

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

เราต้องใช้doubleเพราะ125! == 1.88 * 10 209ซึ่งสูงกว่าulong.MaxValueมาก

ข้อจำกัดความรับผิดชอบเกี่ยวกับการนับจำนวนตัวอักษรของแลมบ์ดา:

หากคุณเรียกซ้ำใน C # แลมบ์ดาคุณต้องเก็บแลมบ์ดาไว้ในตัวแปรที่ตั้งชื่อเพื่อที่จะสามารถเรียกตัวมันเองได้ แต่แตกต่างจาก (เช่น) JavaScript แลมบ์ดาอ้างอิงตนเองต้องได้รับการประกาศและเริ่มต้นในบรรทัดก่อนหน้า คุณไม่สามารถเรียกใช้ฟังก์ชันในคำสั่งเดียวกับที่คุณประกาศและ / หรือเริ่มต้นตัวแปร

กล่าวอีกนัยหนึ่งสิ่งนี้ไม่ได้ผล :

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

แต่ สิ่งนี้จะ :

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

ไม่มีเหตุผลที่ดีสำหรับข้อ จำกัด นี้เนื่องจากfไม่สามารถยกเลิกการมอบหมายในขณะที่ทำงาน ความจำเป็นของFunc<int,double> f=null;สายคือการเล่นโวหารของ C # ไม่ว่าจะทำให้มันยุติธรรมที่จะไม่สนใจมันในการนับตัวละครขึ้นอยู่กับผู้อ่าน

CoffeeScript, 21ตัวอักษรจริง 19 ตัว

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

ทดสอบที่นี่: http://jsfiddle.net/0xjdm971/


6

Brachylog , 7 6 ไบต์

โดยการทำพิสัยและการคูณนั้น

-1 ไบต์รถถังไปยัง ovs โดยใช้แนวคิด max () ฟังก์ชั่น

;1⌉⟦₁×

คำอธิบาย

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

ลองออนไลน์!


Brachylog , 10 9 ไบต์

เรียกซ้ำ

≤1|-₁↰;?×

คำอธิบาย

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

ลองออนไลน์!


1
ใช้งานได้ 6 ไบต์ การป้อนข้อมูลเป็นแบบซิงเกิลได้รับอนุญาตโดยค่าเริ่มต้น
ovs

@ovs ขอบคุณ แต่การใช้;แทนที่จะ,อนุญาตให้ป้อนเพียงตัวเลขปกติ -1byte ต่อไป
Kroppeb

5

C (39 ตัวอักษร)

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

3
ดี แต่สามารถบันทึกตัวละครได้บ้าง: double f(n){return!n?1:n*f(n-1);}- 33 ตัวอักษร
ugoren

2
f(125)จะล้น
jkabrg

4

D: 45 ตัวอักษร

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

ชัดเจนมากขึ้น:

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

ตัวทำความเย็น (แม้ว่าเวอร์ชั่นที่ยาวกว่า) คือเทมเพลตที่ทำทั้งหมดในเวลารวบรวม ( 64 ตัวอักษร ):

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

ชัดเจนมากขึ้น:

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

เทมเพลตที่มีความหมายเหมือนกันนั้นค่อนข้างจริงดังนั้นคุณไม่สามารถใช้มันในการเขียนโค้ดได้ดีนัก D's แล้ว verbose เพียงพอในแง่ของจำนวนตัวอักษรจะค่อนข้างไม่ดีสำหรับการเล่นกอล์ฟรหัส (แม้ว่ามันจะไม่จริงจริงๆดีในการลดขนาดโครงการโดยรวมสำหรับโปรแกรมขนาดใหญ่) เป็นภาษาโปรดของฉันดังนั้นฉันคิดว่าฉันอาจลองและดูว่าฉันสามารถทำมันที่ code golf ได้อย่างไรแม้ว่า GolfScript จะผูกพันกับครีม


3
นำช่องว่างออกมาและคุณจะได้รับลงไปที่ 36 ตัวอักษร
วงล้อประหลาด

@Cyoce คุณอธิบายได้ไหม?
YoYoYonnY

ยินดีต้อนรับสู่เว็บไซต์ @ user272735 โปรดทราบว่าเราไม่ได้แก้ไขโซลูชันของผู้คนเพื่อทำการปรับปรุงที่นี่ แต่เราจะแสดงความคิดเห็นเพื่อเสนอการปรับปรุงดังกล่าวเนื่องจากวงล้อประหลาดทำด้านบน
Shaggy


4

สกาลา, 39 ตัวอักษร

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

อักขระส่วนใหญ่มั่นใจว่าBigIntมีการใช้ s เพื่อให้ตรงตามข้อกำหนดสำหรับค่าสูงสุด 125


ตัวเลือกที่สั้นกว่านี้:(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:

  • ฟังก์ชั่นลูกศร

ES6 อายุน้อยกว่าความท้าทายนี้ถ้าฉันจำได้อย่างถูกต้องและดังนั้นจึงไม่มีสิทธิ์
lirtosiast

มีข้อผิดพลาดเล็กน้อยกับตัวดำเนินการแบบมีเงื่อนไข ทำไมมีสอง colons?
Qwertiy

@Qwertiy คุณพูดถูกนั่นเป็นตัวพิมพ์ผิดขอบคุณ
Afonso Matos

4

PowerShell ขนาด 42 ไบต์

(บันทึก 2 ตัวอักษรโดยใช้ตัวกรองแทนฟังก์ชั่น )

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

เอาท์พุท:

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

1
นี่คือวิธีการเก่า ๆ ในขณะนี้ แต่ ... สามารถบันทึก 1 ตัวละครมากขึ้นโดยการย้อนกลับหาก / filter f($x){if($x){$x*(f($x-1))}else{1}}อื่น: และสามารถลดได้มากถึง 36 ตัวอักษรหากถูกเรียกผ่านไปป์ไลน์เนื่องจากเป็นตัวกรอง (เช่น125|f):filter f{if($_){$_*($_-1|f)}else{1}}
Andrew

4

แร็กเก็ต (โครงร่าง) 40 35 29 ไบต์

คำนวณ 0! เป็น 1 และคำนวณ 125! ใน 0 วินาทีตามเวลา วิธีการเวียนเกิดแบบปกติ

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

เวอร์ชั่นใหม่เพื่อเอาชนะเสียงกระเพื่อม: คูณองค์ประกอบทั้งหมดของรายการ (เช่นเดียวกับโซลูชัน Haskell)

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

เวอร์ชันที่ใหม่กว่าที่จะเอาชนะโซลูชันโครงร่างอื่น ๆ และคณิตศาสตร์โซลูชันแร็กเก็ตอื่น ๆ โดยใช้ foldl แทนที่จะใช้และใช้ช่วงแทน buildlist

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

4

Mornington Crescent , 1827 1698 ตัวอักษร

ฉันรู้สึกอยากเรียนภาษาใหม่วันนี้และนี่คือสิ่งที่ฉันได้สัมผัส ... (ทำไมฉันต้องทำสิ่งนี้กับตัวเอง) รายการนี้จะไม่ชนะรางวัลใด ๆ แต่มันก็เอาชนะคำตอบอื่น ๆ ทั้งหมด 0 รายการ ภาษาเดียวกัน!

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

ลองออนไลน์!

ใครก็ตามที่เดินทางไปทั่วลอนดอนจะเข้าใจว่าทันทีดังนั้นฉันแน่ใจว่าฉันไม่จำเป็นต้องอธิบายอะไรเลย

งานส่วนใหญ่ที่เริ่มต้นนั้นอยู่ในการจัดการกรณี 0 หลังจากเริ่มต้นผลิตภัณฑ์ที่ 1 ฉันสามารถใช้เพื่อคำนวณ max (อินพุต 1) เพื่อรับอินพุตใหม่โดยใช้ประโยชน์จากข้อเท็จจริงที่ว่า 0! = 1! จากนั้นลูปหลักสามารถเริ่มต้นได้

(แก้ไข: การเดินทางทั้งหมดได้รับการบันทึกโดยการดึง 1 จาก "Heathrow Terminals 1, 2, 3" แทนที่จะสร้างโดยแบ่ง 7 (Sisters) ด้วยตัวเองฉันยังใช้วิธีที่ถูกกว่าเพื่อสร้าง -1 ใน ขั้นตอนต่อไป.)

Decrementing มีราคาแพงใน Mornington Crescent (แม้ว่าราคาจะถูกกว่า The Tube) เพื่อให้สิ่งต่าง ๆ มีประสิทธิภาพมากขึ้นฉันสร้าง -1 โดยการไม่แยกวิเคราะห์ 0 และเก็บไว้ใน Hammersmith สำหรับวงวนมาก


ฉันใส่งานที่สำคัญลงไปในนี้ แต่เนื่องจากนี่เป็นครั้งแรกของฉันในการเล่นกอล์ฟที่ Mornington Crescent (อันที่จริงความพยายามครั้งแรกของฉันในภาษาใด ๆ ) ฉันคาดว่าฉันพลาดการปรับตัวไม่กี่ที่นี่และที่นั่น หากคุณสนใจการเขียนโปรแกรมในภาษานี้ด้วยตัวเอง (และทำไมคุณไม่เป็นเช่นนั้น), Esoteric IDE - ด้วยโหมดการแก้ไขข้อบกพร่องและหน้าต่างดู - เป็นสิ่งที่ต้องทำ


3

Befunge - 2x20 = 40 ตัวอักษร

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

นี่คือฟังก์ชั่นที่มันเป็นบล็อกแบบสแตนด์อโลนของรหัสที่ไม่ได้ใช้การล้อมรอบ คุณต้องวางอาร์กิวเมนต์ที่ด้านบนสุดของสแต็กจากนั้นป้อนจากบนซ้ายไปขวาฟังก์ชั่นจะออกจากขวาล่างขวาไปพร้อมกับผลที่ด้านบนของสแต็ค

เช่นเพื่อคำนวณแฟคทอเรียลของ 125

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

การทดสอบ 0

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

ฉันรู้ว่านี่ค่อนข้างเก่า แต่ฉันคิดว่านี่ค่อนข้างสั้นและเร็วกว่า: &:!#@_>:# 1# -# :# _$>\# :#* _$.@(โดยที่ & ควรถูกแทนที่ด้วยอินพุต) มันคือ 32 ตัวอักษร / ไบต์
FliiFe

3

J - 6 ตัวอักษร

*/>:i.

สิ่งนี้นับหรือไม่ ฉันรู้ว่ามันคล้ายกับตัวอย่าง J ก่อนหน้านี้ แต่สั้นกว่าเล็กน้อย :)

ฉันเป็นผู้เริ่มต้นกับ J แต่มันสนุกมากจนถึงตอนนี้!


3

ใน C (23 ตัวอักษร)

การใช้งานในทางที่ผิด "คุณสมบัติ" ของ GCC ที่ทำให้การนับครั้งสุดท้ายเป็นการส่งคืนหากไม่มีการระบุการส่งคืน

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

ใน C ที่เหมาะสม 28 ตัวอักษร

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

+1 สำหรับ GCC "คุณสมบัติ" ผมคิดว่า GCC ยังช่วยให้ค่าบล็อกผลตอบแทน (สามารถจำทำอะไรเช่นนี้)0 == ({printf("Hello, world!"); 0;});
YoYoYonnY

3

โคนา ( 11 6)

*/1.+!

K ทำงานขวาไปซ้าย (ส่วนใหญ่) ดังนั้นเราจึงระบุx(ทำรายการ / อาร์เรย์ของตัวเลขจาก0การx-1), เพิ่ม1ไป (รายการช่วง0ไปx) จากนั้นคูณตัวเลขทั้งหมดเข้าด้วยกัน ถ้ามันไม่ได้ต้องการที่จะคำนวณ125!ฉันจะสามารถประหยัดไบต์อีก 1 โดยการกำจัดถัดจาก. 1ไม่ว่าในกรณีใด 125! คำนวณในหน่วยมิลลิวินาทีเพียง:

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

คุณไม่ต้องการสิ่งนี้มาก K มีคำตอบดังนั้นคำตอบทั้งหมด*/1.+!: 6 ไบต์
kirbyfan64sos

@ kirbyfan64sos: จริง & ฉันจะแก้ไขมันฉันคิดว่าเมื่อฉันเขียนสิ่งนี้ ~ 18 เดือนที่ผ่านมาฉันยังคงติดอยู่กับทุกสิ่งที่ต้องเรียก (เช่นฟังก์ชั่น)
Kyle Kanos
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.