ระบุจำนวนที่น้อยที่สุดที่มีตัวหาร 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 ^ ¨⍳2*⍵ d รายการส่งผลให้มีการค้นหาแล้วสำหรับdตัวเอง ( ⍳⍵) ซึ่งเป็นฟังก์ชั่นที่ต้องการf (ง)


ยินดีด้วย! 23 ตัวอักษร ... ว้าว!
SteeveDroz

19:{⍵⍳⍨(+/⊢=⊢∧⍳)¨⍳2*⍵}
อดัม

fผมไม่คิดว่าคุณจะต้องกำหนด
Zacharý

5

GolfScript, 29 28 ตัวอักษร

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

แก้ไข:สามารถบันทึกอักขระตัวเดียวหากเรา จำกัด การค้นหาไว้ที่ <2 ^ n ขอบคุณ Peter Taylorสำหรับแนวคิดนี้

รุ่นก่อนหน้า:

{.{\)..,{)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สำหรับการป้อนข้อมูล
Peter Taylor

ทางออกที่ดีที่สุดของฉันจนถึงตอนนี้ยืมมาค่อนข้างหนักจากคุณเท่าที่ฉันคิดว่ามันควรจะเป็นความคิดเห็นมากกว่าคำตอบที่แยกต่างหาก
Peter Taylor

4

งูหลาม: 64

แก้ไขปัญหาของบาคุริวและรวมเอาข้อเสนอแนะของ grc รวมถึงเคล็ดลับจากโซลูชัน R ของ Plannapus เราได้รับ:

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

4

Python: 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 exceededด้วยอินพุตขนาดเล็กใน CPython และแม้กระทั่งการตั้งค่าขีด จำกัด เป็นจำนวนมากก็อาจจะทำให้เกิดปัญหาบางอย่าง ในการใช้งานของงูหลามที่เพิ่มประสิทธิภาพการเรียกคืนหางควรทำงานได้ดี

เวอร์ชันที่ละเอียดมากขึ้นซึ่งไม่ควรมีข้อ จำกัด ดังกล่าวคือโซลูชัน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))
ความผันผวน

f=lambda n,k=1:n==sum(k%-~i<1for i in range(k))or-~f(n,k+1)บันทึก 7 ไบต์
Dennis

4

Mathematica 38 36

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

การใช้งาน:

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

ผลลัพธ์:

498960

แก้ไข

คำอธิบายบางอย่าง:

DivisorSum [n, form] หมายถึงผลรวมของรูปแบบ [i] สำหรับทุก i ที่หาร n

ในขณะที่form[i]ฉันกำลังใช้ฟังก์ชั่น1 &นั้นมันจะกลับมาเสมอ1ดังนั้นคำนวณผลรวมของตัวหารอย่างมีประสิทธิภาพ


ไม่มีแท็ก code-golf ดังนั้นฉันจึงให้คำตอบนาน! oops
DavidC

@DavidCarraher ฉันแค่เดา ​​:)
ดร. เบลิซาเรี

ฉันคิดว่าฉันรู้ว่าDivisorSumผลตอบแทนคืออะไร(ผลรวมของตัวหาร) แต่ฉันไม่เห็นว่ามันมีประโยชน์อย่างไรในการตอบคำถาม คุณช่วยอธิบายวิธีการทำงานได้ไหม BTW ฉันคิดว่าคุณควรรวมข้อมูลเวลาสำหรับ n = 200 ฟังก์ชั่นนี้เร็วมากให้ตัวเลขทั้งหมดที่ต้องตรวจสอบ
DavidC

@DavidCarraher ดูการแก้ไข Re: กำหนดเวลา - เครื่องของฉันช้า
เกินไป

Mathematica มี built-in ไม่เพียงพอสำหรับแนวทางที่ซับซ้อนมากขึ้นในการแยกแฟคตอริ่งให้สั้นลงหรือไม่? หากเป็นกรณีนี้ฉันผิดหวัง
Peter Taylor

3

J, 33 ตัวอักษร

รวดเร็วพอสมควรผ่านจำนวนที่น้อยกว่าและคำนวณจำนวนตัวหารตามการแยกตัวประกอบ

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

   f 19
262144

3

