ตัวเลขที่ไม่ใช่ศูนย์ล่าสุดของแฟคทอเรียลในฐาน


22

คุณควรจะเขียนโปรแกรมหรือฟังก์ชั่นที่ได้รับสามจำนวนเต็มบวกn b kเป็นผลการป้อนข้อมูลหรือผลตอบแทนที่ผ่านมาkตัวเลขก่อนที่ศูนย์ต่อท้ายในฐานตัวแทนของbn!

ตัวอย่าง

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

อินพุต

  • 3 จำนวนเต็มบวกที่n b k2 <= b <= 10
  • ลำดับของจำนวนเต็มอินพุทสามารถเลือกได้เอง

เอาท์พุต

  • รายการของตัวเลขที่ส่งคืนหรือส่งออกเป็นรายการจำนวนเต็มหรือจำนวนเต็ม
  • เลขศูนย์นำหน้าเป็นตัวเลือก
  • โซลูชันของคุณต้องแก้กรณีทดสอบตัวอย่างใด ๆในคอมพิวเตอร์ของฉัน (ฉันจะทดสอบเฉพาะกรณีที่ปิดฉันมีพีซีที่ต่ำกว่าค่าเฉลี่ย)

ตัวอย่าง

เพิ่มการทดสอบใหม่เพื่อตรวจสอบความถูกต้องของการส่ง (ไม่ได้เป็นส่วนหนึ่งของกฎรันไทม์ภายใต้ 1 นาที)

อินพุต => เอาท์พุท (พร้อมตัวเลือกสำหรับการละเว้นค่าศูนย์นำหน้า)

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

นี่คือรหัสกอล์ฟดังนั้นรายการที่สั้นที่สุดชนะ


1
ในเวลาไม่ถึงนาทีบนคอมพิวเตอร์ของฉันนั้นยากที่จะตั้งเป้าหมายหากเราไม่ทราบรายละเอียดใด ๆ
เดนนิส

1
7 5 3เอาต์พุตจะเป็น"013" หรือ "13"
Claudiu

1
@Claudiu ขึ้นอยู่กับ7 10 4กรณีทดสอบฉันจะบอกว่า13
Maltysen

2
@Claudiu "เลขศูนย์นำหน้าเป็นตัวเลือก" ดังนั้นทั้งสองรุ่นนั้นถูกต้อง
randomra

1
เราต้องยอมรับใด ๆจำนวนเต็มบวกสำหรับnหรือk? หรือเราสามารถ จำกัด ให้อยู่ในช่วงประเภทจำนวนเต็มของภาษาได้หรือไม่
Toby Speight

คำตอบ:


1

Dyalog APLขนาด 23 ไบต์

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

โปรแกรมนี้ทำงานตราบเท่าที่แฟคทอเรียลไม่เกินขีด จำกัด การเป็นตัวแทนภายใน ใน Dyalog APL ขีด จำกัด ⎕FR←1287สามารถยกได้โดย

ถือว่าตัวแปร n, B และ k ได้รับการกำหนด (เช่นn b k←7 5 4) แต่ถ้าคุณค่อนข้างต้องการกระตุ้นสำหรับn , และk (ตามลำดับ) แล้วแทนที่ตัวละครทั้งสามด้วย


ทุกกรณีการทดสอบที่ฉันโยนไปจะถูกคำนวณในเวลาประมาณ 11 ไมโครวินาทีบนเครื่องของฉัน (M540)
อดัม

7

Mathematica, 57 48 ไบต์

บันทึกแล้ว 9 ไบต์ด้วย @ 2012rcampion

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

ฉันไม่เคยใช้ mathematica มาก่อน แต่คุณไม่สามารถสลับลำดับของข้อโต้แย้งเพื่อให้bประหยัดได้ 2 ไบต์ก่อนหรือไม่
FryAmTheEggman

@FryAmTheEggman ฉันใหม่กับชุมชนนักกอล์ฟกำลังแลกเปลี่ยนคำสั่ง "kosher" หรือไม่
2012rcampion

