C, 150 140 135 bayt
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 sistemleri için olan versiyon budur; dizesini değiştirmek 33436ile 11214bir EBCDIC sistem için, ya da \1\1\2\1\4taşınabilir bir program için.
C çözümleri, tam bir program sağlama zorunluluğu tarafından biraz engellenmiştir; ancak, bu soruyu tam olarak cevaplıyor.
Çevrimiçi deneyin (Javascript gerektirir):
açıklama
N En Az Önemli Sıfır Basamağında belirtilen algoritmaya dayanmaktadır ! , döndü, böylece beşin en yüksek gücünü bulmak için tekrar girip tekrar hesaplamayı yaptık. Sabit tabloları çok büyüktü, bu yüzden önceki kalıntı r, mevcut basamak dve özyineleme derinliği arasında bir ilişki bularak onları azalttım 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
Çünkü r>0bu, sabit bir zaman rsürelerine 2^dk(mod 5) düzelir ; sabitler a[]aşağıdadır (golf kodunda belirtilmiştir). Bunun (2^4)%51 olduğunu da gözlemliyoruz , bu nedenle menzili taşmasını önlemek için üssü azaltabiliriz 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 */
}
Testler:
$ for i in 100 1000 10000 100000; do echo $i: `./694 $i`; done
100: 4
1000: 2
10000: 8
100000: 6
1000000: 4
Performans da saygıdeğerdir. İşte 32 bitlik bir sistem için maksimum giriş int:
$ time ./694 2147483647
8
real 0m0.001s
user 0m0.000s
sys 0m0.000s
Aynı zamanlamaları maksimum 64 bit ile de aldım int.