C 150 140 135 Bytes
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));}
Dies ist die Version für ASCII-Systeme. Ersetzen Sie die Zeichenfolge 33436
durch11214
für ein EBCDIC-System oder durch \1\1\2\1\4
für ein tragbares Programm.
C-Lösungen werden durch die Anforderung, ein vollständiges Programm bereitzustellen, etwas behindert. Dies beantwortet jedoch die Frage vollständig.
Probieren Sie es online aus (erfordert Javascript):
Erläuterung
Es basiert auf dem Algorithmus, der in der am wenigsten signifikanten Nicht-Null-Ziffer von n angegeben ist! , drehte sich um, damit wir die höchste Potenz von fünf finden und die Berechnung auf dem Weg nach draußen durchführen. Die Konstantentabellen waren zu groß, deshalb habe ich sie reduziert, indem ich eine Beziehung zwischen dem vorherigen Rest r
, der aktuellen Ziffer d
und der Rekursionstiefe gefunden habe 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
Denn r>0
dies löst sich zu konstanten Zeiten r
auf 2^dk
(mod 5); Die Konstanten sind a[]
unten angegeben (im Golf Code angegeben). Wir beobachten auch, dass dies (2^4)%5
1 ist, so dass wir den Exponenten reduzieren können, um ein Überlaufen des Bereichs von zu vermeiden 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 */
}
Tests:
$ for i in 100 1000 10000 100000; do echo $i: `./694 $i`; done
100: 4
1000: 2
10000: 8
100000: 6
1000000: 4
Auch die Leistung ist respektabel. Hier ist eine maximale Eingabe für ein System mit 32-Bit int
:
$ time ./694 2147483647
8
real 0m0.001s
user 0m0.000s
sys 0m0.000s
Ich habe die gleichen Timings auch mit maximal 64-Bit int
.