คำนวณตัวเลขจริง


18

คำนิยาม

เป็นจำนวนเต็มบวกnเป็นจำนวนปฏิบัติ (OEIS ลำดับA005153 ) IFF nทุกจำนวนเต็มบวกที่มีขนาดเล็กสามารถแสดงเป็นผลรวมของตัวหารที่แตกต่างของ

ตัวอย่างเช่น18เป็นจำนวนจริง: ตัวหารคือ 1, 2, 3, 6, 9, และ 18 และจำนวนเต็มบวกอื่น ๆ ที่น้อยกว่า 18 สามารถเกิดขึ้นได้ดังนี้:

 4 = 1 + 3          5 = 2 + 3           7 = 1 + 6
 8 = 2 + 6          10 = 1 + 9         11 = 2 + 9
12 = 3 + 9 = 1 + 2 + 9 = 1 + 2 + 3 + 6
13 = 1 + 3 + 9      14 = 2 + 3 + 9      15 = 6 + 9
16 = 1 + 6 + 9      17 = 2 + 6 + 9

แต่14ไม่ใช่ตัวเลขที่ใช้งานได้จริง: ตัวหารคือ 1, 2, 7 และ 14 และไม่มีส่วนย่อยของสิ่งเหล่านี้ซึ่งเพิ่มไปยัง 4, 5, 6, 11, 12, หรือ 13

ท้าทาย

เขียนโปรแกรมฟังก์ชั่นหรือคำกริยาที่ใช้เป็นจำนวนเต็มบวกxและส่งกลับหรือพิมพ์จำนวนจริงx th , ดัชนีจาก 1 เพื่อความสอดคล้องกับ OEIS รหัสของคุณต้องมีประสิทธิภาพเพียงพอที่สามารถจัดการอินพุตได้สูงสุด 250000 ในเวลาน้อยกว่าสองนาทีบนคอมพิวเตอร์เดสก์ท็อปที่เหมาะสม (NB การใช้งานอ้างอิงของฉันใน Java จัดการ 250000 ในเวลาน้อยกว่า 0.5 วินาทีและการใช้งานอ้างอิงของฉันใน Python จัดการใน 12 วินาที)

กรณีทดสอบ

Input        Expected output
1            1
8            18
1000         6500
250000       2764000
1000000      12214770
3000000      39258256

(IMHO) สิ่งนี้สามารถเป็นที่น่าสนใจหากรหัสที่เร็วที่สุด (ต่อภาษา?) ชนะ
ชื่อที่ปรากฏ

4
@SargeBorsch ดังนั้นคุณจะเห็นตารางรายการ 250K ทั่วทุกคำตอบ
Dr. belisarius

@ belisarius เป็นจุดที่ดี แต่ฉันคิดว่าการโกงนั้นสามารถถูกแบนได้อย่างง่ายดาย หรือปัญหาอาจต้องการคำตอบที่ถูกต้องสำหรับหมายเลขใด ๆแต่ก็จะมีปัญหาเมื่อทำในภาษาที่ไม่มีเลขจำนวนเต็มขนาดใหญ่ในไลบรารีมาตรฐาน ... : /
ชื่อที่แสดง

ฉันมีการเพิ่มประสิทธิภาพอัลกอริทึมอย่างเดียว แต่ด้วยกฎปัจจุบันฉันขี้เกียจเกินกว่าจะใช้งานได้: P
ชื่อที่แสดง

4
@SargeBorsch หากคุณไม่ต้องการเล่นกอล์ฟโค้ดของคุณสามารถอัปโหลดไปยัง gist.github.com และวางลิงค์ในความคิดเห็นที่นี่หรือในการแชท FWIW ฉันชอบโค้ดกอล์ฟที่มีข้อ จำกัด ด้านประสิทธิภาพและโค้ดที่เร็วที่สุดด้วยเหตุผลสองประการประการแรกความยาวของโค้ดนั้นสามารถวัดได้อย่างเป็นกลางมากกว่า ประการที่สองมันแนะนำองค์ประกอบของการแลกเปลี่ยน: การเพิ่มประสิทธิภาพความเร็วใดที่จะถูกปล่อยออกมาเพื่อลดรหัสโดยไม่ทำลายประสิทธิภาพการทำงาน?
ปีเตอร์เทย์เลอ

