Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
25
Task/Hamming-numbers/F-Sharp/hamming-numbers-1.fs
Normal file
25
Task/Hamming-numbers/F-Sharp/hamming-numbers-1.fs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
type LazyList<'a> = Cons of 'a * Lazy<LazyList<'a>>
|
||||
|
||||
let rec hammings() =
|
||||
let rec (-|-) (Cons(x, nxf) as xs) (Cons(y, nyf) as ys) =
|
||||
if x < y then Cons(x, lazy(nxf.Value -|- ys))
|
||||
elif x > y then Cons(y, lazy(xs -|- nyf.Value))
|
||||
else Cons(x, lazy(nxf.Value -|- nyf.Value))
|
||||
let rec inf_map f (Cons(x, nxf)) =
|
||||
Cons(f x, lazy(inf_map f nxf.Value))
|
||||
Cons(1I, lazy(let x = inf_map ((*) 2I) hamming
|
||||
let y = inf_map ((*) 3I) hamming
|
||||
let z = inf_map ((*) 5I) hamming
|
||||
x -|- y -|- z))
|
||||
|
||||
// testing...
|
||||
[<EntryPoint>]
|
||||
let main args =
|
||||
let rec iterLazyListFor f n (Cons(v, rf)) =
|
||||
if n > 0 then f v; iterLazyListFor f (n - 1) rf.Value
|
||||
let rec nthLazyList n ((Cons(v, rf)) as ll) =
|
||||
if n <= 1 then v else nthLazyList (n - 1) rf.Value
|
||||
printf "( "; iterLazyListFor (printf "%A ") 20 (hammings()); printfn ")"
|
||||
printfn "%A" (hammings() |> nthLazyList 1691)
|
||||
printfn "%A" (hammings() |> nthLazyList 1000000)
|
||||
0
|
||||
30
Task/Hamming-numbers/F-Sharp/hamming-numbers-2.fs
Normal file
30
Task/Hamming-numbers/F-Sharp/hamming-numbers-2.fs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
let cNUMVALS = 1000000
|
||||
|
||||
type LazyList<'a> = Cons of 'a * Lazy<LazyList<'a>>
|
||||
|
||||
let hammings() =
|
||||
let rec merge (Cons(x, f) as xs) (Cons(y, g) as ys) =
|
||||
if x < y then Cons(x, lazy(merge (f.Force()) ys))
|
||||
else Cons(y, lazy(merge xs (g.Force())))
|
||||
let rec smult m (Cons(x, rxs)) =
|
||||
Cons(m * x, lazy(smult m (rxs.Force())))
|
||||
let rec first = smult 5I (Cons(1I, lazy first))
|
||||
let u s n =
|
||||
let rec r = merge s (smult n (Cons(1I, lazy r))) in r
|
||||
Seq.unfold (fun (Cons(hd, rst)) -> Some (hd, rst.Value))
|
||||
(Cons(1I, lazy(Seq.fold u first [| 3I; 2I |])))
|
||||
|
||||
[<EntryPoint>]
|
||||
let main argv =
|
||||
printf "( "; hammings() |> Seq.take 20 |> Seq.iter (printf "%A "); printfn ")"
|
||||
printfn "%A" (hammings() |> Seq.item (1691 - 1))
|
||||
let strt = System.DateTime.Now.Ticks
|
||||
|
||||
let rslt = (hammings()) |> Seq.item (cNUMVALS - 1)
|
||||
|
||||
let stop = System.DateTime.Now.Ticks
|
||||
|
||||
printfn "%A" rslt
|
||||
printfn "Found this last up to %d in %d milliseconds." cNUMVALS ((stop - strt) / 10000L)
|
||||
|
||||
0 // return an integer exit code
|
||||
58
Task/Hamming-numbers/F-Sharp/hamming-numbers-3.fs
Normal file
58
Task/Hamming-numbers/F-Sharp/hamming-numbers-3.fs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
let cCOUNT = 1000000
|
||||
|
||||
type LogRep = struct val lr: double; val x2: uint32; val x3: uint32; val x5: uint32
|
||||
new(lr, x2, x3, x5) = {lr = lr; x2 = x2; x3 = x3; x5 = x5 } end
|
||||
let one: LogRep = LogRep(0.0, 0u, 0u, 0u)
|
||||
let lg2_2: double = 1.0
|
||||
let lg3_2: double = log 3.0 / log 2.0
|
||||
let lg5_2: double = log 5.0 / log 2.0
|
||||
let inline mul2 (lr: LogRep): LogRep = LogRep(lr.lr + lg2_2, lr.x2 + 1u, lr.x3, lr.x5)
|
||||
let inline mul3 (lr: LogRep): LogRep = LogRep(lr.lr + lg3_2, lr.x2, lr.x3 + 1u, lr.x5)
|
||||
let inline mul5 (lr: LogRep): LogRep = LogRep(lr.lr + lg5_2, lr.x2, lr.x3, lr.x5 + 1u)
|
||||
|
||||
let hammingsLog() = // imperative arrays, eliminates the BigInteger operations...
|
||||
let s2 = ResizeArray<_>() in let s3 = ResizeArray<_>()
|
||||
s2.Add(one); s3.Add(mul3 one)
|
||||
let mutable s5 = mul5 one in let mutable mrg = mul3 one
|
||||
let mutable s2hdi = 0 in let mutable s3hdi = 0
|
||||
let next() = // imperative next function to advance value
|
||||
if s2hdi + s2hdi >= s2.Count then s2.RemoveRange(0, s2hdi); s2hdi <- 0
|
||||
let mutable rslt: LogRep = s2.[s2hdi]
|
||||
if rslt.lr < mrg.lr then s2.Add(mul2 rslt); s2hdi <- s2hdi + 1
|
||||
else
|
||||
if s3hdi + s3hdi >= s3.Count then s3.RemoveRange(0, s3hdi); s3hdi <- 0
|
||||
rslt <- mrg; s2.Add(mul2 rslt); s3.Add(mul3 rslt); s3hdi <- s3hdi + 1
|
||||
let chkv: LogRep = s3.[s3hdi]
|
||||
if chkv.lr < s5.lr then mrg <- chkv
|
||||
else mrg <- s5; s5 <- mul5 s5; s3hdi <- s3hdi - 1
|
||||
rslt
|
||||
next
|
||||
|
||||
let hl2Seq f = Seq.unfold (fun v -> Some(v, f())) (f())
|
||||
let nthLogHamming n f =
|
||||
let rec nxt i = if i >= n then f() else f() |> ignore; nxt (i + 1) in nxt 0
|
||||
|
||||
let lr2BigInt (lr: LogRep) = // convert trival to BigInteger
|
||||
let rec xpnd n mlt rslt =
|
||||
if n <= 0u then rslt
|
||||
else xpnd (n - 1u) mlt (mlt * rslt)
|
||||
xpnd lr.x2 2I 1I |> xpnd lr.x3 3I |> xpnd lr.x5 5I
|
||||
|
||||
[<EntryPoint>]
|
||||
let main argv =
|
||||
printf "( "; hammingsLog() |> hl2Seq |> Seq.take 20
|
||||
|> Seq.iter (printf "%A " << lr2BigInt); printfn ")"
|
||||
printfn "%A" (hammingsLog() |> hl2Seq |> Seq.item (1691 - 1) |> lr2BigInt)
|
||||
let strt = System.DateTime.Now.Ticks
|
||||
// slow way using Seq:
|
||||
// let rslt = (hammingsLog()) |> hl2Seq |> Seq.item (1000000 - 1)
|
||||
// fast way using closure directly:
|
||||
let rslt = (hammingsLog()) |> nthLogHamming (1000000 - 1)
|
||||
|
||||
let stop = System.DateTime.Now.Ticks
|
||||
|
||||
printfn "%A" (rslt |> lr2BigInt)
|
||||
printfn "Found this last up to %d in %d milliseconds." cCOUNT ((stop - strt) / 10000L)
|
||||
|
||||
printfn ""
|
||||
0 // return an integer exit code
|
||||
62
Task/Hamming-numbers/F-Sharp/hamming-numbers-4.fs
Normal file
62
Task/Hamming-numbers/F-Sharp/hamming-numbers-4.fs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
let nthHamming n =
|
||||
if n < 1UL then failwith "nthHamming; argument must be > 0!"
|
||||
if n < 2UL then 0u, 0u, 0u else // trivial case for first value of one
|
||||
let lb3 = 1.5849625007211561814537389439478 // Math.Log(3) / Math.Log(2);
|
||||
let lb5 = 2.3219280948873623478703194294894 // Math.Log(5) / Math.Log(2);
|
||||
let fctr = 6.0 * lb3 * lb5
|
||||
let crctn = 2.4534452978042592646620291867186 // Math.Log(Math.sqrt(30.0)) / Math.Log(2.0)
|
||||
let lbest = (fctr * double n) ** (1.0/3.0) - crctn // from WP formula
|
||||
let lbhi = lbest + 1.0 / lbest
|
||||
let lblo = 2.0 * lbest - lbhi // upper and lower bound of upper "band"
|
||||
let klmt = uint32 (lbhi / lb5)
|
||||
let rec loopk k kcnt kbnd =
|
||||
if k > klmt then kcnt, kbnd else
|
||||
let p = lbhi - double k * lb5
|
||||
let jlmt = uint32 (p / lb3)
|
||||
let rec loopj j jcnt jbnd =
|
||||
if j > jlmt then loopk (k + 1u) jcnt jbnd else
|
||||
let q = p - double j * lb3
|
||||
let i = uint32 q
|
||||
let lg = lbhi - q + double i // current log 2 value (estimated)
|
||||
let nbnd = if lg >= lblo then (lg, (uint32 i, j, k)) :: jbnd else jbnd
|
||||
loopj (j + 1u) (jcnt + uint64 i + 1UL) nbnd in loopj 0u kcnt kbnd
|
||||
let count, bnd = loopk 0u 0UL [] // 64-bit value so doesn't overflow
|
||||
if n > count then failwith "nthHamming: band high estimate is too low!"
|
||||
let ndx = int (count - n)
|
||||
if ndx >= bnd.Length then failwith "NthHamming.findNth: band low estimate is too high!"
|
||||
let sbnd = bnd |> List.sortBy (fun (lg, _) -> -lg) // sort in decending order
|
||||
let _, rslt = sbnd.[ndx]
|
||||
rslt
|
||||
|
||||
[<EntryPoint>]
|
||||
let main argv =
|
||||
let topNum = 1000000UL
|
||||
printf "( "; {1..20} |> Seq.iter (printf "%A " << trival << nthHamming << uint64); printfn ")"
|
||||
printfn "%A" (nthHamming 1691UL |> trival)
|
||||
let rslt = nthHammingx topNum
|
||||
let strt = System.DateTime.Now.Ticks
|
||||
|
||||
let rslt = nthHamming topNum
|
||||
|
||||
let stop = System.DateTime.Now.Ticks
|
||||
|
||||
let x2, x3, x5 = rslt
|
||||
printfn "2**%A times 3**%A times 5**%A" x2 x3 x5
|
||||
let lgrthm = log10 2.0 * (double x2 + (double x3 * log 3.0 + double x5 * log 5.0) / log 2.0)
|
||||
let exp = floor lgrthm |> int
|
||||
let mntsa = 10.0 ** (lgrthm - double exp)
|
||||
printfn "Approximately %AE+%A" mntsa exp
|
||||
let s = trival rslt |> string
|
||||
let lngth = s.Length
|
||||
printfn "Digits: %A" lngth
|
||||
if lngth <= 10000 then
|
||||
{0..100..lngth-1}
|
||||
|> Seq.iter (fun i ->
|
||||
printfn "%s" (s.Substring(i, if i + 100 < lngth then 100 else lngth - i)))
|
||||
|
||||
printfn "\r\nFound this last up to %A in %A milliseconds." topNum ((stop - strt) / 10000L)
|
||||
|
||||
printf "\r\nPress any key to exit:"
|
||||
System.Console.ReadKey(true) |> ignore
|
||||
printfn ""
|
||||
0 // return an integer exit code
|
||||
34
Task/Hamming-numbers/F-Sharp/hamming-numbers-5.fs
Normal file
34
Task/Hamming-numbers/F-Sharp/hamming-numbers-5.fs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
let nthHamming n =
|
||||
if n < 1UL then failwith "nthHamming: argument must be > 0!"
|
||||
if n < 2UL then 0u, 0u, 0u else // trivial case for first value of one
|
||||
let lb3 = 1.5849625007211561814537389439478 // Math.Log(3) / Math.Log(2);
|
||||
let lb5 = 2.3219280948873623478703194294894 // Math.Log(5) / Math.Log(2);
|
||||
let fctr = 6.0 * lb3 * lb5
|
||||
let crctn = 2.4534452978042592646620291867186 // Math.Log(Math.sqrt(30.0)) / Math.Log(2.0)
|
||||
let lbest = (fctr * double n) ** (1.0/3.0) - crctn // from WP formula
|
||||
let lbhi = lbest + 1.0/lbest
|
||||
let lblo = 2.0 * lbest - lbhi // upper and lower bound of upper "band"
|
||||
let bglb2 = 1267650600228229401496703205376I
|
||||
let bglb3 = 2009178665378409109047848542368I
|
||||
let bglb5 = 2943393543170754072109742145491I
|
||||
let klmt = uint32 (lbhi / lb5)
|
||||
let rec loopk k kcnt kbnd =
|
||||
if k > klmt then kcnt, kbnd else
|
||||
let p = lbhi - double k * lb5
|
||||
let jlmt = uint32 (p / lb3)
|
||||
let rec loopj j jcnt jbnd =
|
||||
if j > jlmt then loopk (k + 1u) jcnt jbnd else
|
||||
let q = p - double j * lb3
|
||||
let i = uint32 q
|
||||
let lg = lbhi - q + double i // current log 2 value (estimated)
|
||||
let nbnd = if lg < lblo then jbnd else
|
||||
let bglg = bglb2 * bigint i + bglb3 * bigint j + bglb5 * bigint k in
|
||||
(bglg, (uint32 i, j, k)) :: jbnd
|
||||
loopj (j + 1u) (jcnt + uint64 i + 1UL) nbnd in loopj 0u kcnt kbnd
|
||||
let count, bnd = loopk 0u 0UL [] // 64-bit value so doesn't overflow
|
||||
if n > count then failwith "nthHamming: band high estimate is too low!"
|
||||
let ndx = int (count - n)
|
||||
if ndx >= bnd.Length then failwith "NthHamming.findNth: band low estimate is too high!"
|
||||
let sbnd = bnd |> List.sortBy (fun (lg, _) -> -lg) // sort in decending order
|
||||
let _, rslt = sbnd.[ndx]
|
||||
rslt
|
||||
Loading…
Add table
Add a link
Reference in a new issue