1
คุณสามารถไปถึง 47: IntegerString[#!#2^-#!~IntegerExponent~#2,##2]&(ทั้งสิ่งนี้และต้นฉบับของคุณค่อนข้างเร็ว)
2012rcampion

ผู้ถามเขียนว่า: "ลำดับของจำนวนเต็มสามารถเลือกได้เอง" ภายใต้การป้อนข้อมูลดังนั้นในกรณีนี้มันใช้ได้แน่นอน
FryAmTheEggman

@ ทอด Wow ดูเหมือนว่าฉันไม่ได้อ่านอย่างใกล้ชิดพอ อย่างไรก็ตามSlotSequenceเคล็ดลับที่ฉันใช้ในความคิดเห็นของฉันใช้ได้กับคำสั่งซื้อปัจจุบันเท่านั้นดังนั้นคุณจึงไม่สามารถบันทึกได้อีก
2012rcampion

7

Python, 198 192 181 ตัวอักษร

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

มันเร็วพอ ~ 23 วินาทีสำหรับตัวอย่างที่ใหญ่ที่สุด และไม่มีแฟคทอเรียลในตัว (ฉันกำลังมองดูคุณมาเธมาติกา!)


[2,3,2,5,3,7,2,3,5][b-2]สามารถint('232537235'[b-2])บันทึกได้ 3 ไบต์ [1,1,2,1,1,1,3,2,1][b-2]เหมือนกับ
randomra

สำหรับหลังตารางการค้นหา111973>>2*(b-2)&3นั้นสั้นกว่า มันเป็นจำนวนไบต์เดียวกันสำหรับในอดีตแม้ว่า ( 90946202>>3*(b-2)&7)
Sp3000

nvm ดูเหมือนว่าคุณพูดถูกเกี่ยวกับตัวเลขที่สูงกว่า
Sp3000

ฉันเชื่อว่าคุณสามารถบันทึกไม่กี่ไบต์โดยการทำโปรแกรมนี้และไม่ฟังก์ชั่น
FryAmTheEggman

6

Pyth, 26 35 ไบต์

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

นี่คือฟังก์ชั่นของ 3 ข้อโต้แย้งตัวเลขฐานจำนวนหลัก

สาธิต.

เคสทดสอบที่ช้าที่สุดซึ่งเป็นเคสสุดท้ายใช้เวลา 15 วินาทีบนเครื่องของฉัน


@ Sp3000 ฉันได้เพิ่มการแก้ไขที่ฉันคิดว่าควรจะเพียงพอ
isaacg

2

PARI / GP, 43 ไบต์

ความเร็วในการซื้อขายสำหรับพื้นที่ให้ผลตอบแทนอัลกอริทึมตรงไปตรงมานี้:

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

กรณีทดสอบแต่ละกรณีทำงานในเครื่องของฉันน้อยกว่าหนึ่งวินาที


2

Mathematica - 48 ไบต์

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

ตัวอย่าง:

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

สำหรับกรณีที่ใหญ่ที่สุดปัจจัย จำกัด ไม่ได้สร้างตัวเลข:

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

การจับคู่รูปแบบดูเหมือนจะO(n^2)ทำให้เกิดกรณีทดสอบสองกรณีที่ผ่านไปไกลกว่าเครื่องหมายหนึ่งนาที


2

Bash / coreutils / dc, 60 ไบต์

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

ใช้dcสคริปต์จากคำตอบของฉันไปที่ค้นหาแฟคทอเรียลเอาท์พุทเป็นฐาน$2โดยsedตัดแต่งเลขศูนย์ต่อท้ายและtailเพื่อเลือก$3ตัวเลขสุดท้าย


ฉันต้องยอมรับว่ามันช้ามากกับ 40-bit base-2 testcase ฉันพยายามทำให้การทำงานของ sed ผ่อนคลายโดยใช้revเพื่อลดการย้อนรอย แต่มันคือdcการกินซีพียู ...
Toby Speight

2

Haskell, 111 109 ไบต์

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

การใช้งาน: f 158596 8 20 ->[3,7,2,1,2,4,7,6,7,0,0,4,4,2,2,5,4,6,1,4]

ใช้เวลาประมาณ 8 วินาที f 359221 2 40แล็ปท็อปอายุ 4 ปีของฉัน

วิธีการทำงาน: พับคูณ ( *) [1..n]ลงในรายการ แปลงทุกผลกลางถึงเบสbเป็นรายการของตัวเลข (สำคัญน้อยที่สุดก่อน), ตัดศูนย์นำหน้าจากนั้นนำkตัวเลขแรกและแปลงเป็นฐาน 10 อีกครั้ง ในที่สุดก็แปลงเป็นเบสbอีกครั้ง แต่ด้วยหลักที่สำคัญที่สุดก่อน


คุณมีความคิดในใจของฉันว่าฉันตีความมันโดยใช้ matlab สิ่งที่เกิดขึ้นพร้อมกัน: D
Abr001am

1

Python 3, 146 ไบต์

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

ฉันไม่แน่ใจว่ากรณีทดสอบทั้งหมดจะทำงานเร็วพอ - กรณีที่ใหญ่กว่านั้นช้ามาก (เนื่องจากวนรอบจำนวน)

ลองออนไลน์ได้ที่นี่ (แต่ระวัง)


1

Java, 303 299 296 ไบต์

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

ในคอมพิวเตอร์ของฉันค่าเฉลี่ยนี้น้อยกว่าหนึ่งในสามของวินาทีใน359221 2 40testcase รับอินพุตผ่านอาร์กิวเมนต์บรรทัดคำสั่ง


1

bc, 75 ไบต์

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

ใช้ส่วนขยาย GNU บางตัวเพื่อลดขนาดรหัส น้ำหนักเทียบเท่าเทียบเท่า POSIX ที่ 80 ไบต์:

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

เพื่อให้เวลาในการรันสมเหตุสมผลเราตัดค่าศูนย์ต่อท้าย ( while(!x%b)x/=b) และตัดให้เป็นkตัวเลขสุดท้าย( x%=b^k) ในขณะที่เราคำนวณแฟคทอเรียลfor(x=1;n;)x*=n-- )

โปรแกรมทดสอบ:

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

รันไทม์ของชุดทดสอบเต็มประมาณ 4 approx วินาทีบนเวิร์กสเตชันวินเทจปี 2549 ของฉัน


นี่เป็นรายการแรกของฉันbc(กอล์ฟหรือไม่) ดังนั้นเคล็ดลับใด ๆ ยินดีต้อนรับโดยเฉพาะอย่างยิ่ง ...
Toby Speight

0

PHP, 80 ไบต์

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

ใช้เป็น f(359221,2,40)กรณีทดสอบครั้งสุดท้าย ทำงานได้อย่างราบรื่นสำหรับทุกกรณีทดสอบ

ลองที่นี่!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.