N 제수가있는 가장 작은 수를 지정하십시오


17

함수는 자연수를 취하고 자신을 포함하여 정확히 그 양의 제수를 가진 가장 작은 자연수를 반환합니다.

예 :

f(1) =  1 [1]
f(2) =  2 [1, 2]
f(3) =  4 [1, 2, 4]
f(4) =  6 [1, 2, 3, 6]
f(5) = 16 [1, 2, 4, 8, 16]
f(6) = 12 [1, 2, 3, 4, 6, 12]
 ...

이 함수는 제수 목록을 반환 할 필요가 없으며 예제를위한 것입니다.


2
이 코드 골프 또는 코드 도전입니까?
— marinus

코드 태그를 잊어 버렸습니다.
— SteeveDroz

답변:


6

APL, 25 24 23 자

f←{({+/⍵=⍵∧⍳⍵}¨⍳2*⍵)⍳⍵}

f숫자를 계산하는 데 사용할 수 있는 함수 를 정의합니다 .

> f 13
4096

> f 14
192

이 솔루션은 LCM (n, x) == n iff x가 n을 나누는 사실을 이용합니다 . 따라서 블록은 {+/⍵=⍵∧⍳⍵}단순히 제수의 수를 계산합니다. 이 함수는 1 에서 2 ^ d 까지의 모든 숫자에 적용됩니다 ¨⍳2*⍵. 그런 다음 결과 목록 에서 원하는 함수 f (d) 인 d 자체 ( ⍳⍵) 를 검색합니다 .


축하합니다! 23 자 ... 와우!
— SteeveDroz

19 :{⍵⍳⍨(+/⊢=⊢∧⍳)¨⍳2*⍵}
— Adám

나는 당신이 정의 할 필요가 없다고 생각합니다 f.
— Zacharý

5

GolfScript, 29 28 자

{.{\.,{)1$\%},,-=}+2@?,?}:f;

편집 : Peter Taylor 덕분에 검색을 <2 ^ n으로 제한하면 단일 문자를 저장할 수 있습니다 .

이전 버전:

{.{\)..,{)1$\%},,-@=!}+do}:f;

GolfScript에서 온라인으로 실행하십시오 .

예 :

13 f p  # => 4096
14 f p  # => 192
15 f p  # => 144

이 코드에는 기본적으로 세 개의 블록이 포함되어 있으며 다음 줄에 자세히 설명되어 있습니다.

# Calculate numbers of divisors
#         .,{)1$\%},,-    
# Input stack: n
# After application: D(n)

.,          # push array [0 .. n-1] to stack
{           # filter array by function
  )         #   take array element and increase by one
  1$\%      #   test division of n ($1) by this value
},          # -> List of numbers x where n is NOT divisible by x+1
,           # count these numbers. Stack now is n xd(n)
-           # subtracting from n yields the result



# Test if number of divisors D(n) is equal to d
#         {\D=}+   , for D see above
# Input stack: n d
# After application: D(n)==d

{
  \         # swap stack -> d n
  D         # calculate D(n) -> d D(n)
  =         # compare
}+          # consumes d from stack and prepends it to code block         



# Search for the first number which D(n) is equal to d
#         .T2@?,?    , for T see above
# Input stack: d
# After application: f(d)

.           # duplicate -> d d
T           # push code block (!) for T(n,d) -> d T(n,d)
2@?         # swap and calculate 2^d -> T(n,d) 2^d
,           # make array -> T(n,d) [0 .. 2^d-1]
?           # search first element in array where T(n,d) is true -> f(d)

입력을 위해 무한 루프로 들어가는 것 같습니다 1.
— 피터 테일러

내 최선의 해결책은 지금까지 별도의 답변이 아닌 의견이 될만한 정도까지 귀하의 것에서 상당히 많이 빌립니다.
— 피터 테일러

4

파이썬 : 64

Bakuriu의 솔루션을 수정하고 grc의 제안과 plannapus의 R 솔루션의 트릭을 통합하면 다음과 같은 이점을 얻을 수 있습니다.

f=lambda n,k=1:n-sum(k%i<1for i in range(1,k+1))and f(n,k+1)or k

4

파이썬 : 66

f=lambda n,k=1:n==sum(k%i<1for i in range(1,k+1))and k or f(n,k+1)

위의 내용은 RuntimeError: maximum recursion depth exceededCPython에서 작은 입력으로 a를 발생시키고 한계를 큰 수로 설정하면 문제가 발생할 수 있습니다. 꼬리 재귀를 최적화하는 파이썬 구현에서는 정상적으로 작동합니다.

이러한 제한이 없어야하는보다 자세한 버전은 다음 79 바이트 솔루션입니다.

def f(n,k=1):
    while 1:
        if sum(k%i<1for i in range(1,k+1))==n:return k
        k+=1

11, 13, 17, 19 등의 재귀 한계에 도달했습니다.
— Steven Rumbalski

@StevenRumbalski 아무도 프로그램이 임의의 정수로 작동해야한다고 언급하지 않았습니다. 불행히도 숫자는 작은 입력으로도 매우 빠르게 자랍니다.
— Bakuriu

다음 if else과 함께 and or및 다음 ==1을 사용하여 일부 문자를 저장할 수 있습니다 <1.f=lambda n,k=1:n==sum(k%i<1for i in range(1,k+1))and k or f(n,k+1)
— grc

66이 약간 악하다고 생각하기 때문에 사용하면 2자를 절약 할 수 있습니다.sum(k%-~i<1for i in range(k))
— Volatility

f=lambda n,k=1:n==sum(k%-~i<1for i in range(k))or-~f(n,k+1)7 바이트를 절약합니다.
— Dennis

4

매스 매 티카 38 36

(For[i=1,DivisorSum[++i,1&]!=#,];i)&

용법:

(For[i=1,DivisorSum[++i,1&]!=#,];i)&@200

결과:

498960

편집하다

몇 가지 설명 :

DivisorSum [n, form]은 n을 나누는 모든 i에 대한 form [i]의 합을 나타냅니다.

마찬가지로 form[i]나는 기능을 사용하고 1 &반환 항상 것을, 1그래서 효과적으로 간결한 방식의 약수의 합을 계산.


코드 골프 태그가 없으므로 긴 대답을했습니다! 죄송합니다
— DavidC

@DavidCarraher 방금 추측했습니다 :)
— Dr. belisarius

나는 어떤 DivisorSum수익 (제수의 합)을 알고 있다고 생각 했지만 그것이 질문에 대답하는 데 어떻게 도움이되는지는 알지 못합니다. 작동 방식을 설명해 주시겠습니까? BTW, n = 200에 대한 타이밍 데이터를 포함해야한다고 생각합니다. 확인해야 할 모든 숫자가 주어지면 기능이 매우 빠릅니다.
— DavidC

@DavidCarraher 편집을보십시오. 다시 : 타이밍-내 기계가 너무 느리다 :(
— Dr. belisarius

Mathematica에는 팩토링을 단축하기위한보다 정교한 접근 방식을위한 충분한 내장 기능이 없습니까? 이 경우 실망합니다.
— 피터 테일러

3

J, 33 자

상당히 빠르며, 모든 작은 수를 거치고 인수 분해를 기반으로 제수를 계산합니다.

   f=.>:@]^:([~:[:*/[:>:_&q:@])^:_&1

   f 19
262144

3

하스켈 54

빠르고 더러운 (읽기 쉽고 까다로운) 솔루션 :

f k=head[x|x<-[k..],length[y|y<-[1..x],mod x y==0]==k]

편집은 대답을 더 짧게 만들지 않았지만 아마도 더 빠른 속임수입니다. 또한 나는 항상 코드 길이에 줄 바꿈을 포함 시켰습니다.
— shiona

당신이 잘못 계산했다고 생각했습니다. 편집의 주요 목적은 개수를 업데이트하는 것이 었습니다. 코드 자체의 변경은 미미했습니다. J의 항목 (예 : 33 자)과 같은 다른 항목도 후행 줄 바꿈을 포함하지 않는다고 생각합니다.
— Will Ness

2

K, 42

스택을 매우 쉽게 분해하는 비효율적 인 재귀 솔루션

{{$[x=+/a=_a:y%!1+y;y;.z.s[x;1+y]]}[x;0]} 

.

k){{$[x=+/a=_a:y%!1+y;y;.z.s[x;1+y]]}[x;0]}14
192
k){{$[x=+/a=_a:y%!1+y;y;.z.s[x;1+y]]}[x;0]}13
'stack


2

APL (25)

{⍵{⍺=+/0=⍵|⍨⍳⍵:⍵⋄⍺∇⍵+1}1}

사기꾼! echo -n '{⍵ {⍺ = + / 0 = ⍵ | ⍨⍳⍵ : ⍵⋄⍺∇⍵ + 1} 1}'| 화장실 -c는 나에게 47을 준다! 그러나 실제로 APL에 대한 간단한 자습서에 대한 링크를 제공해 주시겠습니까? 나는 그것을 시도하고 몇 가지 기사를 읽었지만 결국 나는 항상 "왜 그들이 이것을하고 있습니까 :(?")를 묻고 싶습니다. 그것은 실제 장점이있다.
— XzKto

이것은 내가 사용하는 Dyalog APL 용이며 동일한 사이트에서 무료로 Windows 버전을 다운로드 할 수 있습니다. dyalog.com/MasteringDyalogAPL/MasteringDyalogAPL.pdf
— marinus

와우, 나는 이것을 정말로 이해할 수있는 것처럼 보입니다. 링크 주셔서 감사합니다! 유일한 단점은 그들이 매우 이상한 라이센스 정책을 가지고 있지만 어쩌면 나는 단지 영어를 향상시킬 필요가 있다는 것입니다)
— XzKto

2

R-47 자

f=function(N){n=1;while(N-sum(!n%%1:n))n=n+1;n}

!n%%1:n부울 벡터를 제공합니다. 1에서 n까지의 정수가 n의 제수이면 TRUE이고 그렇지 않으면 FALSE입니다. sum(!n%%1:n)FALSE이면 부울을 0으로 강제 변환하고 TRUE이면 1을 강제로 합산합니다. 따라서 N-sum(...)제수의 수가 N이면 0이됩니다. 0은 FALSE로 해석되어 while중지됩니다.

용법:

f(6)
[1] 12
f(13)
[1] 4096

2

자바 스크립트 70

function f(N){for(j=i=m=1;m-N||j-i;j>i?i+=m=j=1:m+=!(i%++j));return i}

실제로 46 개의 의미있는 캐릭터 만 있습니다 :

for(j=i=m=1;m-N||j-i;j>i?i+=m=j=1:m+=!(i%++j))

문법이 짧은 언어를 배워야 할 것입니다 :)


