Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
184
Task/Zeckendorf-arithmetic/Go/zeckendorf-arithmetic.go
Normal file
184
Task/Zeckendorf-arithmetic/Go/zeckendorf-arithmetic.go
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
dig = [3]string{"00", "01", "10"}
|
||||
dig1 = [3]string{"", "1", "10"}
|
||||
)
|
||||
|
||||
type Zeckendorf struct{ dVal, dLen int }
|
||||
|
||||
func NewZeck(x string) *Zeckendorf {
|
||||
z := new(Zeckendorf)
|
||||
if x == "" {
|
||||
x = "0"
|
||||
}
|
||||
q := 1
|
||||
i := len(x) - 1
|
||||
z.dLen = i / 2
|
||||
for ; i >= 0; i-- {
|
||||
z.dVal += int(x[i]-'0') * q
|
||||
q *= 2
|
||||
}
|
||||
return z
|
||||
}
|
||||
|
||||
func (z *Zeckendorf) a(i int) {
|
||||
for ; ; i++ {
|
||||
if z.dLen < i {
|
||||
z.dLen = i
|
||||
}
|
||||
j := (z.dVal >> uint(i*2)) & 3
|
||||
switch j {
|
||||
case 0, 1:
|
||||
return
|
||||
case 2:
|
||||
if ((z.dVal >> (uint(i+1) * 2)) & 1) != 1 {
|
||||
return
|
||||
}
|
||||
z.dVal += 1 << uint(i*2+1)
|
||||
return
|
||||
case 3:
|
||||
z.dVal &= ^(3 << uint(i*2))
|
||||
z.b((i + 1) * 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (z *Zeckendorf) b(pos int) {
|
||||
if pos == 0 {
|
||||
z.Inc()
|
||||
return
|
||||
}
|
||||
if ((z.dVal >> uint(pos)) & 1) == 0 {
|
||||
z.dVal += 1 << uint(pos)
|
||||
z.a(pos / 2)
|
||||
if pos > 1 {
|
||||
z.a(pos/2 - 1)
|
||||
}
|
||||
} else {
|
||||
z.dVal &= ^(1 << uint(pos))
|
||||
z.b(pos + 1)
|
||||
temp := 1
|
||||
if pos > 1 {
|
||||
temp = 2
|
||||
}
|
||||
z.b(pos - temp)
|
||||
}
|
||||
}
|
||||
|
||||
func (z *Zeckendorf) c(pos int) {
|
||||
if ((z.dVal >> uint(pos)) & 1) == 1 {
|
||||
z.dVal &= ^(1 << uint(pos))
|
||||
return
|
||||
}
|
||||
z.c(pos + 1)
|
||||
if pos > 0 {
|
||||
z.b(pos - 1)
|
||||
} else {
|
||||
z.Inc()
|
||||
}
|
||||
}
|
||||
|
||||
func (z *Zeckendorf) Inc() {
|
||||
z.dVal++
|
||||
z.a(0)
|
||||
}
|
||||
|
||||
func (z1 *Zeckendorf) PlusAssign(z2 *Zeckendorf) {
|
||||
for gn := 0; gn < (z2.dLen+1)*2; gn++ {
|
||||
if ((z2.dVal >> uint(gn)) & 1) == 1 {
|
||||
z1.b(gn)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (z1 *Zeckendorf) MinusAssign(z2 *Zeckendorf) {
|
||||
for gn := 0; gn < (z2.dLen+1)*2; gn++ {
|
||||
if ((z2.dVal >> uint(gn)) & 1) == 1 {
|
||||
z1.c(gn)
|
||||
}
|
||||
}
|
||||
|
||||
for z1.dLen > 0 && ((z1.dVal>>uint(z1.dLen*2))&3) == 0 {
|
||||
z1.dLen--
|
||||
}
|
||||
}
|
||||
|
||||
func (z1 *Zeckendorf) TimesAssign(z2 *Zeckendorf) {
|
||||
na := z2.Copy()
|
||||
nb := z2.Copy()
|
||||
nr := new(Zeckendorf)
|
||||
for i := 0; i <= (z1.dLen+1)*2; i++ {
|
||||
if ((z1.dVal >> uint(i)) & 1) > 0 {
|
||||
nr.PlusAssign(nb)
|
||||
}
|
||||
nt := nb.Copy()
|
||||
nb.PlusAssign(na)
|
||||
na = nt.Copy()
|
||||
}
|
||||
z1.dVal = nr.dVal
|
||||
z1.dLen = nr.dLen
|
||||
}
|
||||
|
||||
func (z *Zeckendorf) Copy() *Zeckendorf {
|
||||
return &Zeckendorf{z.dVal, z.dLen}
|
||||
}
|
||||
|
||||
func (z1 *Zeckendorf) Compare(z2 *Zeckendorf) int {
|
||||
switch {
|
||||
case z1.dVal < z2.dVal:
|
||||
return -1
|
||||
case z1.dVal > z2.dVal:
|
||||
return 1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (z *Zeckendorf) String() string {
|
||||
if z.dVal == 0 {
|
||||
return "0"
|
||||
}
|
||||
var sb strings.Builder
|
||||
sb.WriteString(dig1[(z.dVal>>uint(z.dLen*2))&3])
|
||||
for i := z.dLen - 1; i >= 0; i-- {
|
||||
sb.WriteString(dig[(z.dVal>>uint(i*2))&3])
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("Addition:")
|
||||
g := NewZeck("10")
|
||||
g.PlusAssign(NewZeck("10"))
|
||||
fmt.Println(g)
|
||||
g.PlusAssign(NewZeck("10"))
|
||||
fmt.Println(g)
|
||||
g.PlusAssign(NewZeck("1001"))
|
||||
fmt.Println(g)
|
||||
g.PlusAssign(NewZeck("1000"))
|
||||
fmt.Println(g)
|
||||
g.PlusAssign(NewZeck("10101"))
|
||||
fmt.Println(g)
|
||||
|
||||
fmt.Println("\nSubtraction:")
|
||||
g = NewZeck("1000")
|
||||
g.MinusAssign(NewZeck("101"))
|
||||
fmt.Println(g)
|
||||
g = NewZeck("10101010")
|
||||
g.MinusAssign(NewZeck("1010101"))
|
||||
fmt.Println(g)
|
||||
|
||||
fmt.Println("\nMultiplication:")
|
||||
g = NewZeck("1001")
|
||||
g.TimesAssign(NewZeck("101"))
|
||||
fmt.Println(g)
|
||||
g = NewZeck("101010")
|
||||
g.PlusAssign(NewZeck("101"))
|
||||
fmt.Println(g)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue