Cho số nhỏ nhất có N ước số


17

Hàm của bạn lấy một số tự nhiên và trả về số tự nhiên nhỏ nhất có chính xác số lượng ước đó, bao gồm cả chính nó.

Ví dụ:

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]
 ...

Hàm không phải trả về danh sách các ước, chúng chỉ ở đây để lấy ví dụ.


2
Đây là mã golf hay thử thách mã?
bến tàu

Rất tiếc, quên thẻ đó, code-golf!
SteeveDroz

Câu trả lời:


6

APL, 25 24 23 ký tự

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

Xác định một hàm fmà sau đó có thể được sử dụng để tính các số:

> f 13
4096

> f 14
192

Giải pháp sử dụng thực tế là LCM (n, x) == n iff x chia n . Do đó, khối {+/⍵=⍵∧⍳⍵}chỉ đơn giản là tính toán số lượng ước. Hàm này được áp dụng cho tất cả các số từ 1 đến 2 ^ d ¨⍳2*⍵ . Sau đó, danh sách kết quả được tìm kiếm cho chính d ( ⍳⍵) là hàm mong muốn f (d) .


Chúc mừng! 23 ký tự ... wow!
SteeveDroz

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

Tôi không nghĩ bạn cần xác định f.
Zacharý

5

GolfScript, 29 28 ký tự

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

Chỉnh sửa: Một char duy nhất có thể được lưu nếu chúng tôi giới hạn tìm kiếm ở <2 ^ n, nhờ Peter Taylor cho ý tưởng này.

Phiên bản trước:

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

Một nỗ lực trong GolfScript, chạy trực tuyến .

Ví dụ:

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

Mã này về cơ bản chứa ba khối được giải thích chi tiết trong các dòng sau.

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

Có vẻ đi vào một vòng lặp vô hạn cho đầu vào 1.
Peter Taylor

Giải pháp tốt nhất của tôi cho đến nay vay khá nhiều từ bạn, đến mức tôi nghĩ rằng nó xứng đáng là một nhận xét hơn là một câu trả lời riêng biệt.
Peter Taylor

4

Con trăn: 64

Sửa đổi giải pháp của Bakuriu và kết hợp đề xuất của grc cũng như mẹo từ giải pháp R của plannapus, chúng tôi nhận được:

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

4

Con trăn: 66

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

Ở trên sẽ đưa ra một RuntimeError: maximum recursion depth exceededđầu vào nhỏ trong CPython, và thậm chí đặt giới hạn cho một số lượng lớn, nó có thể sẽ đưa ra một số vấn đề. Trên các triển khai python tối ưu hóa đệ quy đuôi, nó sẽ hoạt động tốt.

Một phiên bản dài hơn, không nên có những hạn chế như vậy, là giải pháp 79 byte sau đây :

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

Tôi đang đạt giới hạn đệ quy vào ngày 11, 13, 17, 19 và những người khác.
Steven Rumbalski

@StevenRumbalski Không ai đề cập rằng chương trình nên hoạt động với các số nguyên tùy ý. Thật không may, số lượng tăng lên khá nhanh ngay cả với đầu vào nhỏ.
Bakuriu

Bạn có thể lưu một số ký tự bằng cách sử dụng thay thế if elsebằng and or==1bằng <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

Bởi vì tôi thấy 66 hơi quá ác, bạn có thể lưu 2 ký tự nếu bạn sử dụngsum(k%-~i<1for i in range(k))
Biến động

f=lambda n,k=1:n==sum(k%-~i<1for i in range(k))or-~f(n,k+1)tiết kiệm 7 byte.
Dennis

4

Toán học 38 36

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

Sử dụng:

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

Kết quả:

498960

Biên tập

Một số giải thích:

DivisorSum [n, mẫu] đại diện cho tổng mẫu [i] cho tất cả i chia n.

Khi form[i]tôi đang sử dụng hàm 1 &, nó luôn trả về 1, vì vậy tính toán hiệu quả tổng của các ước số một cách ngắn gọn.


Không có thẻ golf-code nên tôi đã trả lời dài! Rất tiếc
DavidC

@DavidCarraher Tôi chỉ đoán :)
Tiến sĩ belisarius

Tôi nghĩ rằng tôi biết những gì DivisorSumtrả về (tổng của các ước số) nhưng tôi không thấy đó là công cụ để trả lời câu hỏi được đặt ra. Bạn sẽ giải thích làm thế nào nó hoạt động. BTW, tôi nghĩ bạn nên bao gồm dữ liệu thời gian cho n = 200; chức năng này rất nhanh, với tất cả các con số mà nó phải kiểm tra.
DavidC

