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.