N=>eval("for(j=i=m=1;m-N||j-i;j>i?i+=m=j=1:m+=!(i%++j));i")
— TuxCrafting

2

하스켈 : 49 자

초기 Haskell 솔루션의 개선으로 볼 수 있지만 자체적으로 생각했습니다 (경고 : 매우 느립니다).

f n=until(\i->n==sum[1|j<-[1..i],rem i j<1])(+1)1

예를 들어 f (p) = 2 ^ (p-1)입니다. 여기서 p는 소수입니다.


짧고 반대로 계산하는 효율적인 방법은 n소수 (소수점)를 반복하고, 내림차순으로 정렬하고, 각각을 감소시키고, 소수의 소수로 압축 한 다음 곱을 계산하는 것입니다.p^(factor-1)
— Peter Taylor

2
@PeterTaylor 필요하지 않습니다. n = 16 = 2 * 2 * 2 * 2의 경우 솔루션은 2 ^ 1 * 3 ^ 1 * 5 ^ 1 * 7 ^ 1 = 210이 아니라 2 ^ 3 * 3 ^ 1 * 5 ^ 1 = 120입니다.
— randomra

2

C : 66 64 자

거의 짧은 해결책 :

i;f(n){while(n-g(++i));return i;}g(j){return j?!(i%j)+g(j-1):0;}

그리고 내 이전 솔루션은 되풀이되지 않습니다.

i;j;k;f(n){while(k-n&&++i)for(k=0,j=1;j<=i;k+=!(i%j++));return i;}

훨씬 더 짧은 솔루션이 존재해야합니다.


2

하스켈 (120C), 매우 효율적인 방법

1<>p=[]
x<>p|mod x p>0=x<>(p+1)|1<2=(div x p<>p)++[p]
f k=product[p^(c-1)|(p,c)<-zip[r|r<-[2..k],2>length(r<>2)](k<>2)]

테스트 코드 :

main=do putStrLn$show$ f (100000::Integer)

이 방법은 매우 빠릅니다. 아이디어는 먼저 k=p1*p2*...*pmp1 <= p2 <= ... <= pm 의 주요 요소를 찾는 것 입니다. 그럼 대답은n = 2^(pm-1) * 3^(p(m-1)-1) * 5^(p(m-2)-1) ... 입니다.

예를 들어 k = 18을 인수 분해하면 18 = 2 * 3 * 3이됩니다. 처음 3 개의 소수는 2, 3, 5입니다. 따라서 답 n = 2 ^ (3-1) * 3 ^ (3-1) * 5 ^ (2-1) = 4 * 9 * 5 = 180

아래에서 테스트 할 수 있습니다 ghci.

*Main> f 18
180
*Main> f 10000000
1740652905587144828469399739530000
*Main> f 1000000000
1302303070391975081724526582139502123033432810000
*Main> f 100000000000
25958180173643524088357042948368704203923121762667635047013610000
*Main> f 10000000000000
6558313786906640112489895663139340360110815128467528032775795115280724604138270000
*Main> f 1000000000000000
7348810968806203597063900192838925279090695601493714327649576583670128003853133061160889908724790000
*Main> f 100000000000000000
71188706857499485011467278407770542735616855123676504522039680180114830719677927305683781590828722891087523475746870000
*Main> f 10000000000000000000
2798178979166951451842528148175504903754628434958803670791683781551387366333345375422961774196997331643554372758635346791935929536819490000
*Main> f 10000000000000000000000
6628041919424064609742258499702994184911680129293140595567200404379028498804621325505764043845346230598649786731543414049417584746693323667614171464476224652223383190000

