Data update

This commit is contained in:
Ingy döt Net 2026-02-01 16:33:20 -08:00
parent 5150844a7d
commit 4bb20c9b71
7735 changed files with 38060 additions and 199180 deletions

View file

@ -1,61 +1,61 @@
from collections.vector import (DynamicVector, CollectionElement)
from math import (log2, trunc, pow)
from memory import memset_zero #, memcpy)
from time import now
# HammingsLogImp.mojo - uses queue instead of frequent draining...
# compile with: mojo build --march=native Hammings.mojo
# import bigints, std/math # no big ints
from math import (log2, trunc)
from memory import (memset_zero) #, memcpy)
from time import (monotonic)
alias cCOUNT: Int = 1_000_000
struct BigNat(Stringable): # enough just to support conversion and printing
struct BigNat(Movable, ImplicitlyCopyable, Stringable): # enough just to support conversion and printing
''' Enough "infinite" precision to support as required here - multiply and
divide by 10 conversion to string...
'''
var contents: DynamicVector[UInt32]
fn __init__(inout self):
self.contents = DynamicVector[UInt32]()
fn __init__(inout self, val: UInt32):
self.contents = DynamicVector[UInt32](4)
self.contents.resize(1, val)
fn __copyinit__(inout self, existing: Self):
self.contents = existing.contents
fn __moveinit__(inout self, owned existing: Self):
self.contents = existing.contents^
var contents: List[UInt32]
fn __init__(out self):
self.contents = List[UInt32]()
fn __init__(out self, val: UInt32):
self.contents = List[UInt32](length=1, fill=val)
fn __copyinit__(out self, existing: Self):
self.contents = List[UInt32](existing.contents)
fn __str__(self) -> String:
var rslt: String = ""
var v = self.contents
var v = List[UInt32](self.contents)
while len(v) > 0:
var t: UInt64 = 0
for i in range(len(v) - 1, -1, -1):
t = ((t << 32) + v[i].to_int())
v[i] = (t // 10).to_int(); t -= v[i].to_int() * 10
t = (t << 32) + Int(v[i])
v[i] = Int(t // 10); t -= Int(v[i]) * 10
var sz = len(v) - 1
while sz >= 0 and v[sz] == 0: sz -= 1
v.resize(sz + 1, 0)
rslt = str(t) + rslt
rslt = String(t) + rslt
return rslt
fn mult(inout self, mltplr: Self):
var rslt = DynamicVector[UInt32]()
rslt.resize(len(self.contents) + len(mltplr.contents), 0)
for i in range(len(mltplr.contents)):
fn __imul__(mut self, rhs: Self):
var lenl = len(self.contents); var lenr = len(rhs.contents)
var rslt = List[UInt32](length = lenl + lenr, fill = 0)
for i in range(lenr):
var t: UInt64 = 0
for j in range(len(self.contents)):
t += self.contents[j].to_int() * mltplr.contents[i].to_int() + rslt[i + j].to_int()
rslt[i + j] = (t & 0xFFFFFFFF).to_int(); t >>= 32
rslt[i + len(self.contents)] += t.to_int()
for j in range(lenl):
t += Int(self.contents[j]) * Int(rhs.contents[i]) + Int(rslt[i + j])
rslt[i + j] = Int(t & 0xFFFFFFFF); t >>= 32
rslt[i + lenl] += Int(t)
var sz = len(rslt) - 1
while sz >= 0 and rslt[sz] == 0: sz -= 1
rslt.resize(sz + 1, 0); self.contents = rslt
rslt.resize(sz + 1, 0); self.contents = rslt^
alias lb2: Float64 = 1.0
alias lb3: Float64 = log2[DType.float64, 1](3.0)
alias lb5: Float64 = log2[DType.float64, 1](5.0)
alias lb3: Float64 = log2(Float64(3.0))
alias lb5: Float64 = log2(Float64(5.0))
@value
struct LogRep(CollectionElement, Stringable):
@fieldwise_init
struct LogRep(ImplicitlyCopyable, Movable, Stringable):
var logrep: Float64
var x2: UInt32
var x3: UInt32
var x5: UInt32
fn __del__(owned self): return
fn __del__(deinit self): return
@always_inline
fn mul2(self) -> Self:
return LogRep(self.logrep + lb2, self.x2 + 1, self.x3, self.x5)
@ -66,91 +66,122 @@ struct LogRep(CollectionElement, Stringable):
fn mul5(self) -> Self:
return LogRep(self.logrep + lb5, self.x2, self.x3, self.x5 + 1)
fn __str__(self) -> String:
# return "( " + String(self.x2) + ", " + String(self.x3) + ", " + String(self.x5) + " )"
var rslt = BigNat(1)
fn expnd(inout rslt: BigNat, bs: UInt32, n: UInt32):
fn expnd(mut rslt: BigNat, bs: UInt32, n: UInt32):
var bsm = BigNat(bs); var nm = n
while nm > 0:
if (nm & 1) != 0: rslt.mult(bsm)
bsm.mult(bsm); nm >>= 1
if (nm & 1) != 0: rslt *= bsm
tmp = bsm; bsm *= tmp; nm >>= 1
expnd(rslt, 2, self.x2); expnd(rslt, 3, self.x3); expnd(rslt, 5, self.x5)
return str(rslt)
return String(rslt)
alias oneLR: LogRep = LogRep(0.0, 0, 0, 0)
alias LogRepThunk = fn() escaping -> LogRep
fn hammingsLogImp() -> LogRepThunk:
var s2 = DynamicVector[LogRep](); var s3 = DynamicVector[LogRep](); var s5 = oneLR; var mrg = oneLR
s2.resize(512, oneLR); s2[0] = oneLR.mul2(); s3.resize(1, oneLR); s3[0] = oneLR.mul3()
# var s2p = s2.steal_data(); var s3p = s3.steal_data()
var s2hdi = 0; var s2tli = -1; var s3hdi = 0; var s3tli = -1
@always_inline
fn next() escaping -> LogRep:
var rslt = s2[s2hdi]
var s2len = len(s2)
s2tli += 1;
if s2tli >= s2len:
s2tli = 0
if s2hdi == s2tli:
# Since an escaping closure doesn't currently move even for last used captures, and
# List's can't be copied into closures, we could write a minimal List to do the job, or
# probably easier is to just use a Mojo Iterator struct....
struct _HammingsLogImpIter(ImplicitlyCopyable, Movable, Iterator):
alias __copyinit__is_trivial = False
alias __moveinit__is_trivial = False
alias __del__is_trivial = False
alias Element = LogRep
var s2: List[LogRep]; var s3: List[LogRep]; var s5: LogRep; var mrg: LogRep
# var s2p: UnsafePointer[LogRep]; var s3p: UnsafePointer[LogRep]
var s2hdi: Int; var s2tli: Int; var s3hdi: Int; var s3tli: Int
fn __init__(out self: Self):
self.s2 = List[LogRep](length=512, fill=oneLR); self.s2[0] = oneLR.mul2()
self.s3 = List[LogRep](length=1, fill=oneLR); self.s3[0] = oneLR.mul3()
self.s5 = oneLR.mul5(); self.mrg = oneLR
# self.s2p = self.s2.steal_data(); self.s3p = self.s3.steal_data()
self.s2hdi = 0; self.s2tli = -1; self.s3hdi = 0; self.s3tli = -1
fn __copyinit__(out self: Self, existing: Self, /):
self.s2 = existing.s2.copy(); self.s3 = existing.s3.copy()
self.s5 = existing.s5; self.mrg = existing.mrg
# self.s2p = existing.s2p; self.s3p = existing.s3p
self.s2hdi = existing.s2hdi; self.s2tli = existing.s2tli
self.s3hdi = existing.s3hdi; self.s3tli = existing.s3tli
# fn __moveinit__(out self: Self, var existing: Self, /):
# self = existing^
fn __has_next__(self: Self) -> Bool:
return True # "infinite" series!
fn __next__(mut self: Self) -> Self.Element:
var rslt = self.s2.unsafe_get(self.s2hdi)
var s2len = len(self.s2)
self.s2tli += 1;
if self.s2tli >= s2len:
self.s2tli = 0
if self.s2hdi == self.s2tli:
if s2len < 1024:
s2.resize(1024, oneLR)
self.s2.resize(1024, oneLR) # ; self.s2p = self.s2.steal_data()
else:
s2.resize(s2len + s2len, oneLR) # ; s2p = s2.steal_data()
for i in range(s2hdi):
s2[s2len + i] = s2[i]
self.s2.resize(s2len + s2len, oneLR) # ; self.s2p = self.s2.steal_data()
for i in range(self.s2hdi):
self.s2.unsafe_set(s2len + i, self.s2.unsafe_get(i))
# memcpy[UInt8, 0](s2p + s2len, s2p, sizeof[LogRep]() * s2hdi)
s2tli += s2len; s2len += s2len
if rslt.logrep < mrg.logrep:
s2hdi += 1
if s2hdi >= s2len:
s2hdi = 0
self.s2tli += s2len; s2len += s2len
if rslt.logrep < self.mrg.logrep:
self.s2hdi += 1
if self.s2hdi >= s2len:
self.s2hdi = 0
else:
rslt = mrg
var s3len = len(s3)
s3tli += 1;
if s3tli >= s3len:
s3tli = 0
if s3hdi == s3tli:
rslt = self.mrg
var s3len = len(self.s3)
self.s3tli += 1;
if self.s3tli >= s3len:
self.s3tli = 0
if self.s3hdi == self.s3tli:
if s3len < 1024:
s3.resize(1024, oneLR)
self.s3.resize(1024, oneLR) # ; self.s3p = self.s3.steal_data()
else:
s3.resize(s3len + s3len, oneLR) # ; s3p = s3.steal_data()
for i in range(s3hdi):
s3[s3len + i] = s3[i]
self.s3.resize(s3len + s3len, oneLR) # ; self.s3p = self.s3.steal_data()
for i in range(self.s3hdi):
self.s3.unsafe_set(s3len + i, self.s3.unsafe_get(i))
# memcpy[UInt8, 0](s3p + s3len, s3p, sizeof[LogRep]() * s3hdi)
s3tli += s3len; s3len += s3len
if mrg.logrep < s5.logrep:
s3hdi += 1
if s3hdi >= s3len:
s3hdi = 0
self.s3tli += s3len; s3len += s3len
if self.mrg.logrep < self.s5.logrep:
self.s3hdi += 1
if self.s3hdi >= s3len:
self.s3hdi = 0
else:
s5 = s5.mul5()
s3[s3tli] = rslt.mul3(); let t = s3[s3hdi];
mrg = t if t.logrep < s5.logrep else s5
s2[s2tli] = rslt.mul2(); return rslt
return next
self.s5 = self.s5.mul5()
self.s3[self.s3tli] = rslt.mul3(); var t = self.s3[self.s3hdi];
self.mrg = t if t.logrep < self.s5.logrep else self.s5
self.s2.unsafe_set(self.s2tli, rslt.mul2()); return rslt
@fieldwise_init
struct HammingsLogImp(ImplicitlyCopyable, Movable, Iterable):
alias __del__is_trivial = True
alias IteratorType[
iterable_mut: Bool, //, iterable_origin: Origin[iterable_mut]
]: Iterator = _HammingsLogImpIter
fn __iter__(ref self: Self) -> _HammingsLogImpIter:
return _HammingsLogImpIter()
fn main():
print("The first 20 Hamming numbers are:")
var f = hammingsLogImp();
for i in range(20): print_no_newline(f(), " ")
for i, h in enumerate(HammingsLogImp()):
print(String(h) + " ", end='')
if i >= 19: break
print()
f = hammingsLogImp(); var h: LogRep = oneLR
for i in range(1691): h = f()
print("The 1691st Hamming number is", h)
let strt: Int = now()
f = hammingsLogImp()
for i in range(cCOUNT): h = f()
let elpsd = (now() - strt) / 1000
for i, h in enumerate(HammingsLogImp()):
if i >= 1691 - 1: print("The 1691st Hamming number is " + String(h)); break
var strt: Int = monotonic()
var ham = oneLR
for i, h in enumerate(HammingsLogImp()):
if i >= cCOUNT - 1: ham = h; break
var elpsd = (monotonic() - strt) / 1000
print("The " + str(cCOUNT) + "th Hamming number is:")
print("2**" + str(h.x2) + " * 3**" + str(h.x3) + " * 5**" + str(h.x5))
let lg2 = lb2 * Float64(h.x2.to_int()) + lb3 * Float64(h.x3.to_int()) + lb5 * Float64(h.x5.to_int())
let lg10 = lg2 / log2(Float64(10))
let expnt = trunc(lg10); let num = pow(Float64(10.0), lg10 - expnt)
let apprxstr = str(num) + "E+" + str(expnt.to_int())
print("The " + String(cCOUNT) + "th Hamming number is:")
print("2**" + String(ham.x2) + " * 3**" + String(ham.x3) + " * 5**" + String(ham.x5))
var lg2 = lb2 * Float64(Int(ham.x2)) + lb3 * Float64(Int(ham.x3)) + lb5 * Float64(Int(ham.x5))
var lg10 = lg2 / log2(Float64(10))
var expnt = trunc(lg10); var num = Float64(10.0)**(lg10 - expnt)
var apprxstr = String(num) + "E+" + String(Int(expnt))
print("Approximately: ", apprxstr)
let answrstr = str(h)
var answrstr = String(ham)
print("The result has", len(answrstr), "digits.")
print(answrstr)
print("This took " + str(elpsd) + " microseconds.")
print("This took " + String(elpsd) + " microseconds.")