Chữ số khác không cuối cùng của một nhân tố trong cơ sở


22

Bạn nên viết một chương trình hoặc hàm có ba số nguyên dương n b klàm đầu ra đầu vào hoặc trả về các kchữ số cuối trước các số 0 ở cuối trong bbiểu diễn cơ sở của n!.

Thí dụ

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

Đầu vào

  • 3 số nguyên dương n b kở đâu 2 <= b <= 10.
  • Thứ tự của các số nguyên đầu vào có thể được chọn tùy ý.

Đầu ra

  • Một danh sách các chữ số được trả về hoặc xuất ra dưới dạng danh sách số nguyên hoặc số nguyên.
  • Số không hàng đầu là tùy chọn.
  • Giải pháp của bạn phải giải quyết bất kỳ trường hợp kiểm tra ví dụ nào dưới một phút trên máy tính của tôi (tôi sẽ chỉ kiểm tra các trường hợp gần. Tôi có một PC dưới mức trung bình.).

Ví dụ

Các xét nghiệm mới được thêm vào để kiểm tra tính chính xác của bài nộp. (Chúng không phải là một phần của quy tắc thời gian chạy dưới 1 phút.)

Đầu vào => Đầu ra (với lựa chọn bỏ qua các số 0 đứng đầu)

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

Đây là môn đánh gôn, vì vậy bài dự thi ngắn nhất sẽ thắng.


1
dưới một phút trên máy tính của tôi là một chút khó khăn để nhắm đến nếu chúng ta không biết bất kỳ chi tiết cụ thể.
Dennis

1
Sẽ 7 5 3xuất "013" hay "13"?
Claudiu

1
@Claudiu dựa trên 7 10 4trường hợp thử nghiệm tôi sẽ nói13
Maltysen

2
@Claudiu "Số không hàng đầu là tùy chọn." vì vậy cả hai phiên bản đều đúng
Randomra

1
Chúng ta phải chấp nhận bất kỳ số nguyên dương cho nhay k? Hoặc chúng ta có thể giới hạn chúng trong phạm vi loại số nguyên của ngôn ngữ không?
Toby Speight

Câu trả lời:


1

APL Dyalog , 23 byte

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

Chương trình này hoạt động miễn là giai thừa không vượt quá giới hạn đại diện nội bộ. Trong Dyalog APL, giới hạn có thể được nâng lên bằng ⎕FR←1287.

Giả sử các biến n, b và k đã được đặt (ví dụ n b k←7 5 4), nhưng nếu bạn muốn nhắc cho n , bk (theo thứ tự đó) thì hãy thay thế ba ký tự bằng .


Mỗi trường hợp thử nghiệm tôi ném vào nó được tính toán trong khoảng 11 micro giây trên máy của tôi (M540).
Adám

7

Toán học, 57 48 byte

Đã lưu 9 byte nhờ @ 2012rcampion.

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

Tôi chưa bao giờ thực sự sử dụng mathicala, nhưng bạn không thể trao đổi thứ tự của các đối số để tạo bđầu tiên để tiết kiệm 2 byte?
FryAmTheEggman

@FryAmTheEggman Tôi mới tham gia vào cộng đồng chơi gôn, đang tráo đổi thứ tự tranh luận "kosher"?
2012rcampion

