Cifre non zero di un fattoriale in base


22

Dovresti scrivere un programma o una funzione che ha dato tre numeri interi positivi n b kcome output di input o restituisce le ultime kcifre prima degli zeri finali nella brappresentazione di base di n!.

Esempio

n=7 b=5 k=4
factorial(n) is 5040
5040 is 130130 in base 5
the last 4 digits of 130130 before the trailing zeros are 3013
the output is 3013

Ingresso

  • 3 numeri interi positivi n b kdove 2 <= b <= 10.
  • L'ordine degli interi di input può essere scelto arbitrariamente.

Produzione

  • Un elenco di cifre restituite o emesse come un numero intero o un elenco intero.
  • Gli zeri iniziali sono facoltativi.
  • La tua soluzione deve risolvere qualsiasi caso di test di esempio in meno di un minuto sul mio computer (testerò solo casi chiusi. Ho un PC sotto la media.).

Esempi

Nuovi test aggiunti per verificare la correttezza degli invii. (Non fanno parte della regola di runtime inferiore a 1 minuto.)

Input => Output (con la scelta di omettere gli zeri iniziali)

3 10 1  =>  6

7 5 4  =>  3013

3 2 3  =>  11

6 2 10  =>  101101

9 9 6  =>  6127

7 10 4  =>  504

758 9 19  =>  6645002302217537863

158596 8 20  =>  37212476700442254614

359221 2 40  =>  1101111111001100010101100000110001110001

New tests:
----------

9 6 3  =>  144

10 6 3  =>  544

Questo è code-golf, quindi vince l'ingresso più breve.


1
meno di un minuto sul mio computer è un po 'difficile da mirare se non conosciamo alcun dettaglio.
Dennis,

1
Emetterebbe 7 5 3"013" o "13"?
Claudiu,

1
@Claudiu in base al 7 10 4caso di test direi13
Maltysen,

2
@Claudiu "Gli zeri iniziali sono opzionali." quindi entrambe le versioni sono corrette.
randomra,

1
Dobbiamo accettare un numero intero positivo per no k? O possiamo limitarli all'intervallo del tipo intero della lingua?
Toby Speight

Risposte:


1

Dyalog APL , 23 byte

⌽k↑⌽{⍵↓⍨-⊥⍨0=⍵}b⊥⍣¯1⊢!n

Questo programma funziona fintanto che il fattoriale non supera il limite di rappresentazione interna. In Dyalog APL, il limite può essere aumentato di⎕FR←1287 .

Presuppone che siano state impostate le variabili n, b e k (ad es. n b k←7 5 4), Ma se si desidera piuttosto richiedere n , b e k (in questo ordine), sostituire i tre caratteri con .


Ogni caso di test che ho lanciato è stato calcolato in circa 11 microsecondi sulla mia macchina (M540).
Adám,

7

Mathematica, 57 48 byte

Salvataggio di 9 byte grazie a @ 2012rcampion.

