Tabandaki Faktörün Son Sıfır Olmayan Basamağı


22

n b kGiriş çıkışları olarak üç pozitif tamsayı veren bir program ya da fonksiyon yazmalı ya kda taban bgöstergesindeki sondaki sıfırlardan önceki son rakamları döndürmelisiniz n!.

Örnek

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

Giriş

  • 3 pozitif tamsayı n b knerede 2 <= b <= 10.
  • Giriş tamsayılarının sırası isteğe bağlı olarak seçilebilir.

Çıktı

  • Bir tamsayı veya tamsayı listesi olarak döndürülen veya çıkan rakamların bir listesi.
  • Önde gelen sıfırlar isteğe bağlıdır.
  • Çözümünüz bilgisayarımdaki bir dakikadan az bir sürede herhangi bir test senaryosunu çözmelidir (sadece yakın vakaları test edeceğim. Ortalamanın altında bir PC'm var.).

Örnekler

Başvuruların doğruluğunu kontrol etmek için yeni testler eklendi. (1 dakikalık çalışma zamanı kuralının altında değildirler.)

Giriş => Çıktı (baştaki sıfırların çıkarılması seçeneğiyle)

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

Bu kod golf, yani en kısa giriş kazanır.


1
Bilgisayarımdaki bir dakikadan daha azını bilmemiz biraz zor.
Dennis,

1
Misiniz 7 5 3çıkışı "013" veya "13"?
Claudiu

1
Söyleyeceğim 7 10 4test olayına dayanan @Claudiu13
Maltysen

2
@ Claudiu "Lider sıfırlar isteğe bağlıdır." bu yüzden her iki sürüm de doğru.
randomra,

1
Kabul Must herhangi pozitif tamsayı nveya k? Veya onları dilin tamsayı tipinin aralığına sınırlayabilir miyiz?
Toby Speight

Yanıtlar:


1

Dyalog APL , 23 bayt

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

Bu program, faktoring dahili temsil sınırını aşmadığı sürece çalışır. Dyalog APL'de limit yükseltilebilir ⎕FR←1287.

N, b ve k değişkenlerinin ayarlanmış olduğunu varsayar (örneğin n b k←7 5 4), ancak n , b ve k komutunu istemeyi tercih ediyorsanız (bu sırada), üç karakteri ile değiştirin .


Fırlattığım her test makinemde (M540) yaklaşık 11 mikrosaniye cinsinden hesaplandı.
Ocak'ta

7

Mathematica, 57 48 bayt

@ 2012rcampion sayesinde 9 bayt kaydedildi.

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

Asla matematiği kullanmadım, ama bönce 2 byte tasarruf etmek için argümanların sırasını değiştiremez miydiniz ?
FryAmTheEggman

@FryAmTheEggman Golf topluluğuna yeniyim, argüman sırası "koşer" takas ediyor mu?
2012rampampion

1
Aslında 47'ye gidebilirsiniz: IntegerString[#!#2^-#!~IntegerExponent~#2,##2]&(hem bu hem de sizin orijinaliniz oldukça hızlı)
2012rcampion

Soru sahibi: "Girilen tamsayıların sırası isteğe bağlı olarak seçilebilir." girdi altında, bu durumda kesinlikle iyi
FryAmTheEggman

@ Fry Wow, yeterince okumamış gibiyim. Ancak, SlotSequenceyorumumda kullandığım numara yalnızca geçerli siparişle çalışıyor, bu yüzden daha fazla tasarruf edemediniz.
2012rampampion

7

Python, 198 192 181 karakter

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

Yeterince hızlı, en büyük örnekte ~ 23 saniye. Ve hiçbir faktoring yapısı yok (Sana bakıyorum, Mathematica!).


[2,3,2,5,3,7,2,3,5][b-2]int('232537235'[b-2])3 bayt kaydetmek olabilir . [1,1,2,1,1,1,3,2,1][b-2]benzer şekilde.
randomra

İkincisi için, bir arama tablosu 111973>>2*(b-2)&3daha kısadır. Eski için aynı bayt sayısı ( 90946202>>3*(b-2)&7).
Sp3000

nvm daha yüksek rakamlar konusunda haklıymışsınız gibi görünüyor
Sp3000

Bu fonksiyonu bir program değil bir program yaparak birkaç bayttan tasarruf edebileceğinizi düşünüyorum.
FryAmTheEggman

6

Pyth, 26 35 bayt

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

Bu, 3 argüman, sayı, temel, hane sayısının bir fonksiyonudur.

Gösteri.

En yavaş test olan sonuncusu makinemde 15 saniye sürüyor.


@ Sp3000 Yeterli olması gerektiğini düşündüğüm bir düzeltme ekledim.
isaacg

2

PARI / GP, 43 bayt

Uzay için işlem yapma hızı bu basit algoritmayı sağlar:

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

Test durumlarının her biri makinemde bir saniyeden daha kısa sürede çalışıyor.


2

Mathematica - 48 bayt

#!~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*)
]