1
Bạn thực sự có thể đến 47: IntegerString[#!#2^-#!~IntegerExponent~#2,##2]&(cả cái này và bản gốc của bạn đều khá nhanh)
2012rcampion

Người hỏi viết: "Thứ tự của các số nguyên đầu vào có thể được chọn tùy ý." dưới đầu vào, vì vậy trong trường hợp này chắc chắn là ổn
FryAmTheEggman

@Fry Wow, có vẻ như tôi đã không đọc kỹ. Tuy nhiên, SlotSequencemẹo tôi sử dụng trong nhận xét của mình chỉ hoạt động với đơn hàng hiện tại, vì vậy bạn không thể lưu thêm nữa.
2012rcampion

7

Python, 198 192 181 ký tự

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

Nó đủ nhanh, ~ 23 giây trong ví dụ lớn nhất. Và không có yếu tố tích hợp nào (Tôi đang nhìn bạn, Mathicala!).


[2,3,2,5,3,7,2,3,5][b-2]có thể int('232537235'[b-2])để lưu 3 byte. [1,1,2,1,1,1,3,2,1][b-2]tương tự
ngẫu nhiên

Đối với cái sau, một bảng tra cứu 111973>>2*(b-2)&3thậm chí còn ngắn hơn. Đó là cùng một số byte cho trước đây ( 90946202>>3*(b-2)&7).
Sp3000

nvm có vẻ như bạn đã đúng về điều có chữ số cao hơn
Sp3000

Tôi tin rằng bạn có thể lưu một vài byte bằng cách biến nó thành một chương trình chứ không phải là một hàm.
FryAmTheEggman

6

Bình thường, 26 35 byte

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

Đây là hàm gồm 3 đối số, số, cơ sở, số chữ số.

Trình diễn.

Trường hợp thử nghiệm chậm nhất, trường hợp cuối cùng, mất 15 giây trên máy của tôi.


@ Sp3000 Tôi đã thêm một bản sửa lỗi mà tôi nghĩ là đủ.
isaacg

2

PARI / GP, 43 byte

Tốc độ giao dịch cho không gian mang lại thuật toán đơn giản này:

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

Mỗi trường hợp thử nghiệm chạy trong chưa đầy một giây trên máy của tôi.


2

Toán học - 48 byte

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

Ung dung:

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

Thí dụ:

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

Đối với các trường hợp lớn nhất, hệ số giới hạn không tạo ra các chữ số:

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

Sự khớp mẫu dường như là nguyên nhân O(n^2), khiến hai trường hợp thử nghiệm cuối cùng vượt xa mốc một phút.


2

Bash / coreutils / dc, 60 byte

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

Sử dụng dctập lệnh từ câu trả lời của tôi để Tìm nhân tố , xuất ra trong cơ sở $2, sedđể cắt các số 0 ở cuối và tailđể chọn các $3chữ số cuối cùng .


Tôi phải thừa nhận rằng nó cực kỳ chậm với testcase cơ sở 2 bit. Tôi đã cố gắng giảm bớt công việc của sed bằng cách revgiảm việc quay lại, nhưng đó dclà ăn 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]

Cách sử dụng: f 158596 8 20->[3,7,2,1,2,4,7,6,7,0,0,4,4,2,2,5,4,6,1,4]

Mất khoảng 8 giây cho f 359221 2 40máy tính xách tay 4 tuổi của tôi.

Cách thức hoạt động: gấp phép nhân ( *) vào danh sách [1..n]. Chuyển đổi mọi kết quả trung gian thành cơ sở bdưới dạng danh sách các chữ số (đầu tiên có ý nghĩa nhỏ nhất), tước các số 0 đứng đầu, sau đó lấy các kchữ số đầu tiên và chuyển đổi sang cơ sở 10 một lần nữa. Cuối cùng chuyển đổi sang cơ sở bmột lần nữa, nhưng với chữ số quan trọng nhất đầu tiên.


bạn đã có ý tưởng trong đầu tôi, rằng tôi đã diễn giải nó bằng matlab, thật là một sự trùng hợp: 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]):])

Tôi không chắc chắn tất cả các trường hợp thử nghiệm sẽ chạy đủ nhanh - những trường hợp lớn hơn rất chậm (vì nó đang lặp qua số).

Hãy thử trực tuyến tại đây (nhưng hãy cẩn thận).


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

Trên máy tính của tôi, giá trị này trung bình dưới một phần ba giây trên 359221 2 40testcase. Đưa đầu vào thông qua các đối số dòng lệnh.


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}

Điều này sử dụng một số phần mở rộng GNU để giảm kích thước mã; tương đương POSIX có trọng lượng 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)}

Để giữ thời gian chạy hợp lý, chúng tôi cắt các số 0 ( while(!x%b)x/=b) và cắt thành các kchữ số cuối cùng ( x%=b^k) khi chúng tôi tính giai thừa ( for(x=1;n;)x*=n--).

Chương trình kiểm tra:

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

Thời gian chạy của bộ kiểm tra đầy đủ là khoảng 4¼ giây trên máy trạm 2006-vintage của tôi.


Đây là bcchương trình đầu tiên của tôi (chơi gôn hay không), vì vậy mọi lời khuyên đều được đặc biệt hoan nghênh ...
Toby Speight

0

PHP, 80 byte

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

Được sử dụng như f(359221,2,40)cho trường hợp thử nghiệm cuối cùng. Chạy khá trơn tru cho tất cả các trường hợp thử nghiệm.

Thử ở đây !

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.