C, 150 140 135 ไบต์
r,d;f(k,x){r=x<5?3:f(k+1,x/5);return(d=x%5)?r*"33436"[d]*(1<<d*k%4)%5:r;}main(int c,char**v){c=atoi(*++v);printf("%d",c<2?1:2*f(0,c));}
นี่เป็นเวอร์ชั่นสำหรับระบบ ASCII; แทนที่สตริง33436
ด้วย11214
สำหรับระบบ EBCDIC หรือด้วย\1\1\2\1\4
โปรแกรมพกพา
การแก้ปัญหา C นั้นค่อนข้าง จำกัด โดยความต้องการในการจัดหาโปรแกรมเต็มรูปแบบ อย่างไรก็ตามสิ่งนี้จะตอบคำถามได้อย่างเต็มที่
ลองออนไลน์ (ต้องใช้ Javascript):
คำอธิบาย
มันขึ้นอยู่กับอัลกอริทึมที่ระบุไว้ในNon-Zero Digit ที่สำคัญน้อยที่สุดของ n! หันกลับมาเพื่อที่เราจะได้เข้าไปค้นหาพลังสูงสุดห้าและทำการคำนวณให้ได้ ตารางค่าคงที่มีขนาดใหญ่เกินไปดังนั้นฉันจึงลดความมันลงโดยการค้นหาความสัมพันธ์ระหว่างส่วนที่เหลือก่อนหน้าจำนวนr
หลักปัจจุบันd
และความลึกแบบเรียกซ้ำk
:
0 1 2 3 4 =d
0 0 3×2^k 1×2^2k 3×2^3k 2
1 1 1×2^k 2×2^2k 1×2^3k 4
r 2 2 2×2^k 4×2^2k 2×2^3k 3
3 3 3×2^k 3×2^2k 3×2^3k 2
4 4 4×2^k 4×2^2k 4×2^3k 1
สำหรับการr>0
แก้นี้ให้คงที่ครั้งr
ครั้ง2^dk
(สมัย 5) ค่าคงที่อยู่a[]
ด้านล่าง (ขีดเส้นใต้ในรหัส golfed) นอกจากนี้เรายังสังเกตได้ว่า(2^4)%5
เป็น 1 int
เพื่อให้เราสามารถลดตัวแทนเพื่อหลีกเลี่ยงการล้นช่วงของ
const int a[] = { 1, 1, 2, 1, 4 };
int f(int k, int x){
int r = x<5 ? 3 : f(k+1,x/5); /* residue - from recursing to higher-order quinary digits */
int d = x%5;
if (!d)
return r;
return r * a[d] * (1<<d*k%4) % 5;
}
int main(int c, char **v)
{
c = atoi(*++v);
printf("%d",
c<2
? 1 /* special-case 0 & 1 */
: 2*f(0,c)); /* otherwise, it's 2 times r */
}
แบบทดสอบ:
$ for i in 100 1000 10000 100000; do echo $i: `./694 $i`; done
100: 4
1000: 2
10000: 8
100000: 6
1000000: 4
ประสิทธิภาพก็น่านับถือเช่นกัน นี่คืออินพุตสูงสุดสำหรับระบบที่มี 32- บิตint
:
$ time ./694 2147483647
8
real 0m0.001s
user 0m0.000s
sys 0m0.000s
ฉันได้รับการกำหนดเวลาเดียวกันด้วยสูงสุด 64 บิตint
ด้วย