기본에서 계승의 마지막 0이 아닌 숫자


22

3 개의 양의 정수 n b k를 입력 출력으로 제공하거나 k의 기본 b표현 에서 후행 0 이전의 마지막 숫자를 리턴 하는 프로그램 또는 함수를 작성해야합니다 n!.

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

입력

  • n b k여기서 3 개의 양의 정수 2 <= b <= 10.
  • 입력 정수의 순서는 임의로 선택할 수 있습니다.

산출

  • 정수 또는 정수 목록으로 리턴되거나 출력되는 자릿수 목록.
  • 선행 0은 선택 사항입니다.
  • 귀하의 솔루션은 내 컴퓨터 에서 1 분 이내에 예제 테스트 사례를 해결해야 합니다 (닫기 사례 만 테스트합니다. 평균 이하의 PC가 있습니다).

제출의 정확성을 확인하기 위해 새로운 테스트가 추가되었습니다. (1 분 미만의 런타임 규칙에는 속하지 않습니다.)

입력 => 출력 (앞의 0을 생략하여 선택)

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 분 안에 특정 정보를 모르면 목표로하기가 약간 어렵습니다.
Dennis

1
겠습니까의 7 5 3출력 "013"또는 "13"?
Claudiu

1
@Claudiu 7 10 4는 내가 말할 테스트 사례를 기반으로13
Maltysen

2
@Claudiu "제로 0은 선택 사항입니다." 두 버전이 모두 맞습니다.
randomra

1
또는에 대해 양의 정수를 허용해야 합니까? 아니면 언어의 정수 유형의 범위로 제한 할 수 있습니까? nk
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 , bk를 묻는 순서대로), 세 문자를로 바꿉니다 .


내가 던진 모든 테스트 사례는 내 컴퓨터에서 약 11 마이크로 초로 계산되었습니다 (M540).
Adám

7

매스 매 티카, 57 48 바이트

@ 2012rcampion 덕분에 9 바이트가 절약되었습니다.

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

나는 실제로 수학을 사용한 적이 없지만 인수 순서 b를 바꿔서 2 바이트를 먼저 절약 할 수는 없었 습니까?
FryAmTheEggman

@FryAmTheEggman 저는 골프 커뮤니티를 처음 사용하는데 인수 순서 "코셔"를 바꾸고 있습니까?
2012rcampion

1
당신은 실제로 47에 도착할 수있다 : IntegerString[#!#2^-#!~IntegerExponent~#2,##2]&(이것과 당신의 원본은 꽤 빠르다)
2012rcampion

어커는 "입력 정수의 순서는 임의로 선택할 수있다"고 썼다. 입력에서,
따라서이

@Fry Wow, 내가 충분히 읽지 않은 것 같습니다. 그러나 SlotSequence내 의견에 사용한 트릭은 현재 주문에서만 작동하므로 더 이상 저장할 수 없습니다.
2012rcampion

7

파이썬 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 초 정도로 빠릅니다. 그리고 계승이 없다 (Mathematica!).


[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)

각 테스트 사례는 내 컴퓨터에서 1 초 이내에 실행됩니다.


2

Mathematica-48 바이트

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

언 골프 드 :

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)마지막 두 테스트 사례가 1 분을 훨씬 초과합니다.


2

Bash / coreutils / dc, 60 바이트

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

내 대답dc스크립트를 사용하여 후행 0을 자르고 마지막 자릿수 를 선택하고 base 에서 출력 하는 계승을 찾습니다 .$2sedtail$3


40 비트 base-2 테스트 케이스에서는 속도가 매우 느리다는 것을 인정해야합니다. rev역 추적을 줄이기 위해 sed의 작업을 완화하려고 시도했지만 dcCPU를 사용하고 있습니다.
Toby Speight

2

하스켈 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]

f 359221 2 40내 4 살짜리 노트북에서 약 8 초가 걸립니다 .

작동 방식 : 곱셈 ( *)을 목록으로 접습니다 [1..n]. 모든 중간 결과를 b자릿수 목록 으로 기본 (최하위 우선)으로 k변환 하고 앞에 오는 0을 제거한 다음 첫 번째 자릿수 를 취하고 기본 10으로 다시 변환하십시오. 마지막으로 b다시 밑으로 변환 하지만 가장 중요한 숫자가 먼저 사용됩니다.


당신은 내 마음에 생각, 내가 matlab을 사용하여 그것을 해석했다, 무슨 우연의 일치 : D
Abr001am

1

파이썬 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

자바, 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 40테스트 케이스 에서 1 / 3 초 미만의 평균 입니다. 명령 행 인수를 통해 입력을받습니다.


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

실행 시간을 합리적으로 유지하기 위해 계승 ( )을 계산할 때 후행 0 ( 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

전체 2006 년 빈티지 워크 스테이션에서 전체 테스트 스위트의 런타임은 약 4¼ 초입니다.


이것은 나의 첫 번째 bc프로그램 (골프
유무

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.