คำตอบ:


5

J (99 ตัวอักษร)

f=:3 :0
'n c'=.0 1
while.c<y do.
'p e'=.__ q:n=.n+2
c=.c+*/(}.p)<:}:1+*/\(<:p^e+1)%<:p
end.
n+n=0
)

เนื่องจากคำแถลงปัญหาถามหา "โปรแกรมฟังก์ชั่นหรือคำกริยา " ใครบางคนต้องยื่นญัตติ J คน J จะสังเกตเห็นว่าฉันไม่ได้เล่นกอล์ฟ (!) หรือปรับให้เหมาะสม เช่นเดียวกับรายการอื่น ๆ ฉันใช้ทฤษฎีบทของ Stewart ที่กล่าวถึงที่ลิงก์ OEIS เพื่อทดสอบว่าตัวเลขแต่ละเลขคู่นั้นใช้งานได้จริงหรือไม่

ฉันไม่สามารถเข้าถึง "คอมพิวเตอร์เดสก์ท็อปที่เหมาะสม" พร้อมด้วย J ที่ติดตั้ง ในเน็ตบุ๊กอายุหกปีของฉันf 250000คำนวณใน 120.6 วินาทีซึ่งไม่ได้ค่อนข้างต่ำกว่าสองนาที แต่สันนิษฐานว่าในคอมพิวเตอร์ที่เหมาะสมกว่านี้เล็กน้อยจะเสร็จสิ้นในเวลานี้


6

Mathematica, 126 121 ตัวอักษร

ขอบคุณ belisarius

ใช้สูตรในวิกิพีเดีย