Örnek:

#!~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}} *)

En büyük durumlar için, sınırlayıcı faktör rakam üretmiyor:

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

Desen eşleştirmesi O(n^2), son iki test durumunun bir dakikalık işaretin çok ötesine gitmesine neden gibi görünüyor .


2

Bash / coreutils / dc, 60 bayt

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

Benim cevabımdakidc betiği, sonda sıfırları kesmek ve son basamağı seçmek için birlikte basmak, temelde bulmak için kullanılan Faktör'ü kullanır .$2sedtail$3


40 bit base-2 test çantasıyla oldukça yavaş olduğunu kabul etmeliyim. Sed'in çalışmalarını revgeri izlemeyi azaltmak için kullanmaya çalıştım , ama bu dcCPU'yu yiyor ...
Toby Speight

2

Haskell, 111 109 bayt

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

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

f 359221 2 404 yaşındaki dizüstü bilgisayarımda yaklaşık 8 saniye sürüyor .

Nasıl çalışır: çarpma işlemini ( *) listeye katlayın [1..n]. Her ara sonucu bbir basamak listesi (önce en az önemli olan) kolarak tabana dönüştürün , ilk önce sıfırları sıyırın, ardından ilk rakamları alın ve tekrar 10 tabanına dönüştürün. Sonunda btekrar üsse dönüşür, ancak ilk önce en önemli hane ile.


aklımda fikrin vardı, onu matlab kullanarak yorumluyordum, ne tesadüf: D
Abr001am

1

Python 3, 146 bayt

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]):])

Test senaryolarının hepsinin yeterince hızlı çalışacağından emin değilim - daha büyük olanlar çok yavaşlar (sayıya doğru döndüğü için).

Burada çevrimiçi deneyin (ancak dikkatli olun).


1

Java, 303 299 296 bayt

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()));}}

Bilgisayarımda bu, 359221 2 40test cihazındaki saniyenin üçte birinin biraz altında bir ortalama alıyor . Komut satırı argümanları ile girdi alır.


1

bc, 75 bayt

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

Bu, kod boyutunu azaltmak için bazı GNU uzantılarını kullanır; POSIX uyumlu bir eşdeğer, 80 byte ağırlığındadır:

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

Çalışma sürelerini makul tutmak için, takip eden sıfırları ( while(!x%b)x/=b) kısaltır ve sonuca kadar kısalırız.kx%=b^k keseriz ve faktörü ( for(x=1;n;)x*=n--) hesaplarken basamağa ( ) keseriz .

Test programı:

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

Tam test setinin çalışma zamanı, 2006 vintage iş istasyonumda yaklaşık 4¼ saniyedir.


Bu benim ilk bcprogramım (golf ya da değil), bu yüzden herhangi bir ipucu özellikle açığız ...
Toby Speight

0

PHP, 80 bayt

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

Olarak kullanıldı f(359221,2,40)Son test durumunda . Tüm test durumları için sorunsuz çalışır.

Burada dene!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.