ความท้าทาย:
เขียนโปรแกรมหรือฟังก์ชั่นที่ปัจจัยการผลิตเป็นจำนวนบวกและผลตอบแทนของปัจจัย
หมายเหตุ: นี่เป็นคำถามการหมุนรหัส กรุณาอย่าใช้คำถามและ / หรือคำตอบอย่างจริงจัง ข้อมูลเพิ่มเติมที่นี่ คำถามการหมุนรอบโค้ดทุกคำถามก็เป็นคำถามการประกวดความนิยม
ความท้าทาย:
เขียนโปรแกรมหรือฟังก์ชั่นที่ปัจจัยการผลิตเป็นจำนวนบวกและผลตอบแทนของปัจจัย
หมายเหตุ: นี่เป็นคำถามการหมุนรหัส กรุณาอย่าใช้คำถามและ / หรือคำตอบอย่างจริงจัง ข้อมูลเพิ่มเติมที่นี่ คำถามการหมุนรอบโค้ดทุกคำถามก็เป็นคำถามการประกวดความนิยม
คำตอบ:
นี่เป็นปัญหาการคำนวณเชิงตัวเลขที่ง่ายมากที่เราสามารถแก้ได้ด้วยการประมาณค่าของสเตอร์ลิง :
อย่างที่คุณเห็นสูตรนั้นมีรากที่สองซึ่งเราจะต้องใช้วิธีในการประมาณ เราจะเลือกวิธีการที่เรียกว่า"บาบิโลน"เพราะเป็นวิธีที่ง่ายที่สุด:
โปรดทราบว่าการคำนวณรากที่สองด้วยวิธีนี้เป็นตัวอย่างที่ดีของการเรียกซ้ำ
การนำทุกอย่างมารวมกันในโปรแกรม Python ช่วยให้เราแก้ไขปัญหาของคุณได้ดังต่อไปนี้:
def sqrt(x, n): # not the same n as below
return .5 * (sqrt(x, n - 1) + x / sqrt(x, n - 1)) if n > 0 else x
n = float(raw_input())
print (n / 2.718) ** n * sqrt(2 * 3.141 * n, 10)
ด้วยการปรับเปลี่ยนอย่างง่ายโปรแกรมข้างต้นสามารถแสดงผลตารางแฟกทอเรียลที่เรียบร้อย:
1! = 0.92215
2! = 1.91922
3! = 5.83747
4! = 23.51371
5! = 118.06923
6! = 710.45304
7! = 4983.54173
8! = 39931.74015
9! = 359838.58817
วิธีนี้ควรมีความแม่นยำเพียงพอสำหรับการใช้งานส่วนใหญ่
ขออภัยฉันเกลียดฟังก์ชันแบบเรียกซ้ำ
public string Factorial(uint n) {
return n + "!";
}
ชวา
public int factorial ( int n ) {
switch(n){
case 0: return 1;
case 1: return 1;
case 2: return 2;
case 3: return 6;
case 4: return 24;
case 5: return 120;
case 6: return 720;
case 7: return 5040;
case 8: return 40320;
case 9: return 362880;
case 10: return 3628800;
case 11: return 39916800;
case 12: return 479001600;
default : throw new IllegalArgumentException();
}
}
แน่นอนว่าวิธีที่ดีที่สุดในการแก้ปัญหาคือใช้นิพจน์ทั่วไป:
import re
# adapted from http://stackoverflow.com/q/15175142/1333025
def multiple_replace(dict, text):
# Create a regular expression from the dictionary keys
regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
# Repeat while any replacements are made.
count = -1
while count != 0:
# For each match, look-up corresponding value in dictionary.
(text, count) = regex.subn(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
return text
fdict = {
'A': '@',
'B': 'AA',
'C': 'BBB',
'D': 'CCCC',
'E': 'DDDDD',
'F': 'EEEEEE',
'G': 'FFFFFFF',
'H': 'GGGGGGGG',
'I': 'HHHHHHHHH',
'J': 'IIIIIIIIII',
'K': 'JJJJJJJJJJJ',
'L': 'KKKKKKKKKKKK',
'M': 'LLLLLLLLLLLLL',
'N': 'MMMMMMMMMMMMMM',
'O': 'NNNNNNNNNNNNNNN',
'P': 'OOOOOOOOOOOOOOOO',
'Q': 'PPPPPPPPPPPPPPPPP',
'R': 'QQQQQQQQQQQQQQQQQQ',
'S': 'RRRRRRRRRRRRRRRRRRR',
'T': 'SSSSSSSSSSSSSSSSSSSS',
'U': 'TTTTTTTTTTTTTTTTTTTTT',
'V': 'UUUUUUUUUUUUUUUUUUUUUU',
'W': 'VVVVVVVVVVVVVVVVVVVVVVV',
'X': 'WWWWWWWWWWWWWWWWWWWWWWWW',
'Y': 'XXXXXXXXXXXXXXXXXXXXXXXXX',
'Z': 'YYYYYYYYYYYYYYYYYYYYYYYYYY'}
def fact(n):
return len(multiple_replace(fdict, chr(64 + n)))
if __name__ == "__main__":
print fact(7)
Haskell
รหัสย่อคือรหัสที่มีประสิทธิภาพดังนั้นให้ลองสิ่งนี้
fac = length . permutations . flip take [1..]
ทำไมมันหมุนรอบ:
ฉันจะหัวเราะเยาะผู้เขียนโค้ดคนนี้ ... ความไร้ประสิทธิภาพนั้นช่างสวยงาม นอกจากนี้ยังอาจเข้าใจไม่ได้สำหรับโปรแกรมเมอร์ Haskell ที่จริง ๆ แล้วไม่สามารถเขียนฟังก์ชันแฟกทอเรียล
แก้ไข: ฉันโพสต์เมื่อครู่นี้ แต่ฉันคิดว่าฉันจะชี้แจงให้ผู้คนในอนาคตและผู้ที่ไม่สามารถอ่าน Haskell ได้
รหัสที่นี่ใช้รายการของหมายเลข 1 ถึง n สร้างรายการเรียงลำดับทั้งหมดของรายการนั้นและส่งกลับความยาวของรายการนั้น บนเครื่องของฉันใช้เวลาประมาณ 20 นาทีสำหรับ 13! จากนั้นควรใช้เวลาสี่ชั่วโมงเป็นเวลา 14 ชั่วโมง! และอีกสองวันครึ่งเป็นเวลา 15! ยกเว้นว่าในบางจุดคุณมีหน่วยความจำไม่เพียงพอ
แก้ไข 2: จริง ๆ แล้วคุณอาจจะไม่เหลือหน่วยความจำเนื่องจากนี่คือ Haskell (ดูความคิดเห็นด้านล่าง) คุณอาจจะสามารถบังคับให้ประเมินรายการและเก็บไว้ในหน่วยความจำได้ แต่ฉันไม่รู้เกี่ยวกับการเพิ่มประสิทธิภาพ (และไม่เพิ่มประสิทธิภาพ) Haskell เพื่อให้รู้ว่าจะทำอย่างไร
[1..n]
รายการ - หนึ่งการเปลี่ยนแปลงโดยเฉพาะอย่างยิ่งของ[1..n]
consed ไป thunk สำหรับส่วนที่เหลือของการเรียงสับเปลี่ยน (พหุนามในn
) - การสะสมสำหรับlength
ฟังก์ชั่น
เนื่องจากนี่เป็นปัญหาทางคณิตศาสตร์จึงเหมาะสมที่จะใช้แอปพลิเคชันที่ออกแบบมาเพื่อแก้ปัญหาทางคณิตศาสตร์เพื่อทำการคำนวณ ...
ติดตั้ง MATLAB ฉันคิดว่าการทดลองใช้งานได้ แต่ปัญหาที่ซับซ้อนสุด ๆ นี้มีความสำคัญพอที่จะทำบุญซื้อเวอร์ชันเต็มของแอปพลิเคชัน
รวมส่วนประกอบ MATLAB COM ในแอปพลิเคชันของคุณ
public string Factorial(uint n) {
MLApp.MLApp matlab = new MLApp.MLApp();
return matlab.Execute(String.Format("factorial({0})", n);
}
แฟคทอเรียลเป็นการดำเนินการทางคณิตศาสตร์ในระดับที่สูงขึ้นซึ่งอาจย่อยยากในคราวเดียว ทางออกที่ดีที่สุดในการแก้ปัญหาการเขียนโปรแกรมเช่นนี้คือการแบ่งงานขนาดใหญ่หนึ่งงานออกเป็นงานเล็ก ๆ
ตอนนี้ n! หมายถึง 1 * 2 * ... * n ดังนั้นในสาระสำคัญการคูณซ้ำและการคูณคืออะไรนอกจากการเติมซ้ำ ดังนั้นโดยที่ในใจต่อไปนี้จะช่วยแก้ปัญหานี้:
long Factorial(int n)
{
if(n==0)
{
return 1;
}
Stack<long> s = new Stack<long>();
for(var i=1;i<=n;i++)
{
s.Push(i);
}
var items = new List<long>();
var n2 = s.Pop();
while(s.Count >0)
{
var n3 = s.Pop();
items.AddRange(FactorialPart(n2,n3));
n2 = items.Sum();
}
return items.Sum()/(n-1);
}
IEnumerable<long> FactorialPart(long n1, long n2)
{
for(var i=0;i<n2;i++){
yield return n1;
}
}
#include <math.h>
int factorial(int n)
{
const double g = 7;
static const double p[] = { 0.99999999999980993, 676.5203681218851,
-1259.1392167224028, 771.32342877765313,
-176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6,
1.5056327351493116e-7 };
double z = n - 1 + 1;
double x = p[0];
int i;
for ( i = 1; i < sizeof(p)/sizeof(p[0]); ++i )
x += p[i] / (z + i);
return sqrt(2 * M_PI) * pow(z + g + 0.5, z + 0.5) * exp(-z -g -0.5) * x + 0.5;
}
โทรลล์:
z = n - 1 + 1
คือการจัดทำเอกสารด้วยตนเองถ้าคุณรู้ว่าเกิดอะไรขึ้นp[]
โดยใช้การคำนวณซ้ำของค่าสัมประสิทธิ์อนุกรม!(มันเป็นฟังก์ชั่นการประมาณค่าแกมม่าของLanczos )
- 1 + 1
อะไรบ้าง? คอมไพเลอร์ของฉันปรับมันให้เหมาะสม (ไม่ใช่ตัวเลขจุดลอยตัวที่การปรับโค้ดให้เหมาะสมเช่นนี้อาจเป็นอันตรายได้) ดังนั้นจึงดูเหมือนว่าไม่จำเป็น
double z = n - 1
เป็นส่วนหนึ่งของฟังก์ชันแกมมาโดยประมาณ + 1
จากความสัมพันธ์ที่gamma(n + 1) = n!
สำหรับจำนวนเต็ม n
เราทุกคนรู้จากวิทยาลัยว่าวิธีที่มีประสิทธิภาพที่สุดในการคำนวณการคูณคือการใช้ลอการิทึม ท้ายที่สุดแล้วทำไมคนอื่นจะใช้ตารางลอการิทึมเป็นร้อย ๆ ปี?
ดังนั้นจากตัวตนa*b=e^(log(a)+log(b))
เราจึงสร้างรหัส Python ดังต่อไปนี้:
from math import log,exp
def fac_you(x):
return round(exp(sum(map(log,range(1,x+1)))))
for i in range(1,99):
print i,":",fac_you(i)
มันสร้างรายการของตัวเลขจาก1
ถึงx
( +1
เป็นสิ่งจำเป็นเนื่องจาก Python sucks) คำนวณลอการิทึมของแต่ละจำนวนรวมยก e เพื่ออำนาจของผลรวมและในที่สุดก็รอบค่าเป็นจำนวนเต็มที่ใกล้ที่สุด (เพราะหลาม sucks) . Python มีฟังก์ชันในตัวสำหรับการคำนวณแฟคทอเรียล แต่ใช้ได้กับจำนวนเต็มเท่านั้นดังนั้นจึงไม่สามารถสร้างจำนวนมากได้ (เนื่องจาก Python sucks) นี่คือสาเหตุที่จำเป็นต้องใช้ฟังก์ชันด้านบน
Btw คำแนะนำทั่วไปสำหรับนักเรียนคือหากบางสิ่งบางอย่างไม่ได้ผลตามที่คาดไว้อาจเป็นเพราะภาษาดูด
น่าเสียดายที่ Javascript ไม่มีวิธีการคำนวณแฟคทอเรียลในตัว แต่คุณสามารถใช้ความหมายของมันใน combinatorics เพื่อกำหนดค่าอย่างไรก็ตาม:
แฟคทอเรียลของตัวเลข n คือจำนวนการเรียงสับเปลี่ยนของรายการขนาดนั้น
ดังนั้นเราสามารถสร้างหมายเลข n หลักทุกรายการตรวจสอบว่าเป็นการเปลี่ยนแปลงหรือไม่และหากเป็นเช่นนั้นให้เพิ่มจำนวนตัวนับ:
window.factorial = function($nb_number) {
$nb_trials = 1
for($i = 0; $i < $nb_number; $i++) $nb_trials *= $nb_number
$nb_successes = 0
__trying__:
for($nb_trial = 0; $nb_trial < $nb_trials; $nb_trial++){
$a_trial_split = new Array
$nb_tmp = $nb_trial
for ($nb_digit = 0; $nb_digit < $nb_number; $nb_digit++){
$a_trial_split[$nb_digit] = $nb_tmp - $nb_number * Math.floor($nb_tmp / $nb_number)
$nb_tmp = Math.floor($nb_tmp / $nb_number)
}
for($i = 0; $i < $nb_number; $i++)
for($j = 0; $j < $nb_number; $j++)
if($i != $j)
if($a_trial_split[$i] == $a_trial_split[$j])
continue __trying__
$nb_successes += 1
}
return $nb_successes
}
alert("input a number")
document.open()
document.write("<input type = text onblur = alert(factorial(parseInt(this.value))))>")
document.close()
โทรลล์:
O(n)
ไม่ได้แต่O(n!)
O(n^n)
สิ่งนี้เพียงอย่างเดียวก็เพียงพอแล้วที่จะมีคุณสมบัติที่นี่number.toString(base)
แต่มันใช้ไม่ได้กับฐานที่สูงกว่า 36 ใช่ฉันรู้ว่า 36! มีมากแต่ก็ยัง ...Math.pow
? ไม่มี? โอ้ดี++
นอกลูปทำให้มันลึกลับยิ่งกว่าเดิม นอกจากนี้ยัง==
เป็นสิ่งที่ไม่ดี$i
นอกจากนี้สภาพด้านนอกสามารถหลีกเลี่ยงได้โดยการสิ้นสุดภายในวงที่new Array
, document.write
(กับเพื่อน) และalert
(แทนพร้อมท์หรือฉลากการป้อนข้อมูล) รูปแบบ Trifecta สมบูรณ์ของบาปทางเลือกฟังก์ชั่น ทำไมอินพุทจึงถูกเพิ่มเข้ามาแบบไดนามิกหลังจากทั้งหมด?=
ทำให้พวกเขาอ่านยากขึ้นRuby และ WolframAlpha
วิธีการแก้ปัญหานี้ใช้ WolframAlpha REST API เพื่อคำนวณแฟคทอเรียลด้วย RestClient เพื่อดึงข้อมูลโซลูชันและ Nokogiri เพื่อแยกวิเคราะห์ มันไม่ได้คิดค้นใหม่ล้อใด ๆ และใช้เทคโนโลยีที่ผ่านการทดสอบและเป็นที่นิยมเพื่อให้ได้ผลลัพธ์ในแบบที่ทันสมัยที่สุดเท่าที่จะเป็นไปได้
require 'rest-client'
require 'nokogiri'
n = gets.chomp.to_i
response = Nokogiri::XML(RestClient.get("http://api.wolframalpha.com/v2/query?input=#{n}!&format=moutput&appid=YOUR_APP_KEY"))
puts response.xpath("//*/moutput/text()").text
Javascript เป็นภาษาโปรแกรมที่ใช้งานได้ซึ่งหมายความว่าคุณต้องใช้ฟังก์ชั่นสำหรับทุกสิ่งเพราะมันเร็วกว่า
function fac(n){
var r = 1,
a = Array.apply(null, Array(n)).map(Number.call, Number).map(function(n){r = r * (n + 1);});
return r;
}
r = -~(function(){})
จะแก้ปัญหานั้นอย่างแน่นอน
public class Factorial {
public static void main(String[] args) {
//take the factorial of the integers from 0 to 7:
for(int i = 0; i < 8; i++) {
System.out.println(i + ": " + accurate_factorial(i));
}
}
//takes the average over many tries
public static long accurate_factorial(int n) {
double sum = 0;
for(int i = 0; i < 10000; i++) {
sum += factorial(n);
}
return Math.round(sum / 10000);
}
public static long factorial(int n) {
//n! = number of ways to sort n
//bogo-sort has O(n!) time, a good approximation for n!
//for best results, average over several passes
//create the list {1, 2, ..., n}
int[] list = new int[n];
for(int i = 0; i < n; i++)
list[i] = i;
//mess up list once before we begin
randomize(list);
long guesses = 1;
while(!isSorted(list)) {
randomize(list);
guesses++;
}
return guesses;
}
public static void randomize(int[] list) {
for(int i = 0; i < list.length; i++) {
int j = (int) (Math.random() * list.length);
//super-efficient way of swapping 2 elements without temp variables
if(i != j) {
list[i] ^= list[j];
list[j] ^= list[i];
list[i] ^= list[j];
}
}
}
public static boolean isSorted(int[] list) {
for(int i = 1; i < list.length; i++) {
if(list[i - 1] > list[i])
return false;
}
return true;
}
}
ใช้งานได้จริงช้ามากและไม่แม่นยำสำหรับตัวเลขที่สูงขึ้น
PERL
ปัจจัยอาจเป็นปัญหาได้ยาก แผนที่ / ย่อเช่นเทคนิค - เช่นเดียวกับที่ Google ใช้ - สามารถแยกคณิตศาสตร์โดยการแยกกระบวนการและรวบรวมผลลัพธ์ สิ่งนี้จะใช้ประโยชน์จากคอร์หรือซีพียูทั้งหมดในระบบของคุณในคืนฤดูหนาวที่หนาวเหน็บ
บันทึกเป็น f.perl และ chmod 755 เพื่อให้แน่ใจว่าคุณสามารถเรียกใช้ได้ คุณมีการติดตั้งขยะทางพยาธิวิทยาผสมผสานจากลิสเตอร์ใช่หรือไม่?
#!/usr/bin/perl -w
use strict;
use bigint;
die "usage: f.perl N (outputs N!)" unless ($ARGV[0] > 1);
print STDOUT &main::rangeProduct(1,$ARGV[0])."\n";
sub main::rangeProduct {
my($l, $h) = @_;
return $l if ($l==$h);
return $l*$h if ($l==($h-1));
# arghhh - multiplying more than 2 numbers at a time is too much work
# find the midpoint and split the work up :-)
my $m = int(($h+$l)/2);
my $pid = open(my $KID, "-|");
if ($pid){ # parent
my $X = &main::rangeProduct($l,$m);
my $Y = <$KID>;
chomp($Y);
close($KID);
die "kid failed" unless defined $Y;
return $X*$Y;
} else {
# kid
print STDOUT &main::rangeProduct($m+1,$h)."\n";
exit(0);
}
}
โทรลล์:
ARGV[0]
เป็นอาร์กิวเมนต์แรกไม่ใช่สคริปต์!
$ARGV[0]
เพราะภาษาส่วนใหญ่ฉันรู้ว่ามันมี
อัลกอริทึม O (n! * n ^ 2) เพื่อค้นหาแฟคทอเรียล กรณีฐานการจัดการ ไม่มีล้น
def divide(n,i):
res=0
while n>=i:
res+=1
n=n-i
return res
def isdivisible(n,numbers):
for i in numbers:
if n%i!=0:
return 0
n=divide(n,i)
return 1
def factorial(n):
res = 1
if n==0: return 1 #Handling the base case
while not isdivisible(res,range(1,n+1)):
res+=1
return res
มีวิธีแก้ปัญหาอย่างง่ายใน Golfscript คุณสามารถใช้ล่าม Golfscript และเรียกใช้รหัสนี้:
.!+,1\{)}%{*}/
ง่ายฮะ :) โชคดี!
!
factorial[n_] := Length[Permutations[Table[k, {k, 1, n}]]]
ดูเหมือนจะไม่ทำงานสำหรับตัวเลขที่มากกว่า 11 และแฟคทอเรียล [11] ทำให้คอมพิวเตอร์ของฉันแข็ง
f=->(n) { return 1 if n.zero?; t=0; t+=1 until t/n == f[n-1]; t }
ซับที่ช้าที่สุดที่ฉันจินตนาการได้ มันต้องใช้เวลา 2 นาทีใน i7 6!
โปรเซสเซอร์ในการคำนวณ
แนวทางที่ถูกต้องสำหรับปัญหาทางคณิตศาสตร์ที่ยากเหล่านี้คือ DSL ดังนั้นฉันจะทำแบบนี้ในแง่ของภาษาที่เรียบง่าย
data DSL b a = Var x (b -> a)
| Mult DSL DSL (b -> a)
| Plus DSL DSL (b -> a)
| Const Integer (b -> a)
ในการเขียน DSL ของเราเป็นสิ่งที่ดีหากเรามองว่ามันเป็น monad ฟรีที่สร้างขึ้นโดย functor เกี่ยวกับพีชคณิต
F X = X + F (DSL b (F X)) -- Informally define + to be the disjoint sum of two sets
เราสามารถเขียนมันใน Haskell เป็น
Free b a = Pure a
| Free (DSL b (Free b a))
ฉันจะปล่อยให้ผู้อ่านได้รับการนำไปปฏิบัติเล็กน้อย
join :: Free b (Free b a) -> Free b a
return :: a -> Free b a
liftF :: DSL b a -> Free b a
ตอนนี้เราสามารถสืบทอดการทำงานเพื่อจำลองปัจจัยใน DSL นี้
factorial :: Integer -> Free Integer Integer
factorial 0 = liftF $ Const 1 id
factorial n = do
fact' <- factorial (n - 1)
liftF $ Mult fact' n id
ตอนนี้เราได้สร้างแบบจำลองนี้ขึ้นมาเราเพียงแค่ต้องจัดหาฟังก์ชั่นการตีความที่เกิดขึ้นจริงสำหรับ monad ฟรีของเรา
denote :: Free Integer Integer -> Integer
denote (Pure a) = a
denote (Free (Const 0 rest)) = denote $ rest 0
...
และฉันจะทิ้งส่วนที่เหลือของ denotation ไปยังผู้อ่าน
ในการปรับปรุงความสามารถในการอ่านบางครั้งก็มีประโยชน์ในการนำเสนอ AST ที่เป็นรูปธรรมของแบบฟอร์ม
data AST = ConstE Integer
| PlusE AST AST
| MultE AST AST
และจากนั้นก็เป็นภาพสะท้อนเล็กน้อย
reify :: Free b Integer -> AST
แล้วมันก็ตรงไปตรงมาเพื่อประเมิน AST ซ้ำ ๆ
factorial
รูทีนและแบ่งสตริงภายในเป็นตัวเลขเพื่อให้สามารถทำการคูณได้
นี่คือรหัส: getDigits
ฟังก์ชั่นจะแยกสตริงที่แสดงตัวเลขเป็นหลักดังนั้น "1234" จึงกลายเป็น[ 4, 3, 2, 1 ]
(ลำดับย้อนกลับทำให้ฟังก์ชันincrease
และmultiply
ฟังก์ชันง่ายขึ้น) increase
ฟังก์ชั่นใช้เวลารายการดังกล่าวและการเพิ่มขึ้นของมันโดยหนึ่ง เป็นชื่อแนะนำ, multiply
คูณฟังก์ชั่นเช่นmultiply([2, 1], [3])
ผลตอบแทน[ 6, 3 ]
เพราะ 12 ครั้ง 3 เป็น 36 ผลงานในลักษณะเดียวกันนี้ตามที่คุณต้องการบางสิ่งบางอย่างคูณด้วยปากกาและกระดาษ
จากนั้นในที่สุดfactorial
ฟังก์ชันจะใช้ฟังก์ชันตัวช่วยเหล่านี้เพื่อคำนวณแฟคทอเรียลจริงเช่นfactorial("9")
ให้"362880"
เป็นเอาต์พุต
import copy
def getDigits(n):
digits = []
for c in n:
digits.append(ord(c) - ord('0'))
digits.reverse()
return digits
def increase(d):
d[0] += 1
i = 0
while d[i] >= 10:
if i == len(d)-1:
d.append(0)
d[i] -= 10
d[i+1] += 1
i += 1
def multiply(a, b):
subs = [ ]
s0 = [ ]
for bi in b:
s = copy.copy(s0)
carry = 0
for ai in a:
m = ai * bi + carry
s.append(m%10)
carry = m//10
if carry != 0:
s.append(carry)
subs.append(s)
s0.append(0)
done = False
res = [ ]
termsum = 0
pos = 0
while not done:
found = False
for s in subs:
if pos < len(s):
found = True
termsum += s[pos]
if not found:
if termsum != 0:
res.append(termsum%10)
termsum = termsum//10
done = True
else:
res.append(termsum%10)
termsum = termsum//10
pos += 1
while termsum != 0:
res.append(termsum%10)
termsum = termsum//10
return res
def factorial(x):
if x.strip() == "0" or x.strip() == "1":
return "1"
factorial = [ 1 ]
done = False
number = [ 1 ]
stopNumber = getDigits(x)
while not done:
if number == stopNumber:
done = True
factorial = multiply(factorial, number)
increase(number)
factorial.reverse()
result = ""
for c in factorial:
result += chr(c + ord('0'))
return result
print factorial("9")
ในไพ ธ อนจำนวนเต็มไม่มีขีด จำกัด ดังนั้นหากคุณต้องการทำสิ่งนี้ด้วยตนเองคุณสามารถทำได้
fac = 1
for i in range(2,n+1):
fac *= i
นอกจากนี้ยังมีmath.factorial(n)
ฟังก์ชั่นที่สะดวกมาก
เห็นได้ชัดว่าวิธีการแก้ปัญหานี้มีความซับซ้อนมากกว่าที่จำเป็น แต่มันใช้งานได้และในความเป็นจริงมันแสดงให้เห็นว่าคุณสามารถคำนวณแฟคทอเรียลได้อย่างไรในกรณีที่คุณถูก จำกัด ด้วย 32 หรือ 64 บิต ดังนั้นในขณะที่ไม่มีใครเชื่อว่านี่เป็นวิธีการแก้ปัญหาที่คุณคิดขึ้นมาสำหรับปัญหาง่ายๆ (อย่างน้อยใน Python) คุณสามารถเรียนรู้บางสิ่งได้
การแก้ปัญหาที่สมเหตุสมผลที่สุดคือการตรวจสอบตัวเลขทั้งหมดอย่างชัดเจนจนกว่าคุณจะพบหมายเลขที่เป็นปัจจัยของตัวเลขที่กำหนด
print('Enter the number')
n=int(input())
x=1
while True:
x+=1
tempx=int(str(x))
d=True
for i in range(1, n+1):
if tempx/i!=round(tempx/i):
d=False
else:
tempx/=i
if d:
print(x)
break
ทุกคนรู้ว่าทางออกที่ดีที่สุดสำหรับแฟคทอเรียลนั้นวนเวียนอยู่ซ้ำ
factorial:
0! = 1
1! = 1
n! = n * (n - 1)!
แต่การคูณสามารถกำหนดแบบวนซ้ำเป็นการเพิ่มเติมต่อเนื่อง
คูณ:
n * 0 = 0
n * 1 = n
n * m = n + n * (m - 1)
และเพื่อให้สามารถเพิ่มขึ้นเป็นลำดับอย่างต่อเนื่อง
ส่วนที่เพิ่มเข้าไป:
n + 0 = n
n + 1 = (n + 1)
n + m = (n + 1) + (m - 1)
ในC
เราสามารถใช้++x
และ--x
จัดการดั้งเดิม(x + 1)
และ(x - 1)
ตามลำดับดังนั้นเราจึงมีทุกอย่างที่กำหนดไว้
#include <stdlib.h>
#include <stdio.h>
// For more elegance, use T for the type
typedef unsigned long T;
// For even more elegance, functions are small enough to fit on one line
// Addition
T A(T n, T m) { return (m > 0)? A(++n, --m) : n; }
// Multiplication
T M(T n, T m) { return (m > 1)? A(n, M(n, --m)): (m? n: 0); }
// Factorial
T F(T n) { T m = n; return (m > 1)? M(n, F(--m)): 1; }
int main(int argc, char **argv)
{
if (argc != 2)
return 1;
printf("%lu\n", F(atol(argv[1])));
return 0;
}
ลองดูสิ:
$ ./factorial 0
1
$ ./factorial 1
1
$ ./factorial 2
2
$ ./factorial 3
6
$ ./factorial 4
24
$ ./factorial 5
120
$ ./factorial 6
720
$ ./factorial 7
5040
$ ./factorial 8
40320
สมบูรณ์แบบแม้ว่า 8! ใช้เวลานานด้วยเหตุผลบางอย่าง แหมโซลูชั่นที่สง่างามที่สุดไม่ใช่วิธีที่เร็วที่สุดเสมอไป มาต่อกันที่:
$ ./factorial 9
อืมฉันจะแจ้งให้คุณทราบเมื่อมันกลับมา ...
ตามที่ระบุในคำตอบของ @ Matt_Sieker แฟคทอเรียลสามารถแยกออกเป็นส่วนเสริมได้ - ทำไมการเลิกงานจึงเป็นสาระสำคัญของการเขียนโปรแกรม แต่เราสามารถแยกมันออกเป็น 1 ได้!
def complicatedfactorial(n):
def addby1(num):
return num + 1
def addnumbers(a,b):
copy = b
cp2 = a
while b != 0:
cp2 = addby1(cp2)
b -= 1
def multiply(a,b):
copy = b
cp2 = a
while b != 0:
cp2 = addnumbers(cp2,cp2)
if n == 0:
return 1
else:
return multiply(complicatedfactorial(n-1),n)
ฉันคิดว่ารหัสนี้รับประกันข้อผิดพลาด SO เพราะ
การเรียกซ้ำ - ทำให้อุ่นขึ้น
แต่ละเลเยอร์สร้างการเรียกเพื่อคูณ
ซึ่งสร้างสายเพื่อเพิ่มหมายเลข
ซึ่งสร้างสายเพื่อ addby1!
ฟังก์ชั่นมากเกินไปใช่ไหม
:yumtcInputdrtb@gmail And:cReturnbunchojunk@Yahoo A!op:sEnd:theemailaddressIS Crazy ANSWER LOL
มันใช้งานได้จริง :)
เห็นได้ชัดว่างานของโปรแกรมเมอร์คือการทำงานให้น้อยที่สุดเท่าที่จะทำได้และใช้ไลบรารีให้มากที่สุดเท่าที่จะทำได้ ดังนั้นเราจึงต้องการที่จะนำเข้าjQuery และ math.js ตอนนี้งานง่ายอย่างนี้:
$.alert=function(message){
alert(message);
}$.factorial=function(number){
alert(math.eval(number+"!"));
return math.eval(number+"!");
}
$.factorial(10);
ด้วยการปรับเปลี่ยนเล็กน้อยของการใช้แฟ็กทอเรียลแบบเรียกซ้ำมาตรฐานมันจะช้าเกินไปสำหรับ n> 10
def factorial(n):
if n in (0, 1):
return 1
else:
result = 0
for i in range(n):
result += factorial(n - 1)
return result
#! /bin/bash
function fact {
if [[ ${1} -le 1 ]]; then
return 1
fi;
fact $((${1} - 1))
START=$(date +%s)
for i in $(seq 1 $?); do sleep ${1}; done
END=$(date +%s)
RESULT=$(($END - $START))
return $RESULT
}
fact ${1}
echo $?
ลองที่จะทำมันด้วยมอนติคาร์โลวิธี เราทุกคนรู้ว่าความน่าจะเป็นของการสุ่มสองn- permutations เท่ากับเท่ากับ1 / n! . ดังนั้นเราสามารถตรวจสอบจำนวนการทดสอบที่ต้องการ (เรียกหมายเลขนี้ข ) จนกว่าเราจะได้รับความนิยมc จากนั้นn! ~ B / C
def RandomPermutation(n) :
t = range(0,n)
for i in xrange(n-1,0,-1):
x = t[i]
r = randint(0,i)
t[i] = t[r]
t[r] = x
return t
def MonteCarloFactorial(n,c) :
a = 0
b = 0
t = RandomPermutation(n)
while a < c :
t2 = list(t)
t = RandomPermutation(n)
if t == t2 :
a += 1
b += 1
return round(b/c)
MonteCarloFactorial(5,1000)
# returns an estimate of 5!
แฟกทอรีสามารถกำหนดได้อย่างง่ายดายด้วยเครื่องมือบรรทัดคำสั่งที่รู้จักกันดีจากการทุบตี
read -p "Enter number: " $n
seq 1 $n | xargs echo | tr ' ' '*' | bc
อย่างที่ @Aaron Davies พูดถึงในคอมเม้นต์นี่มันดูเป็นระเบียบมากและเราทุกคนก็ต้องการโปรแกรมที่ดีและเป็นระเบียบใช่มั้ย
read -p "Enter number: " $n
seq 1 $n | paste -sd\* | bc
paste
คำสั่ง:seq 1 $n | paste -sd\* | bc
paste
ดูเหมือนคำภาษาอังกฤษทั่วไปและง่ายต่อการจดจำ เราต้องการสิ่งนั้นจริงหรือ ; o)