f=(i=j=1;While[j<#,If[And@@Thread[#[[;;,1]]<2+Most@DivisorSum[FoldList[#Power@@#2&,1,#],#&]&@FactorInteger@++i],j++]];i)&

ตัวอย่าง:

f[1]

1

f[8]

18

f[250000]

2764000

ใช้เวลา 70 ปีในการคำนวณf[250000]บนคอมพิวเตอร์ของฉัน


3
ฉันคิดว่าคุณจะได้ประสิทธิภาพที่ดีขึ้นโดยเสียค่าใช้จ่ายของถ่านหนึ่งตัวด้วยการเลี่ยงจำนวนเต็มแปลก ๆ
ดร. เบลิซา

1
ในการลดรหัสจากการส่งข้อมูล OEIS คุณจะทำให้การประมวลผลช้าลง 10 เท่า เพียงแค่สงสัยว่า "ทำไมคุณถึงคิดว่ารหัสของคุณทำงานช้ากว่าตัวอย่าง OEIS มาก?"
DavidC

@belisarius ข้อเสนอแนะของคุณลดเวลาครึ่งตามที่คาดไว้
DavidC

2
เช่นเดียวกันใน 119 ตัวอักษร:(i=j=1;While[j<#,If[And@@Thread[#[[;;,1]]<2+Most@DivisorSum[FoldList[#Power@@#2&,1,#],#&]&@FactorInteger@++i],j++]];i)&
ดร. เบลิซา

3

Haskell - 329

s 1=[]
s n=p:(s$div n p)where d=dropWhile((/=0).mod n)[2..ceiling$sqrt$fromIntegral n];p=if null d then n else head d
u=foldr(\v l@((n,c):q)->if v==n then(n,c+1):q else(v,1):l)[(0,1)]
i z=(z<2)||(head w==2)&&(and$zipWith(\(n,_)p->n-1<=p)(tail n)$scanl1(*)$map(\(n,c)->(n*n^c-1)`div`(n-1))n)where w=s z;n=u w
f=((filter i[0..])!!)

ตัวอย่าง:

> f 1
1
> f 13
32
> f 1000
6500

นี่คือชุดทดสอบขนาดเล็ก (ต่อจากข้างต้น):

import Data.Time.Clock
import System.IO

test x = do
    start <- getCurrentTime
    putStr $ (show x) ++ " -> " ++ (show $ f x)
    finish <- getCurrentTime
    putStrLn $ " [" ++ (show $ diffUTCTime finish start) ++ "]"

main = do
    hSetBuffering stdout NoBuffering
    mapM_ test [1, 8, 1000, 250000, 1000000, 3000000]

ผลการทดสอบหลังจากคอมไพล์ด้วยghc -O3:

1 -> 1 [0.000071s]
8 -> 18 [0.000047s]
1000 -> 6500 [0.010045s]
250000 -> 2764000 [29.084049s]
1000000 -> 12214770 [201.374324s]
3000000 -> 39258256 [986.885397s]

เมื่อฉันพยายามใน ghci parse error on input `='มันบ่น ฉันจำเป็นต้องใช้การตั้งค่าสถานะหรืออื่น ๆ
Peter Taylor

1
@PeterTaylor คุณไม่สามารถวางนิยามฟังก์ชันลงใน ghci เช่นนั้นได้ ง่ายที่สุดที่คุณสามารถทำได้คือบันทึกasdf.hsและเรียกใช้ghci asdf.hsจากนั้นคุณจะสามารถเข้าถึงได้f
mniip

ghc --make -O3 [filename]@PeterTaylor คุณสามารถโหลดด้วย ghci ด้วย:l [filename]แต่เนื่องจากข้อ จำกัด ด้านเวลาที่รวบรวมไว้น่าจะดีที่สุด :)
Jonathan Van Matre

@JonathanVanMatre ตามที่เห็นในความคิดเห็นด้านบนghciโหลดไฟล์ที่ระบุไว้ในอาร์กิวเมนต์ของมัน
mniip

อาโอเค. ghcในขณะเดียวกันที่ผมเคยได้มันทำงานด้วยกรอบทดสอบของคุณและ คอมพิวเตอร์ของคุณเร็วกว่าของฉัน แต่ก็ยังอยู่ในเกณฑ์ประสิทธิภาพการทำงานบนคอมพิวเตอร์ของฉันที่ 98 วินาที
ปีเตอร์เทย์เลอ

2

Javascript, 306 307 282B

function y(r){for(n=r-1,k=1;n;k++)if(p=[],e=[],c=0,P=s=1,!((x=k)%2|1==x)){while(x>1){for(f=x,j=2;j<=Math.sqrt(f);j++)if(f%j==0){f=j;break}f!=p[c-1]?(p.push(f),e.push(2),c++):e[c-1]++,x/=f}for(i=0;c>i;i++){if(p[i]>P+1){s=0;break}P*=(Math.pow(p[i],e[i])-1)/(p[i]-1)}s&&n--}return k-1}

250k โดยประมาณ 6s บนแล็ปท็อปของฉัน

แสดงความคิดเห็นรหัส un-golfed: http://jsfiddle.net/82xb9/3/ตอนนี้มีการทดสอบซิกม่าที่ดีขึ้นและเงื่อนไขที่ดีขึ้น (ขอบคุณความคิดเห็น)

รุ่นที่แก้ไขล่วงหน้า: http://jsfiddle.net/82xb9/ http://jsfiddle.net/82xb9/1/


คำถามไม่ขอฟังก์ชั่นหรือโปรแกรม (JS ไม่ได้มีคำกริยา) ดังนั้นแทนที่จะไม่นับบรรทัดแรกที่คุณควรห่อบรรทัดที่สองในการประกาศฟังก์ชั่นและแทนที่สุดท้ายกับk--; return k-1แม้ว่านั่นจะเป็นการเพิ่มจำนวนไบต์ของคุณเล็กน้อย แต่คุณสามารถบันทึกบางอย่างด้วยสิ่งต่าง ๆ เช่นแทนที่p[i]>=P+2ด้วยp[i]>P+1(และอาจโดยการลบการเรียกฟังก์ชันภายในและใช้breakแทน)
Peter Taylor

ผมคิดว่า "การทดสอบซิก" ส่วนหนึ่งสามารถเขียนใหม่สำหรับทั้งขนาดและความเร็ว: jsfiddle.net/3DTSa แม้ว่าโซลูชัน JS นี้จะเร็วมากเหมือนเดิม
user2846289
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.