Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View 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

View 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

View 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

View 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

View 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