IntegerString[#!/#2^#!~IntegerExponent~#2,##2]&

Non ho mai usato la matematica, ma non potresti scambiare l'ordine degli argomenti per fare bprima il salvataggio di 2 byte?
FryAmTheEggman,

@FryAmTheEggman Sono nuovo nella comunità del golf, lo scambio di argomenti "kosher"?
2012campo

1
Puoi effettivamente arrivare a 47: IntegerString[#!#2^-#!~IntegerExponent~#2,##2]&(sia questo che il tuo originale sono abbastanza veloci)
2012rcampion

Il richiedente ha scritto: "L'ordine degli interi di input può essere scelto arbitrariamente". sotto input, quindi in questo caso va decisamente bene
FryAmTheEggman

@Fry Wow, sembra che non abbia letto abbastanza attentamente. Tuttavia, il SlotSequencetrucco che ho usato nel mio commento funziona solo con l'ordine corrente, quindi non puoi più salvarlo.
2012campo

7

Python, 198 192 181 caratteri

def F(n,b,k):
 p=5820556928/8**b%8;z=0;e=f=x=1
 while n/p**e:z+=n/p**e;e+=1
 z/=1791568/4**b%4;B=b**(z+k)
 while x<=n:f=f*x%B;x+=1
 s='';f/=b**z
 while f:s=str(f%b)+s;f/=b
 return s

È abbastanza veloce, ~ 23 secondi sul più grande esempio. E nessun fatto fattoriale (ti sto guardando, Mathematica!).


[2,3,2,5,3,7,2,3,5][b-2]potrebbe essere int('232537235'[b-2])di salvare 3 byte. [1,1,2,1,1,1,3,2,1][b-2]allo stesso modo.
randomra,

Per quest'ultimo, una tabella di ricerca 111973>>2*(b-2)&3è ancora più breve. È lo stesso numero di byte per il primo però ( 90946202>>3*(b-2)&7).
Sp3000,

nvm sembra che tu abbia ragione sulla cosa delle cifre più alte
Sp3000,

Credo che puoi salvare qualche byte rendendolo un programma e non una funzione.
FryAmTheEggman,

6

Pyth, 26 35 byte

M?G%GHg/GHH.N>ju%g*GhHT^T+YslNN1T_Y

Questa è una funzione di 3 argomenti, numero, base, numero di cifre.

Dimostrazione.

Il caso di test più lento, l'ultimo, impiega 15 secondi sulla mia macchina.


@ Sp3000 Ho aggiunto una correzione che penso dovrebbe essere sufficiente.
isaacg,

2

PARI / GP, 43 byte

La velocità di trading per lo spazio produce questo semplice algoritmo:

(n,b,k)->digits(n!/b^valuation(n!,b)%b^k,b)

Ciascuno dei casi di test viene eseguito in meno di un secondo sul mio computer.


2

Mathematica - 48 byte

#!~IntegerDigits~#2/.{l__,0...}:>{l}~PadLeft~#3&

Ungolfed:

Function[{n, b, k},
  IntegerDigits[n!, b] (* list of the base-b digits in n! *)
  /. {l__, 0...} (* match a sequence of elements l and some number of zeros*)
                 (* lucky for me, __ defaults to match the shortest number *)
     :> PadLeft[List[l], k] (* pad l to be k elements long with zeros on the left *)
                            (* this truncates the list if it is too long*)
]

Esempio:

#!~IntegerDigits~#2/.{l__,0...}:>{l}~PadLeft~#3 &
%[758, 9, 19] // Timing

(* {0.031250, {6, 6, 4, 5, 0, 0, 2, 3, 0, 2, 2, 1, 7, 5, 3, 7, 8, 6, 3}} *)

Per i casi più grandi, il fattore limitante non sta generando le cifre:

Length@IntegerDigits[359221!, 2] // Timing
(* {0.109375, 6111013} 6.1M digits in 100 ms *)

La corrispondenza del modello sembra essere O(n^2), facendo sì che gli ultimi due casi di test vadano ben oltre il segno di un minuto.


2

Bash / coreutils / dc, 60 byte

dc<<<"1 `seq -f%g* $1`$2op"|sed -r s/0+$//|tail -c$(($3+1))

Usa lo dcscript della mia risposta per trovare il fattoriale , emettendo in base $2, con sedper tagliare gli zeri finali e tailper selezionare le ultime $3cifre.


Devo ammettere che è estremamente lento con il testcase base-2 a 40 bit. Ho provato a facilitare il lavoro di sed usando revper ridurre il backtracking, ma è questo dcche sta mangiando la CPU ...
Toby Speight

2

Haskell, 111 109 byte

import Data.Digits
f n b k=digits b$foldl(((unDigits b.reverse.take k.snd.span(<1).digitsRev b).).(*))1[1..n]

Utilizzo: f 158596 8 20->[3,7,2,1,2,4,7,6,7,0,0,4,4,2,2,5,4,6,1,4]

Richiede circa 8 secondi per f 359221 2 40il mio laptop di 4 anni.

Come funziona: piega la moltiplicazione ( *) nell'elenco [1..n]. Converti ogni risultato intermedio in base bcome un elenco di cifre (prima il meno significativo), elimina gli zeri iniziali, quindi prendi le prime kcifre e converti nuovamente in base 10. Alla fine converti di bnuovo in base , ma prima con la cifra più significativa.


avevi in ​​mente l'idea che la stavo interpretando usando matlab, che coincidenza: D
Abr001am

1

Python 3, 146 byte

import math
i,f=input(),int
n=i.split()
e=math.factorial(f(n[0]))
d=''
while e>0:
 d=str((e%f(n[1])))+d;e=e//f(n[1])
print(d.strip('0')[-f(n[2]):])

Non sono sicuro che i casi di test funzioneranno tutti abbastanza velocemente - quelli più grandi sono molto lenti (poiché scorre ciclicamente il numero).

Provalo online qui (ma fai attenzione).


1

Java, 303 299 296 byte

import java.math.*;interface R{static void main(String[]a){BigInteger c=new BigInteger(a[1]),b=c.valueOf(1);for(int i=new Integer(a[0]);i>0;i--){b=b.multiply(b.valueOf(i));while(b.mod(c).equals(b.ZERO))b=b.divide(c);b=b.mod(c.pow(new Integer(a[2])));}System.out.print(b.toString(c.intValue()));}}

Sul mio computer, questo è in media un po 'meno di un terzo di secondo sul 359221 2 40testcase. Accetta input tramite argomenti della riga di comando.


1

bc, 75 byte

define void f(n,b,k){
obase=b
for(x=1;n;x%=b^k){
x*=n--
while(!x%b)x/=b}
x}

Questo utilizza alcune estensioni GNU per ridurre la dimensione del codice; un equivalente conforme a POSIX pesa 80 byte:

define f(n,b,k){
obase=b
for(x=1;n;x%=b^k){
x*=n--
while(x%b==0)x/=b}
return(x)}

Per mantenere ragionevoli i tempi di esecuzione, tagliamo gli zeri finali ( while(!x%b)x/=b) e tronciamo le kcifre finali ( x%=b^k) mentre calcoliamo il fattoriale ( for(x=1;n;)x*=n--).

Programma di test:

f(3, 10, 1)
f(7, 5, 4)
f(3, 2, 3)
f(6, 2, 10)
f(9, 9, 6)
f(7, 10, 4)
f(758, 9, 19)
f(158596, 8, 20)
f(359221, 2, 40)
f(9, 6, 3)
f(10, 6, 3)
quit

La durata dell'intera suite di test è di circa 4¼ secondi sulla mia workstation vintage del 2006.


Questo è il mio primo bcprogramma in assoluto (golf o no), quindi qualsiasi consiglio è particolarmente gradito ...
Toby Speight,

0

PHP, 80 byte

function f($a,$b,$c){echo substr(rtrim(gmp_strval(gmp_fact($a),$b),"0"),-1*$c);}

Utilizzato come f(359221,2,40)per l'ultimo test case. Funziona abbastanza agevolmente per tutti i casi di test.

Prova qui!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.