골프 점수는 좋지 않지만, 당신이 선택한 길에 +1입니다!
— SteeveDroz

8 = 2 * 2 * 2의 경우이 알고리즘은 숫자 2 * 3 * 5 = 30을 제공합니다. 그러나 가장 좋은 해결책은 2 ^ 3 * 3 = 24입니다 (8 = 2 * 4의 경우)
— AMK

지정된 수의 제수에 작은 소수의 높은 거듭 제곱이 포함되어 있으면 솔루션이 올바르지 않습니다. 따라서 10의 거듭 제곱에 대한 대부분의 솔루션은 잘못되었습니다.
— AMK

@AMK 네, 그렇습니다. 지적 해 주셔서 감사합니다.
— Ray

2

Brachylog , 2 바이트

fl

온라인으로 사용해보십시오!

출력 변수를 통해 입력을 받고 입력 변수를 통해 출력합니다.

f     The list of factors of
      the input variable
 l    has length equal to
      the output variable.

입력 변수를 통해 입력하고 출력 변수를 통해 출력하는이 동일한 술어 는 대신이 문제를 해결합니다 .


언어가 질문보다 최신이기 때문에 훌륭하지만 그 퍼즐에 적합하지 않습니다.
— SteeveDroz

내가 처음 여기에 들었을 때 가장 먼저 들었던 것 중 하나는 질문보다 새로운 언어는 더 이상 비경쟁이 아니며 메타로 백업 된다는 것입니다
— String

오, 그럼 신경 쓰지 마 분명히, 규칙은 진화하도록 만들어졌으며이 사이트의 주된 목적은 자신을 향상시키고 즐겁게하는 것임을 명심해야합니다. 답변이 접수되었습니다!
— SteeveDroz

1

C, 69 자

가장 짧은 것이 아니라 첫 번째 C 답변 :

f(n,s){return--s?f(n,s)+!(n%s):1;}
x;
g(d){return++x,f(x,x)-d&&g(d),x;}

f(n,s)n범위의 제수를 계산 합니다 1..s. 의 f(n,n)제수를 계산합니다 n.
g(d)까지 반복 (반복)하고 f(x,x)==dx를 반환합니다.


1

매스 매 티카 38 36

(For[k=1,DivisorSigma[0, k]!= #,k++]; k)&

용법

   (For[k = 1, DivisorSigma[0, k] != #, k++]; k) &[7]

(* 64 *)

첫 번째 항목 ( code-golf태그가 질문에 추가 되기 전 )

직접적인 문제는, 그 주어진 Divisors[n]반환에게의 제수 n(포함 n) 및 Length[Divisors[n]]반환 등의 약수의 개수를. **

smallestNumber[nDivisors_] :=
   Module[{k = 1},
   While[Length[Divisors[k]] != nDivisors, k++];k]

예

Table[{i, nDivisors[i]}, {i, 1, 20}] // Grid

Mathematica 그래픽


데이비드, 짧고 빠른보다는 Length@Divisors@n이다 DivisorSigma[0,n].
— Mr.Wizard

감사. 의 사용에 대해서는 몰랐습니다 DivisorSigma.
— DavidC


1

젤리 , 6 바이트 (비경쟁)

2*RÆdi

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인 .

작동 원리

2*RÆdi  Main link. Argument: n (integer)

2*      Compute 2**n.
  R     Range; yield [1, ..., 2**n]. Note that 2**(n-1) has n divisors, so this
        range contains the number we are searching for.
   Æd   Divisor count; compute the number of divisors of each integer in the range.
     i  Index; return the first (1-based) index of n.

왜합니까 2*? 그 이후의 모든 숫자가 n보다 더 많은 제수를 가지고 있습니까?
— Outgolfer Erik

2
아니; 예를 들어, 모든 소수에는 정확히 두 개의 제수가 있습니다. 그러나 우리는 n 제수로 가장 작은 양의 정수를 찾고 있습니다. 그 범위에 속하기 때문에 가장 작은 것도 마찬가지입니다. 2**(n-1)
— Dennis

0

C ++, 87 자

int a(int d){int k=0,r,i;for(;r!=d;k++)for(i=2,r=1;i<=k;i++)if(!(k%i))r++;return k-1;}

0

Python2, 95 자, 비 재귀

다른 파이썬 솔루션보다 조금 더 장황하지만 재귀 적이 지 않으므로 cpython의 재귀 한계에 도달하지 않습니다.

from itertools import*
f=lambda n:next(i for i in count()if sum(1>i%(j+1)for j in range(i))==n)

0

펄 6 , 39 자

{my \a=$=0;a++while $_-[+] a X%%1..a;a}

사용법 예 :

say (0..10).map: {my \a=$=0;a++while $_-[+] a X%%1..a;a}
(0 1 2 4 6 16 12 64 24 36 48)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.