@DavidCarraher Xem chỉnh sửa. Re: timings - Máy của tôi hoạt động rất chậm :(
Tiến sĩ belisarius

Mathicala không có đủ tích hợp cho cách tiếp cận tinh vi hơn xung quanh bao thanh toán ngắn hơn? Nếu đó là trường hợp, tôi thất vọng.
Peter Taylor

3

J, 33 ký tự

Khá nhanh chóng, đi qua tất cả các số nhỏ hơn và tính toán số lượng ước tính dựa trên hệ số.

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

   f 19
262144

3

Haskell 54

Giải pháp nhanh chóng và bẩn (rất dễ đọc và không khó khăn):

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

Bản chỉnh sửa không làm cho câu trả lời ngắn hơn, nhưng nó có thể giống như haskell hơn. Ngoài ra tôi đã luôn luôn bao gồm các dòng mới theo chiều dài mã của tôi, điều này có sai không?
shiona

Tôi nghĩ bạn đã nhầm lẫn; mục đích chính của việc chỉnh sửa là cập nhật số lượng. Sự thay đổi trong chính mã là nhỏ. Tôi nghĩ rằng các mục khác ở đây cũng không tính dòng mới, ví dụ như mục cho J (33 ký tự).
Will Ness

2

K, 42

Giải pháp đệ quy không hiệu quả làm nổ tung stack khá dễ dàng

{{$[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 33

F n            
i←0              
l:i←i+1          
→(n≠+/0=(⍳i)|i)/l
i 

Thí dụ:

F 6
12           

2

APL (25)

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

Gian lận! tiếng vang -n '{⍵ {⍺ = + / 0 = ⍵ | ⍨⍳⍵: ⍵⋄⍺∇⍵ + 1} 1}' | wc -c cho tôi 47! Nhưng thực sự, bạn có thể vui lòng cho tôi một liên kết đến một số hướng dẫn dễ dàng cho APL không? Tôi đã cố gắng google nó và đã đọc một vài bài báo, nhưng cuối cùng tôi vẫn luôn muốn hỏi "Tại sao họ làm điều này :(?". Tôi chưa bao giờ làm việc với bất kỳ ngôn ngữ cú pháp không phải ASCII nào và muốn tìm hiểu xem nó có bất kỳ lợi thế thực sự nào.
XzKto

Cái này dành cho Dyalog APL, đây là thứ tôi sử dụng, bạn có thể tải xuống phiên bản Windows miễn phí tại cùng một trang. dyalog.com/MasteringDyalogAPL/MasteringDyalogAPL.pdf
marinus

Wow, có vẻ như tôi thực sự có thể hiểu điều này. Cảm ơn vi đương link! Nhược điểm duy nhất là họ có một số chính sách cấp phép rất lạ nhưng có lẽ tôi chỉ cần cải thiện tiếng Anh của mình)
XzKto

2

R - 47 ký tự

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

!n%%1:nđưa ra một vectơ booleans: TRUE khi một số nguyên từ 1 đến n là ước của n và FALSE nếu không. sum(!n%%1:n)ép booleans thành 0 nếu FALSE và 1 nếu TRUE và tính tổng của chúng, vì vậy đó N-sum(...)là 0 khi số lượng ước là N. 0 sau đó được hiểu là FALSE bởiwhile sau đó dừng lại.

Sử dụng:

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

2

Javascript 70

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

Thực sự chỉ có 46 nhân vật có ý nghĩa:

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

Tôi có lẽ nên học một ngôn ngữ với cú pháp ngắn hơn :)


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

2

Haskell: 49 ký tự

Nó có thể được coi là một cải tiến của giải pháp Haskell trước đó, nhưng nó được hình thành theo đúng nghĩa của nó (cảnh báo: nó rất chậm):

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

Đây là một hàm khá thú vị, ví dụ lưu ý rằng f (p) = 2 ^ (p-1), trong đó p là số nguyên tố.


Cách tính hiệu quả, trái ngược với cách tính ngắn gọn sẽ là yếu tố nthành các số nguyên tố (có sự lặp lại), sắp xếp giảm dần, giảm dần từng cái, zip với một chuỗi các số nguyên tố vô hạn, và sau đó gấp sản phẩm củap^(factor-1)
Peter Taylor

2
@PeterTaylor Không cần thiết. Với n = 16 = 2 * 2 * 2 * 2 giải pháp là 2 ^ 3 * 3 ^ 1 * 5 ^ 1 = 120, không phải 2 ^ 1 * 3 ^ 1 * 5 ^ 1 * 7 ^ 1 = 210.
Randomra

2

C: 66 64 ký tự

Một giải pháp gần như ngắn:

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

Và giải pháp trước đây của tôi không tái diễn:

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

Các giải pháp ngắn hơn nhiều phải tồn tại.


2

Haskell (120C), một phương pháp rất hiệu quả

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

Mã kiểm tra:

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

Phương pháp này rất nhanh. Ý tưởng đầu tiên là tìm các thừa số nguyên tố của k=p1*p2*...*pm, trong đó p1 <= p2 <= ... <= pm. Sau đó, câu trả lời là n = 2^(pm-1) * 3^(p(m-1)-1) * 5^(p(m-2)-1) ....

Ví dụ: hệ số k = 18, ta được 18 = 2 * 3 * 3. 3 số nguyên tố đầu tiên là 2, 3, 5. Vì vậy, câu trả lời n = 2 ^ (3-1) * 3 ^ (3-1) * 5 ^ (2-1) = 4 * 9 * 5 = 180

Bạn có thể kiểm tra nó dưới 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

Đó là điểm golf kém, nhưng +1 cho con đường bạn đã đi!
SteeveDroz

Với 8 = 2 * 2 * 2 thuật toán này cho số 2 * 3 * 5 = 30. Nhưng giải pháp tốt nhất là 2 ^ 3 * 3 = 24 (cho 8 = 2 * 4)
AMK

Giải pháp không chính xác nếu số lượng ước được chỉ định chứa công suất lớn của số nguyên tố nhỏ. Vì vậy, rất có thể các giải pháp được liệt kê cho quyền hạn 10 là sai.
AMK

@AMK Vâng, bạn nói đúng. Cảm ơn đã chỉ ra rằng.
Ray

2

Brachylog , 2 byte

fl

Hãy thử trực tuyến!

Đưa đầu vào thông qua biến đầu ra và đầu ra thông qua biến đầu vào.

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

Chính xác vị từ này, lấy đầu vào thông qua biến đầu vào của nó và xuất ra thông qua biến đầu ra của nó, thay vào đó giải quyết thách thức này .


Đẹp, nhưng không đủ điều kiện cho câu đố đó vì ngôn ngữ gần đây hơn câu hỏi.
SteeveDroz

Khi tôi mới ở đây một trong những điều đầu tiên tôi được cho biết là ngôn ngữ mới hơn câu hỏi không noncompeting nữa, và điều này được hỗ trợ bởi meta: codegolf.meta.stackexchange.com/questions/12877/...
Không liên quan Chuỗi

Oh tốt, đừng bận tâm. Rõ ràng, các quy tắc được thực hiện để phát triển và chúng ta phải ghi nhớ rằng mục đích chính của trang web này là để cải thiện bản thân và vui chơi. Trả lời chấp nhận!
SteeveDroz

1

C, 69 ký tự

Không phải là ngắn nhất, nhưng câu trả lời C đầu tiên:

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)đếm các ước của ntrong phạm vi 1..s. Vì vậy, f(n,n)tính các ước của n.
g(d)các vòng lặp (bằng cách đệ quy) cho đến khi f(x,x)==dtrả về x.


1

Toán học 38 36

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

Sử dụng

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

(* 64 *)

Mục đầu tiên (trước khi code-golfthẻ được thêm vào câu hỏi.)

Một vấn đề đơn giản, được đưa ra là Divisors[n]trả về các ước của n(bao gồm n) và Length[Divisors[n]]trả về số lượng các ước đó. **

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

Ví dụ

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

Đồ họa toán học


David, ngắn hơn và nhanh hơn Length@Divisors@nDivisorSigma[0,n].
Mr.Wizard

Cảm ơn. Tôi đã không biết về việc sử dụng DivisorSigma.
DavidC


1

Jelly , 6 byte (không cạnh tranh)

2*RÆdi

Hãy thử trực tuyến!hoặc xác minh tất cả các trường hợp thử nghiệm .

Làm thế nào nó hoạt động

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.

Tại sao bạn làm 2*vậy Có phải mọi số sau đó đều có nhiều ước hơn n?
Erik the Outgolfer

2
Không; ví dụ, tất cả các số nguyên tố có chính xác hai ước. Tuy nhiên, chúng tôi đang tìm kiếm số nguyên dương nhỏ nhất với n ước. Vì 2**(n-1)thuộc về phạm vi đó, cái nhỏ nhất cũng làm như vậy.
Dennis

0

C ++, 87 ký tự

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 ký tự, Không đệ quy

Một chút dài dòng hơn các giải pháp python khác nhưng nó không đệ quy nên nó không đạt giới hạn đệ quy của 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

Perl 6 , 39 ký tự

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

Ví dụ sử dụng:

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