Haskell 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? ฉันพยายาม google มันและได้อ่านบทความไม่กี่ แต่ยังในท้ายที่สุดฉันมักจะถามว่า "ทำไมพวกเขาทำเช่นนี้ :(?" ฉันไม่เคยทำงานกับภาษาไวยากรณ์ที่ไม่ใช่ ASCII และต้องการหาว่า มันมีข้อได้เปรียบที่แท้จริงใด ๆ
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ให้เวกเตอร์ของ booleans: TRUE เมื่อจำนวนเต็มจาก 1 ถึง n เป็นตัวหารของ n และ FALSE ถ้าไม่ใช่ sum(!n%%1:n)รวมค่าบูลีนเป็น 0 ถ้า FALSE และ 1 ถ้า TRUE และผลรวมพวกเขาดังนั้นนั่นN-sum(...)คือ 0 เมื่อจำนวนตัวหารคือ N 0 จะถูกตีความว่าเป็น FALSE โดยwhileซึ่งจะหยุด

การใช้งาน:

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}

จริงๆแล้วมีเพียง 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

Haskell: 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ออกเป็น primes (ด้วยการทำซ้ำ) เรียงลำดับจากมากไปน้อยลดขนาดแต่ละอัน zip ด้วยลำดับ primes ที่ไม่มีที่สิ้นสุดแล้วจึงพับผลิตภัณฑ์ของp^(factor-1)
Peter Taylor

2
@PeterTaylor ไม่จำเป็น สำหรับ n = 16 = 2 * 2 * 2 * 2 โซลูชันคือ 2 ^ 3 * 3 ^ 1 * 5 ^ 1 = 120 ไม่ใช่ 2 ^ 1 * 3 ^ 1 * 5 ^ 1 * 7 ^ 1 = 210
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

Haskell (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*...*pmที่ p1 <= 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 ใช่คุณพูดถูก ขอบคุณสำหรับการชี้ให้เห็นว่า
เรย์

2

Brachylogขนาด 2 ไบต์

fl

ลองออนไลน์!

รับอินพุตผ่านตัวแปรเอาต์พุตและเอาต์พุตผ่านตัวแปรอินพุต

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

นี้กริยาเดียวกันการป้อนข้อมูลผ่านตัวแปรและแสดงผลผ่านตัวแปรเอาท์พุท, แก้ความท้าทายนี้แทน


ดี แต่ไม่มีสิทธิ์ใช้ตัวต่อเนื่องจากภาษานี้ใช้งานได้เร็วกว่าคำถาม
SteeveDroz

เมื่อฉันใหม่ที่นี่หนึ่งในสิ่งแรกที่ฉันบอกคือภาษาใหม่กว่าคำถามที่ไม่ได้ไม่ใช่การแข่งขันอีกต่อไปและสำรองไว้โดย meta: codegolf.meta.stackexchange.com/questions/12877/…
สตริงที่ไม่เกี่ยวข้อง

โอไม่เป็นไรแล้ว เห็นได้ชัดว่ากฎถูกสร้างขึ้นเพื่อพัฒนาและเราต้องจำไว้ว่าจุดประสงค์หลักของเว็บไซต์นี้คือการพัฒนาตนเองและสนุกสนาน ตอบรับแล้ว!
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) วนซ้ำ (ตามการเรียกซ้ำ) จนกระทั่งแล้วส่งคืน xn
g(d)f(x,x)==d


1

Mathematica 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

กราฟิกทางคณิตศาสตร์


เดวิดสั้นและเร็วขึ้นกว่าที่เป็น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 หรือไม่
Erik the Outgolfer

2
ไม่มี เช่นทุกช่วงเวลามีตัวหารสองตัว อย่างไรก็ตามเรากำลังค้นหาจำนวนเต็มบวกที่เล็กที่สุดที่มีตัวหารnตัว เนื่องจาก2**(n-1)อยู่ในช่วงดังกล่าวจึงมีขนาดเล็กที่สุดเช่นกัน
Dennis


0

Python2, 95 ตัวอักษร, ไม่เรียกซ้ำ

verbose มากกว่าโซลูชันหลามอื่น ๆ เล็กน้อย แต่มันไม่ใช่แบบเรียกซ้ำดังนั้นจึงไม่ถึงขีด จำกัด การเรียกซ้ำ 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)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.