{-# OPTIONS_GHC -O2 #-}
{-# LANGUAGE BangPatterns #-}
-- forked ideone.com/q3fma: use Int in nthHam for speed
-- rosettacode.org/wiki/Hamming_numbers#Haskell
-- stackoverflow.com/a/10160054/849891
-- stackoverflow.com/a/12041774/849891
-- stackoverflow.com/a/60805693/849891
module Main where -- cf. ideone.com/k8PU3, GXh4P0, 01dpQu
import Data.List
import Data.Function
hamming
= 1 :
map (2*) hamming `union`
map (3*) hamming `union`
map (5*) hamming
where
union a
@(x:xs
) b
@(y:ys
) = case compare x y
of LT -> x : union xs b
EQ -> x : union xs ys
GT -> y : union a ys
main =
do
case s of
print (hamming
!! 1690, hamming
!! 1691) print $ hamming
!! (1000000-1) -- 9 MB: releases the prefix of the list "b" -> do
print $ hamming
!! (1000000-1) print $ hamming
!! 1000000 -- 77 MB: does NOT release the prefix (is needed twice) "c" -> do
"d" -> do
let (_ ,(r,t)) = nthHam (1000000) -- 4 MB: stores upper band only
(_ ,(r2,t2)) = nthHam (1000001)
_ -> do -- 10^8: 4 MB 0.27 sec
let (nb
,(r
,t
)) = nthHam
(read s
) -- 10^9: 6 MB (-4=2) 1.42 sec ~n^0.7 print (nb
, t
, showLogVal
2 r
) -- 10^10: 14 MB (-4=10) 7.20 sec ~n^0.7 -- print (case t of (i,j,k) -> 2^i*3^j*5^k)
-- print (case t of (i,j,k) -> 2^i*3^j*5^k)
showLogVal base logval
= show (10**y
) ++ "E+" ++ show x
trival (i,j,k) = 2^i * 3^j * 5^k
-- directly find n-th Hamming number (base 1, from 2), in ~ O(n^{2/3}) time
-- based on "top band" idea by Louis Klauder from DDJ discussion,
-- by Will Ness, my original post: drdobbs.com/blogs/architecture-and-design/228700538
{-
ln2 = log 2; ln3 = log 3; ln5 = log 5
logval (i,j,k) = fromIntegral i*ln2 + fromIntegral j*ln3 + fromIntegral k*ln5
estval n = (6*ln2*ln3*ln5* fromIntegral n)**(1/3) -- estimated logval
rngval n
| n > 500000 = (1.698 , 0.0050) -- empirical
| n > 50000 = (1.693 , 0.0100) -- estimation
| n > 500 = (1.66 , 0.0500) -- correction
| n > 1 = (1.56 , 0.2000) -- (dist,width)
| otherwise = (1.56 , 0.4000)
-- estval(n) = log (M[n]) = ln2 * logBase 2 (M[n])
-}
-- lb3 :: Double
lb3
= logBase 2 3; lb5
= logBase 2 5 -- lb3 == log 3/log 2, lb5 == log 5/log 2-- logval2 :: (Int,Int,Int) -> Double
-- estval2 :: Integer -> Double
estval2 n
= (6*lb3
*lb5
* fromIntegral n
)**(1/3) -- estimated logval **Base 2**rngval2 n -- -1/v +2/v seems to works too
| n > 500000 = (ww-(3/estval2 n), 6/estval2 n) -- space tweak !!! (thx, GBG!)
| n > 500000 = (2.4496 , 0.0076 ) -- empirical
| n > 50000 = (2.4424 , 0.0146 ) -- estimation
| n > 500 = (2.3948 , 0.0723 ) -- correction - base 2
| n > 1 = (2.2506 , 0.2887 ) -- (dist,width)
-- nthHam :: Integer -> ( (Int,Int), (Double, (Int, Int, Int))) -- ( 64-bits: use Int!! NB! )
-- _band size stuff_ ---------------- (*1*)
-- _max logval, min delta in band_
nthHam n -- n: 1-based 1,2,3...
| w
>= 1 = error $ "Breach of contract: (w < 1): " ++ show (w
) | m
< 0 = error $ "Not enough triples generated: " ++ show (c
,n
) | m
>= nb
= error $ "Generated band is too narrow: " ++ show (m
,nb
) | True = -- ((m,nb),res) -- m=target index in band from top, nb=band's length
( ( isTrulySorted ,
fst (head s
), ---------------- (*1*) , res)
where
(d,w) = rngval2 n -- correction dist, width
hi = estval2 n - d -- hi > logval2 > hi-w
(c,b) = foldl_ -- total count, the band
(\(!c,!b) (i,t) -> case t of [] -> (i+c,b)
[x] -> (i+c,x:b))
(0::Int,[]) -- ( 64bit: use Int!!! NB! ) -- (sum *** concat) . unzip $
[ (r,(i,j,k)) | frac < w ] ) -- store it, if inside band
let (i,frac) = pr (hi-q) ; r = hi - frac -- r = i + q
(s
,res
) = ( sortBy
(flip compare `on`
fst) b
, s
!!m
) -- sorted decreasing, result
ey0jIE9QVElPTlNfR0hDIC1PMiAjLX0Key0jIExBTkdVQUdFIEJhbmdQYXR0ZXJucyAjLX0KCi0tIGZvcmtlZCBpZGVvbmUuY29tL3EzZm1hOiAgdXNlIEludCBpbiBudGhIYW0gZm9yIHNwZWVkCgotLSByb3NldHRhY29kZS5vcmcvd2lraS9IYW1taW5nX251bWJlcnMjSGFza2VsbCAKLS0gc3RhY2tvdmVyZmxvdy5jb20vYS8xMDE2MDA1NC84NDk4OTEKLS0gc3RhY2tvdmVyZmxvdy5jb20vYS8xMjA0MTc3NC84NDk4OTEKLS0gc3RhY2tvdmVyZmxvdy5jb20vYS82MDgwNTY5My84NDk4OTEKCm1vZHVsZSBNYWluIHdoZXJlICAgICAgICAgLS0gY2YuIGlkZW9uZS5jb20vazhQVTMsIEdYaDRQMCwgMDFkcFF1CgppbXBvcnQgRGF0YS5MaXN0IAppbXBvcnQgRGF0YS5GdW5jdGlvbgoKaGFtbWluZyA6OiBbSW50ZWdlcl0KaGFtbWluZyA9IDEgOiBtYXAgKDIqKSBoYW1taW5nIGB1bmlvbmAgbWFwICgzKikgaGFtbWluZyBgdW5pb25gIG1hcCAoNSopIGhhbW1pbmcKICB3aGVyZQogICAgdW5pb24gYUAoeDp4cykgYkAoeTp5cykgPSBjYXNlIGNvbXBhcmUgeCB5IG9mCiAgICAgICAgICAgIExUIC0+IHggOiB1bmlvbiAgeHMgIGIKICAgICAgICAgICAgRVEgLT4geCA6IHVuaW9uICB4cyAgeXMKICAgICAgICAgICAgR1QgLT4geSA6IHVuaW9uICBhICAgeXMKCm1haW4gOjogSU8gKCkKbWFpbiA9CiBkbyAKICBzIDwtIGdldExpbmUKICBjYXNlIHMgb2YKICAgImEiIC0+IGRvIHByaW50ICQgdGFrZSAyMCBoYW1taW5nCiAgICAgICAgICAgICBwcmludCAgKGhhbW1pbmcgISEgMTY5MCwgaGFtbWluZyAhISAxNjkxKQogICAgICAgICAgICAgcHJpbnQgJCBoYW1taW5nICEhICgxMDAwMDAwLTEpICAgICAgICAgIC0tIDkgTUI6IHJlbGVhc2VzIHRoZSBwcmVmaXggb2YgdGhlIGxpc3QKICAgImIiIC0+IGRvCiAgICAgICAgICAgICBwcmludCAkIGhhbW1pbmcgISEgKDEwMDAwMDAtMSkKICAgICAgICAgICAgIHByaW50ICQgaGFtbWluZyAhISAgMTAwMDAwMCAgICAgIC0tIDc3IE1COiBkb2VzIE5PVCByZWxlYXNlIHRoZSBwcmVmaXggKGlzIG5lZWRlZCB0d2ljZSkKICAgImMiIC0+IGRvCiAgICAgICAgICAgICBtYXBNXyBwcmludCAkIHRha2UgMiAkIGRyb3AgOTk5OTk5IGhhbW1pbmcgIC0tIDkgTUI6IHVzZWQgb25jZSwgcHJlZml4IGdjLWQKICAgImQiIC0+IGRvCiAgICAgICAgICAgICBsZXQgKF8gLChyLHQpKSAgID0gbnRoSGFtICgxMDAwMDAwKSAgICAgICAgIC0tIDQgTUI6IHN0b3JlcyB1cHBlciBiYW5kIG9ubHkKICAgICAgICAgICAgICAgICAoXyAsKHIyLHQyKSkgPSBudGhIYW0gKDEwMDAwMDEpCiAgICAgICAgICAgICBwcmludCAodCx0cml2YWwgdCkgICAgICAgICAKICAgICAgICAgICAgIHByaW50ICh0Mix0cml2YWwgdDIpICAgICAgICAgCiAgIF8gICAtPiBkbyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tICAgIDEwXjg6ICA0IE1CICAgICAgICAgIDAuMjcgc2VjCiAgICAgICAgICAgICBsZXQgKG5iLChyLHQpKSA9IG50aEhhbSAocmVhZCBzKSAgICAgICAgIC0tICAgIDEwXjk6ICA2IE1CICgtND0yKSAgIDEuNDIgc2VjICAgfm5eMC43CiAgICAgICAgICAgICBwcmludCAobmIsIHQsIHNob3dMb2dWYWwgMiByKSAgICAgICAgICAgLS0gICAxMF4xMDogMTQgTUIgKC00PTEwKSAgNy4yMCBzZWMgICB+bl4wLjcKICAgICAgICAgICAgIC0tIHByaW50IChjYXNlIHQgb2YgKGksaixrKSAtPiAyXmkqM15qKjVeaykKICAgICAgICAgICAgIC0tIHByaW50IChjYXNlIHQgb2YgKGksaixrKSAtPiAyXmkqM15qKjVeaykKCnNob3dMb2dWYWwgOjogRG91YmxlIC0+IERvdWJsZSAtPiBTdHJpbmcKc2hvd0xvZ1ZhbCBiYXNlIGxvZ3ZhbCA9IHNob3cgKDEwKip5KSArKyAiRSsiICsrIHNob3cgeAogICB3aGVyZSAoeCx5KSA9IHByb3BlckZyYWN0aW9uIChsb2dCYXNlIDEwIGJhc2UgKiBsb2d2YWwpIAogICAKdHJpdmFsIChpLGosaykgICAgPSAyXmkgKiAzXmogKiA1XmsKCi0tIGRpcmVjdGx5IGZpbmQgbi10aCBIYW1taW5nIG51bWJlciAoYmFzZSAxLCBmcm9tIDIpLCBpbiB+IE8obl57Mi8zfSkgdGltZQotLSBiYXNlZCBvbiAidG9wIGJhbmQiIGlkZWEgYnkgTG91aXMgS2xhdWRlciBmcm9tIERESiBkaXNjdXNzaW9uLAotLSBieSBXaWxsIE5lc3MsIG15IG9yaWdpbmFsIHBvc3Q6IGRyZG9iYnMuY29tL2Jsb2dzL2FyY2hpdGVjdHVyZS1hbmQtZGVzaWduLzIyODcwMDUzOAp7LQpsbjIgPSBsb2cgMjsgIGxuMyA9IGxvZyAzOyAgbG41ID0gbG9nIDUKbG9ndmFsIChpLGosaykgICAgPSBmcm9tSW50ZWdyYWwgaSpsbjIgKyBmcm9tSW50ZWdyYWwgaipsbjMgKyBmcm9tSW50ZWdyYWwgaypsbjUKZXN0dmFsIG4gICAgICAgICAgPSAoNipsbjIqbG4zKmxuNSogZnJvbUludGVncmFsIG4pKiooMS8zKSAgLS0gZXN0aW1hdGVkIGxvZ3ZhbApybmd2YWwgbiAgICAgICAKICAgIHwgbiA+IDUwMDAwMCAgPSAoMS42OTggLCAwLjAwNTApICAgICAgICAgICAgICAgICAgICAgICAgICAtLSBlbXBpcmljYWwKICAgIHwgbiA+IDUwMDAwICAgPSAoMS42OTMgLCAwLjAxMDApICAgICAgICAgICAgICAgICAgICAgICAgICAtLSAgZXN0aW1hdGlvbgogICAgfCBuID4gNTAwICAgICA9ICgxLjY2ICAsIDAuMDUwMCkgICAgICAgICAgICAgICAgICAgICAgICAgIC0tICAgY29ycmVjdGlvbiAgCiAgICB8IG4gPiAxICAgICAgID0gKDEuNTYgICwgMC4yMDAwKSAgICAgICAgICAgICAgICAgICAgICAgICAgLS0gICAgKGRpc3Qsd2lkdGgpCiAgICB8IG90aGVyd2lzZSAgID0gKDEuNTYgICwgMC40MDAwKSAKCiAtLSBlc3R2YWwobikgPSBsb2cgKE1bbl0pID0gbG4yICogbG9nQmFzZSAyIChNW25dKQotfQp3dyA9IGxvZ0Jhc2UgMiAzMCAvIDIKLS0gbGIzIDo6IERvdWJsZQpsYjMgPSBsb2dCYXNlIDIgMzsgIGxiNSA9IGxvZ0Jhc2UgMiA1ICAgLS0gbGIzID09IGxvZyAzL2xvZyAyLCAgbGI1ID09IGxvZyA1L2xvZyAyCi0tIGxvZ3ZhbDIgOjogKEludCxJbnQsSW50KSAtPiBEb3VibGUKbG9ndmFsMiAoaSxqLGspICAgID0gZnJvbUludGVncmFsIGkgKyBmcm9tSW50ZWdyYWwgaipsYjMgKyBmcm9tSW50ZWdyYWwgaypsYjUKLS0gZXN0dmFsMiA6OiBJbnRlZ2VyIC0+IERvdWJsZQplc3R2YWwyIG4gICAgICAgICAgPSAoNipsYjMqbGI1KiBmcm9tSW50ZWdyYWwgbikqKigxLzMpICAtLSBlc3RpbWF0ZWQgbG9ndmFsICoqQmFzZSAyKioKcm5ndmFsMiBuICAgICAgICAgICAtLSAgLTEvdiAgICAgICAgICArMi92ICAgICAgc2VlbXMgdG8gd29ya3MgdG9vCiAgICB8IG4gPiA1MDAwMDAgID0gKHd3LSgzL2VzdHZhbDIgbiksIDYvZXN0dmFsMiBuKSAgICAgIC0tIHNwYWNlIHR3ZWFrICEhISAodGh4LCBHQkchKQogICAgfCBuID4gNTAwMDAwICA9ICgyLjQ0OTYgLCAwLjAwNzYgKSAgICAgICAgICAgICAgICAgICAgICAgICAgLS0gZW1waXJpY2FsCiAgICB8IG4gPiA1MDAwMCAgID0gKDIuNDQyNCAsIDAuMDE0NiApICAgICAgICAgICAgICAgICAgICAgICAgICAtLSAgZXN0aW1hdGlvbgogICAgfCBuID4gNTAwICAgICA9ICgyLjM5NDggLCAwLjA3MjMgKSAgICAgICAgICAgICAgICAgICAgICAgICAgLS0gICBjb3JyZWN0aW9uIC0gYmFzZSAyCiAgICB8IG4gPiAxICAgICAgID0gKDIuMjUwNiAsIDAuMjg4NyApICAgICAgICAgICAgICAgICAgICAgICAgICAtLSAgICAoZGlzdCx3aWR0aCkKICAgIHwgb3RoZXJ3aXNlICAgPSAoMi4yNTA2ICwgMC41NzcxICkgIAogCi0tIG50aEhhbSA6OiBJbnRlZ2VyIC0+ICggKEludCxJbnQpLCAoRG91YmxlLCAoSW50LCBJbnQsIEludCkpKSAgLS0gKCA2NC1iaXRzOiB1c2UgSW50ISEgICAgTkIhICkKLS0gICAgICAgICAgICAgICAgICAgIF9iYW5kIHNpemUgc3R1ZmZfICAtLS0tLS0tLS0tLS0tLS0tICgqMSopCgpudGhIYW0gOjogSW50IC0+ICggKEJvb2wsIERvdWJsZSwgRG91YmxlKSwgKERvdWJsZSwgKEludCwgSW50LCBJbnQpKSkKLS0gICAgICAgICAgICAgICAgICAgX21heCBsb2d2YWwsIG1pbiBkZWx0YSBpbiBiYW5kXwpudGhIYW0gbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tIG46IDEtYmFzZWQgMSwyLDMuLi4KICB8IHcgPj0gMSAgID0gZXJyb3IgJCAiQnJlYWNoIG9mIGNvbnRyYWN0OiAodyA8IDEpOiAgIiArKyBzaG93ICh3KQogIHwgbSA8ICAwICAgPSBlcnJvciAkICJOb3QgZW5vdWdoIHRyaXBsZXMgZ2VuZXJhdGVkOiAiICsrIHNob3cgKGMsbikKICB8IG0gPj0gbmIgID0gZXJyb3IgJCAiR2VuZXJhdGVkIGJhbmQgaXMgdG9vIG5hcnJvdzogIiArKyBzaG93IChtLG5iKQogIHwgVHJ1ZSAgICAgPSAtLSAoKG0sbmIpLHJlcykgLS0gbT10YXJnZXQgaW5kZXggaW4gYmFuZCBmcm9tIHRvcCwgbmI9YmFuZCdzIGxlbmd0aCAgCiAgICAgICAgICAgICAgICggKCBpc1RydWx5U29ydGVkICwKICAgICAgICAgICAgICAgICAgIGZzdCAoaGVhZCBzKSwgICAgICAgICAtLS0tLS0tLS0tLS0tLS0tICgqMSopCiAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtIC0tIEJ5IChjb21wYXJlIGBvbmAgYWJzKQogICAgICAgICAgICAgICAgICAgICAgICAgKHppcFdpdGggKC0pIChtYXAgZnN0IHMpICh0YWlsIChtYXAgZnN0IHMpKSkgKQogICAgICAgICAgICAgICAgICwgcmVzKQogd2hlcmUgCiAgaXNUcnVseVNvcnRlZCA9IGFuZCBbYT5iIHwgbGV0IHo9bWFwICh0cml2YWwuc25kKSBzLCAoYSxiKTwtemlwIHogKHRhaWwgeildCiAgKGQsdykgICA9IHJuZ3ZhbDIgbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0gY29ycmVjdGlvbiBkaXN0LCB3aWR0aAogIGhpICAgICAgPSBlc3R2YWwyIG4gLSBkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tICAgaGkgPiBsb2d2YWwyID4gaGktdyAKICAoYyxiKSAgID0gZm9sZGxfICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLSB0b3RhbCBjb3VudCwgdGhlIGJhbmQKICAgICAgICAgICAgIChcKCFjLCFiKSAoaSx0KSAtPiBjYXNlIHQgb2YgW10gLT4gKGkrYyxiKSAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt4XSAtPiAoaStjLHg6YikpIAogICAgICAgICAgICAgKDA6OkludCxbXSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tICggNjRiaXQ6IHVzZSBJbnQhISEgICAgIE5CISApIAogICAgICAgICAgICAgLS0gKHN1bSAqKiogY29uY2F0KSAuIHVuemlwICQKICAgICAgICAgICAgIFsgKCBmcm9tSW50ZWdyYWwgaSsxLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLSB0b3RhbCB0cmlwbGVzIHcvIHRoaXMgKGosaykKICAgICAgICAgICAgICAgICBbIChyLChpLGosaykpIHwgZnJhYyA8IHcgXSApICAgICAgICAgICAgICAgICAtLSBzdG9yZSBpdCwgaWYgaW5zaWRlIGJhbmQKICAgICAgICAgICAgICAgfCBrIDwtIFsgMCAuLiBmbG9vciAoIGhpICAgL2xiNSkgXSwgIGxldCBwID0gZnJvbUludGVncmFsIGsqbGI1LCAgICAKICAgICAgICAgICAgICAgICBqIDwtIFsgMCAuLiBmbG9vciAoKGhpLXApL2xiMykgXSwgIGxldCBxID0gZnJvbUludGVncmFsIGoqbGIzICsgcCwKICAgICAgICAgICAgICAgICBsZXQgKGksZnJhYykgPSBwciAgKGhpLXEpIDsgICAgICAgICAgICByID0gaGkgLSBmcmFjICAtLSByID0gaSArIHEgCiAgICAgICAgICAgICAgIF0gd2hlcmUgICAgIHByID0gcHJvcGVyRnJhY3Rpb24gICAgICAgICAgICAgICAgLS0gcHIgMS4yNCA9PiAoMSwwLjI0KQogIChtLG5iKSAgPSAoIGZyb21JbnRlZ3JhbCAkIGMgLSBuLCBsZW5ndGggYiApICAgICAgICAgICAgICAgIC0tIG0gMC1iYXNlZCBmcm9tIHRvcCwgfGJhbmR8CiAgKHMscmVzKSA9ICggc29ydEJ5IChmbGlwIGNvbXBhcmUgYG9uYCBmc3QpIGIsIHMhIW0gKSAgICAgICAgLS0gc29ydGVkIGRlY3JlYXNpbmcsIHJlc3VsdAogIGZvbGRsXyAgPSBmb2xkbCc=
MTAwMDAwMDAwMDAwMAoKdG8gcHJpbnQgdGhlIGZ1bGwgdmFsdWUgYXMgd2VsbCwgdW5jb21tZW50IG9uZSBvZiB0aGUKICBgLS0gcHJpbnQgKGNhc2UgdCBvZiAoaSxqLGspIC0mZ3Q7IDJeaSozXmoqNV5rKWAKbGluZXMgaW4gYG1haW5gLCBhdCBpdHMgdmVyeSBlbmQKCi0tLS0tLQoyMDIwLTAzLTI0OiB1c2UgYEludGAgaW4gbnRoSGFtLCBub3cgb24gNjQgYml0LCBmb3Igc3BlZWQ6CgoxQiAgMC4wMnMgNi4wTUIKKChUcnVlLDI4MDMuMDIyMTkxNjEyMzc4LDEuMzI1MTc5MjU1MjE4MjQ1ZS03KSwoMTMzNCwzMzUsNDA0KSwmcXVvdDs2LjIxNjA3NTc1NTU2MjMzNUUrODQzJnF1b3Q7KQoxVCAgMi4wMXMgMTUuMU1CCigoVHJ1ZSwyODA1Mi4yOTIzNDE0NzYwMzcsMi45Nzk1MDQ2NDMwMDgxMTNlLTkpLCgxMTI2LDE2OTMwLDQwKSwmcXVvdDszLjgxNDMyNTAwNTAwNzc2NUUrODQ0NCZxdW90OykKNFQgIDUuODFzIDIyLjJNQiAgIDE2IGRpZ2l0cyB1c2VkLi4uLiAKICAgICAgICAgICAgICAgICAgc3RpbGwgZ29vZCAoYXMgZXZpZGVuY2VkIGJ5IHRoZSBgVHJ1ZWAgYmVsb3cpLCBidXQgcmVhbGx5IHB1c2hpbmcgaXQuCigoVHJ1ZSw0NDUzMS42Nzk0MjY5NTY3MSw3LjI3NTk1NzYxNDE4MzQyNmUtMTEpLCgxNjM0OCwxNjUwMyw4NzMpLCZxdW90OzIuMzUwOTgzMjcwNDA3MTM0N0UrMTM0MDUmcXVvdDspCjEwVCAgIDExLjEzcyAyNi40TUIKKChUcnVlLDYwNDM5LjY2MzkxNzAzMDYyLDcuMjc1OTU3NjE0MTgzNDI2ZS0xMSksKDE4MTg3LDIzNzcxLDE5NzEpLCZxdW90OzEuNDE4MjU5MjYxMzIxNDI3M0UrMTgxOTQmcXVvdDspCjEzVCAgIDE0LjQ0cyAzMC40TUIgICAgLi4uc3RpbGwgZ29vZAooKFRydWUsNjU5NjMuNjQzMjcyMzk4ODUsNS44MjA3NjYwOTEzNDY3NDFlLTExKSwoMjg2NDgsMjEzMDgsMTUyNiksJnF1b3Q7MS4wODQ1MjA5OTgwNDU3Mzg0RSsxOTg1NyZxdW90OykKCnNhbWUgY29kZSBvbiB0aW86CjEwVCAgIDE2Ljc3cwozNVQgICAzOC44NHMgCigoVHJ1ZSw5MTc2Ni40ODAwMjE2NjQ1Miw1LjgyMDc2NjA5MTM0Njc0MWUtMTEpLCgxMzgyNCwyMTMzLDMyMTEyKSwmcXVvdDsyLjkwNDUyODMxMjA0NDA0MkUrMjc2MjQmcXVvdDspCjYwVCAgIDUzLjc2cwooKFRydWUsMTA5ODI4LjE2MjYyNTI5MDgsNS44MjA3NjYwOTEzNDY3NDFlLTExKSwoMjgxMjMsNDU5MTMsMzg0OCksJnF1b3Q7My43MjY1OTkyMDUxMzE1MDEzRSszMzA2MSZxdW90OykKNjVUICAgNTMuOThzCigoVHJ1ZSwxMTI3OTcuOTg1MTg2OTQzMzIsNS44MjA3NjYwOTEzNDY3NDFlLTExKSwoMjYzNDksMjExNzcsMjI3NzYpLCZxdW90OzMuNzc1NTk3NjM3Njc2MzI5NEUrMzM5NTUmcXVvdDspCjY4VCAgIDU1Ljg4cwooKFRydWUsMTE0NTA3LjM0MjQxODA2MjEsNS44MjA3NjYwOTEzNDY3NDFlLTExKSwoMjgxNzksMTY1NTgsMjU4NzcpLCZxdW90OzEuMzk1Njc5Mzk0Mjc4NzU1RSszNDQ3MCZxdW90OykKNzBUICAgNTkuNTdzCigoVHJ1ZSwxMTU2MTkuMTU3NTQwODg4NDEsNS44MjA3NjYwOTEzNDY3NDFlLTExKSwoMTMxMjUsMTM2ODcsMzQ3OTkpLCZxdW90OzYuODMxMDQ3ODQwNTAyNjAyRSszNDgwNCZxdW90OykKCm9uIGhvbWUgbWFjaGluZToKMTAwVDogMzY4LjEzcyAgICAgbl4wLjcwOAooKFRydWUsMTMwMjE2LjE0MDg1NTE4NzI5LDUuODIwNzY2MDkxMzQ2NzQxZS0xMSksKDg4MzI0LDg3NiwxNzQ0NCksJnF1b3Q7OS4yMTExMDYzNjY0NDM1NjRFKzM5MTk4JnF1b3Q7KQoKMTQwVDogNDY2LjY5cyAgICAgbl4wLjcwNQooKFRydWUsMTQ1NjcxLjY0ODA0Njg1OTQ4LDUuODIwNzY2MDkxMzQ2NzQxZS0xMSksKDk5MTgsMjQwMDIsNDIwODIpLCZxdW90OzMuNDMyMjIxMDA2NTIyMjQ1RSs0Mzg1MSZxdW90OykKCjE3MFQ6IDM4My4yNnMgICAgIG5eMC4wNzYgICAtLS1GQVVMVFktLS0KKChGYWxzZSwxNTU0MTEuMjUwMTIwNTQzODIsMC4wKSwoNzcyMDEsMjc5ODAsMTQ1ODQpLCZxdW90OzIuODA1MDgxOTExNDc3NDIxNUUrNDY3ODMmcXVvdDspCi0tLS0tLQoKYyAgMC44NXMtOC4wTUIKYSAgMC44N3MtOC4wTUIgCgppcyBEb3VibGUgcHJlY2lzaW9uIGVub3VnaD8KMVQ6ICAgKDI4MDUyLjI5MjM0MTQ3NjAzNywyLjk4MzE0MjYyMTgxNTIwNWUtOSkgMTQgc2lnbmlmaWNhbnQgZGlnaXRzIG5lZWRlZC4gICBpZmZ5Li4uIGJ1dCBPSwoxMDBCOiAoMTMwMTkuNDA2MjEyODI0NjM5LDQuOTY0MDIyMDgyMjc2NjQyZS05KSAxNCBzaWduaWZpY2FudCBkaWdpdHMgbmVlZGVkLiAKMTBCOiAgICg2MDQxLjc1ODc4MjMwMjM4MywyLjI5MjY1NDI0NDIyOTE5OGUtOCkgMTIgc2lnbmlmaWNhbnQgZGlnaXRzIG5lZWRlZC4gCjFCOiAgICAoMjgwMy4wMjIxOTE2MTIzNzcsMS4zMjUxNzkyNTUyMTgyNDVlLTcpIDExIHNpZ25pZmljYW50IGRpZ2l0cyBuZWVkZWQuICAKCgoxVCAgICgxMTI2LDE2OTMwLCA0MCksICZxdW90OzMuODE0MzI1MDA1MDA3NzY1RSs4NDQ0JnF1b3Q7ICAgICAgICAgICAgKCBHWGg0UDAgMjAlIGZhc3RlciwgIAoxMDBCICgxMDE3OCwxMzg0LDI3OSksICZxdW90OzEuNzA1MDc1NDgyODc1MDQxRSszOTE5JnF1b3Q7ICAgICAgICAgICAgICAgIHdpdGggZXhwbGljaXQgbG9vcHMpCjEwQiAgKDIxNzcsICA4LCAxNjU5KSwgJnF1b3Q7NS42Mjk5OTIxODEwMTI4MTRFKzE4MTgmcXVvdDsgCjFCICAgKDEzMzQsIDMzNSwgNDA0KSwgJnF1b3Q7Ni4yMTYwNzU3NTU1NjU1OTBFKzg0MyZxdW90OyAgCjEwME0gKCAgMiwgIDQ1NCwgMjQ5KSwgJnF1b3Q7MS44MTQwMTQzMzA5NjEwMzJFKzM5MSZxdW90OwpfX19fCm9sZCAoMzItYml0KSBUSU1JTkdTLCB3aXRob3V0IHRoZSBpc1RydWx5U29ydGVkIGNhbGN1bGF0aW9uIHdoaWNoIHNsb3dlcyBpdCBkb3duIGJ5IH4yMCUgZm9yIDEwMEI6Ci0tLS0KICAgICAgICAgICAgIHRhcmdldCBpZHggICAgCiAgICAgICAgICAgICggIGZyb20gdG9wLGJhbmQgc2l6ZSApIAoxVCAgIDEzLjM5cy03LjlNQiAoODYwOSwyMjg3MikgICAzNy42MyUgICAgfiBuXjAuNjkgdGltZSwgbl4wLjMzIHNwYWNlCjEwMEIgIDIuNzRzLTYuOU1CICgzOTkzLDEwNjA5KSAgIDM3LjY0JSAgICAgICAgICAtLS0tLS0tLSAgICAobm8gdHdlYWs6IH4zLjJzOyB+MTc1LDAwMCBiYW5kIHNpemUpCjUwQiAgIDEuNjZzLTYuOU1CICgzMTY3LDg0MjEgKSAgIDM3LjYxJSAgICAgICAgICAgICB8CjEwQiAgIDAuNDlzLTUuOU1CICgxODU0LDQ5MjggKSAgIDM3LjYyJSAgICAgICAgICAgICBuXigxLzMpIC0tIGJhbmQgc2l6ZQoxQiAgICAwLjA1cy00LjlNQiAoIDg2MiwyMjg4ICkgICAzNy42NyUgICAgICAgICAgICAgfAoxMDBNICAwLjAxcy00LjlNQiAoIDM5OSwxMDYxICkgICAzNy42MSUgICAgICAgICAgLS0tLS0tLS0KMTBNICAgMC4wMHMtNC45TUIgKCAxODMsNDkyICApICAgMzcuMjAlIAo1TSAgICAwLjAwcy00LjlNQiAoIDE1MCwzOTEgICkgICAzOC4zNiUgICAgICggbm8gdHdlYWs6ICA1TSAwLTQuOSAgKDc0LDIzOCkgMC4zMTElICApCjFNICAgIDAuMDBzLTQuOU1CICggIDg2LDIzMSAgKSAgIDM3LjIzJSAgICAgKCBubyB0d2VhazogIDFNIDAtNC45ICAoMTIsNzkpICAwLjE1MTklICkKCgo=
1000000000000
to print the full value as well, uncomment one of the
`-- print (case t of (i,j,k) -> 2^i*3^j*5^k)`
lines in `main`, at its very end
------
2020-03-24: use `Int` in nthHam, now on 64 bit, for speed:
1B 0.02s 6.0MB
((True,2803.022191612378,1.325179255218245e-7),(1334,335,404),"6.216075755562335E+843")
1T 2.01s 15.1MB
((True,28052.292341476037,2.979504643008113e-9),(1126,16930,40),"3.814325005007765E+8444")
4T 5.81s 22.2MB 16 digits used....
still good (as evidenced by the `True` below), but really pushing it.
((True,44531.67942695671,7.275957614183426e-11),(16348,16503,873),"2.3509832704071347E+13405")
10T 11.13s 26.4MB
((True,60439.66391703062,7.275957614183426e-11),(18187,23771,1971),"1.4182592613214273E+18194")
13T 14.44s 30.4MB ...still good
((True,65963.64327239885,5.820766091346741e-11),(28648,21308,1526),"1.0845209980457384E+19857")
same code on tio:
10T 16.77s
35T 38.84s
((True,91766.48002166452,5.820766091346741e-11),(13824,2133,32112),"2.904528312044042E+27624")
60T 53.76s
((True,109828.1626252908,5.820766091346741e-11),(28123,45913,3848),"3.7265992051315013E+33061")
65T 53.98s
((True,112797.98518694332,5.820766091346741e-11),(26349,21177,22776),"3.7755976376763294E+33955")
68T 55.88s
((True,114507.3424180621,5.820766091346741e-11),(28179,16558,25877),"1.395679394278755E+34470")
70T 59.57s
((True,115619.15754088841,5.820766091346741e-11),(13125,13687,34799),"6.831047840502602E+34804")
on home machine:
100T: 368.13s n^0.708
((True,130216.14085518729,5.820766091346741e-11),(88324,876,17444),"9.211106366443564E+39198")
140T: 466.69s n^0.705
((True,145671.64804685948,5.820766091346741e-11),(9918,24002,42082),"3.432221006522245E+43851")
170T: 383.26s n^0.076 ---FAULTY---
((False,155411.25012054382,0.0),(77201,27980,14584),"2.8050819114774215E+46783")
------
c 0.85s-8.0MB
a 0.87s-8.0MB
is Double precision enough?
1T: (28052.292341476037,2.983142621815205e-9) 14 significant digits needed. iffy... but OK
100B: (13019.406212824639,4.964022082276642e-9) 14 significant digits needed.
10B: (6041.758782302383,2.292654244229198e-8) 12 significant digits needed.
1B: (2803.022191612377,1.325179255218245e-7) 11 significant digits needed.
1T (1126,16930, 40), "3.814325005007765E+8444" ( GXh4P0 20% faster,
100B (10178,1384,279), "1.705075482875041E+3919" with explicit loops)
10B (2177, 8, 1659), "5.629992181012814E+1818"
1B (1334, 335, 404), "6.216075755565590E+843"
100M ( 2, 454, 249), "1.814014330961032E+391"
____
old (32-bit) TIMINGS, without the isTrulySorted calculation which slowes it down by ~20% for 100B:
----
target idx
( from top,band size )
1T 13.39s-7.9MB (8609,22872) 37.63% ~ n^0.69 time, n^0.33 space
100B 2.74s-6.9MB (3993,10609) 37.64% -------- (no tweak: ~3.2s; ~175,000 band size)
50B 1.66s-6.9MB (3167,8421 ) 37.61% |
10B 0.49s-5.9MB (1854,4928 ) 37.62% n^(1/3) -- band size
1B 0.05s-4.9MB ( 862,2288 ) 37.67% |
100M 0.01s-4.9MB ( 399,1061 ) 37.61% --------
10M 0.00s-4.9MB ( 183,492 ) 37.20%
5M 0.00s-4.9MB ( 150,391 ) 38.36% ( no tweak: 5M 0-4.9 (74,238) 0.311% )
1M 0.00s-4.9MB ( 86,231 ) 37.23% ( no tweak: 1M 0-4.9 (12,79) 0.1519% )