experimental-pigeongo/internal/codec/lipmaa.go

76 lines
1.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package codec
// CalculateLipmaaLayerSequence calculates a set of nearest lipmaa
// layer natural indexes given the current layer, requested depth, and
// a starting set. It follows these basic math rules:
//
// Given:
// - N: N ∈ {0,1,2...}
// - l: l ∈ N
// - d: d ∈ N
// - x: I->X i|->floor(log(x))+1 = x(i)
// - s: s ⊊ {0,1,4,13,40...}
// - c: c ∈ s ∧ c = 0 (c >= 1 ∧ x(l,s))
// - v: v = (c*3)+1
func CalculateLipmaaLayerSequence(l, d uint, s []uint) []uint {
sl := uint(len(s))
// If the sequence set is empty make it equal to {0}
if sl == 0 {
s = append(s, 0) // Add the base value 0
sl++ // Increment the sequence set length counter
}
// Calculate v based on the last value in the sequence set
c := s[sl-1]
v := (c * 3) + 1
// If the length of the sequence set is less than the layer we are on
if sl < l {
l = sl // Make the layer equal to the sequence set length
s = s[:l] // Take only a valid set of sequences for the layer
}
// If the layer is equal to the requested depth
if l == d {
return s // Return the generated sequeces
}
// Expand the sequence set and layer
s = append(s, v)
l++
// Calculate the next layer
return CalculateLipmaaLayerSequence(l, d, s)
}
// lipmaaLink returns the lipmaa link index from a given index
func lipmaaLink(idx uint) uint {
if idx == 0 {
return 0
}
n := int(idx)
k, po3, x := 1, 3, n
for {
if k >= n {
break
}
po3 *= 3
k = (po3 - 1) / 2
}
po3 /= 3
if k != n {
for {
if x == 0 {
break
}
k = (po3 - 1) / 2
po3 /= 3
x %= k
}
if k != po3 {
po3 = k
}
}
return uint(n - po3)
}
func lipmaaLink2(idx uint) uint {
return idx
}