September Morn Update
This commit is contained in:
parent
4e2d22a71d
commit
aac6731f2c
6856 changed files with 141342 additions and 21127 deletions
|
|
@ -1,239 +1,254 @@
|
|||
import extensions.
|
||||
import extensions;
|
||||
|
||||
const dig = ("00","01","10").
|
||||
const dig1 = ("","1","10").
|
||||
const dig = new string[]{"00","01","10"};
|
||||
const dig1 = new string[]{"","1","10"};
|
||||
|
||||
sealed struct ZeckendorfNumber :: BaseNumber
|
||||
sealed struct ZeckendorfNumber
|
||||
{
|
||||
int dVal.
|
||||
int dLen.
|
||||
int dVal;
|
||||
int dLen;
|
||||
|
||||
clone
|
||||
= ZeckendorfNumber $new(dVal,dLen).
|
||||
clone()
|
||||
= ZeckendorfNumber.newInternal(dVal,dLen);
|
||||
|
||||
stacksafe explicit n(LiteralValue s)
|
||||
[
|
||||
int i := s length - 1.
|
||||
int q := 1.
|
||||
cast n(string s)
|
||||
{
|
||||
int i := s.Length - 1;
|
||||
int q := 1;
|
||||
|
||||
dLen := i / 2.
|
||||
dVal := 0.
|
||||
dLen := i / 2;
|
||||
dVal := 0;
|
||||
|
||||
while (i >= 0)
|
||||
[
|
||||
dVal += ((intConvertor convert(s[i]) - 48) * q).
|
||||
q *= 2.
|
||||
{
|
||||
dVal += ((intConvertor.convert(s[i]) - 48) * q);
|
||||
q *= 2;
|
||||
|
||||
i -= 1.
|
||||
].
|
||||
]
|
||||
i -= 1
|
||||
}
|
||||
}
|
||||
|
||||
stacksafe $readContent vint:val vint:len
|
||||
[
|
||||
val int := dVal.
|
||||
len int := dLen.
|
||||
]
|
||||
internal readContent(ref int val, ref int len)
|
||||
{
|
||||
val := dVal;
|
||||
len := dLen;
|
||||
}
|
||||
|
||||
sealed $a(IntNumber n)
|
||||
[
|
||||
int i := n.
|
||||
private a(int n)
|
||||
{
|
||||
int i := n;
|
||||
|
||||
while (true)
|
||||
[
|
||||
{
|
||||
if (dLen < i)
|
||||
[
|
||||
dLen := i.
|
||||
].
|
||||
{
|
||||
dLen := i
|
||||
};
|
||||
|
||||
((dVal >> (i * 2)) && 3) =>
|
||||
0 [ ^ $self ];
|
||||
1 [ ^ $self ];
|
||||
2 [
|
||||
ifnot ((dVal >> ((i + 1) * 2)) allMask:1)
|
||||
[
|
||||
^ $self.
|
||||
].
|
||||
int v2 := dVal $shr (i * 2);
|
||||
int v := (dVal $shr (i * 2)) && 3;
|
||||
|
||||
dVal += (1 << (i*2 + 1)).
|
||||
^ $self.
|
||||
];
|
||||
3 [
|
||||
dVal := dVal && ((3 << i*2) inverted).
|
||||
((dVal $shr (i * 2)) && 3) =>
|
||||
0 { ^ self }
|
||||
1 { ^ self }
|
||||
2 {
|
||||
ifnot ((dVal $shr ((i + 1) * 2)).allMask:1)
|
||||
{
|
||||
^ self
|
||||
};
|
||||
|
||||
$self $b((i+1)*2).
|
||||
].
|
||||
dVal += (1 $shl (i*2 + 1));
|
||||
|
||||
i += 1.
|
||||
].
|
||||
]
|
||||
^ self
|
||||
}
|
||||
3 {
|
||||
int tmp := 3 $shl (i * 2);
|
||||
tmp := tmp.xor(-1);
|
||||
dVal := dVal && tmp;
|
||||
|
||||
inc
|
||||
[
|
||||
dVal += 1.
|
||||
$self $a(0).
|
||||
]
|
||||
self.b((i+1)*2)
|
||||
};
|
||||
|
||||
$b(IntNumber pos)
|
||||
[
|
||||
if (pos == 0) [ ^ $self inc ].
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
|
||||
ifnot((dVal >> pos) allMask:1)
|
||||
[
|
||||
dVal += (1 << pos).
|
||||
$self $a(pos / 2).
|
||||
if (pos > 1) [ $self $a((pos / 2) - 1) ]
|
||||
];
|
||||
[
|
||||
dVal := dVal && (1 << pos) inverted.
|
||||
$self $b(pos + 1).
|
||||
$self $b(pos - (pos > 1) iif(2,1)).
|
||||
].
|
||||
]
|
||||
inc()
|
||||
{
|
||||
dVal += 1;
|
||||
self.a(0)
|
||||
}
|
||||
|
||||
$c(IntNumber pos)
|
||||
[
|
||||
if ((dVal >> pos) allMask:1)
|
||||
[
|
||||
dVal := dVal && (1 << pos) inverted.
|
||||
private b(int pos)
|
||||
{
|
||||
if (pos == 0) { ^ self.inc() };
|
||||
|
||||
^ $self
|
||||
].
|
||||
ifnot((dVal $shr pos).allMask:1)
|
||||
{
|
||||
dVal += (1 $shl pos);
|
||||
self.a(pos / 2);
|
||||
if (pos > 1) { self.a((pos / 2) - 1) }
|
||||
}
|
||||
else
|
||||
{
|
||||
dVal := dVal && (1 $shl pos).Inverted;
|
||||
self.b(pos + 1);
|
||||
int arg := pos - ((pos > 1) ? 2 : 1);
|
||||
self.b(/*pos - ((pos > 1) ? 2 : 1)*/arg)
|
||||
}
|
||||
}
|
||||
|
||||
$self $c(pos + 1).
|
||||
private c(int pos)
|
||||
{
|
||||
if ((dVal $shr pos).allMask:1)
|
||||
{
|
||||
int tmp := 1 $shl pos;
|
||||
tmp := tmp.xor(-1);
|
||||
|
||||
dVal := dVal && tmp;
|
||||
|
||||
^ self
|
||||
};
|
||||
|
||||
self.c(pos + 1);
|
||||
|
||||
if (pos > 0)
|
||||
[
|
||||
$self $b(pos - 1).
|
||||
];
|
||||
[
|
||||
$self inc.
|
||||
]
|
||||
]
|
||||
{
|
||||
self.b(pos - 1)
|
||||
}
|
||||
else
|
||||
{
|
||||
self.inc()
|
||||
}
|
||||
}
|
||||
|
||||
constructor $sum(ZeckendorfNumber n, ZeckendorfNumber m)
|
||||
[
|
||||
int mVal := 0.
|
||||
int mLen := 0.
|
||||
internal constructor sum(ZeckendorfNumber n, ZeckendorfNumber m)
|
||||
{
|
||||
int mVal := 0;
|
||||
int mLen := 0;
|
||||
|
||||
n $readContent vint:dVal vint:dLen.
|
||||
m $readContent vint:mVal vint:mLen.
|
||||
n.readContent(ref dVal, ref dLen);
|
||||
m.readContent(ref mVal, ref mLen);
|
||||
|
||||
0 till((mLen + 1) * 2) do(:GN)
|
||||
[
|
||||
if (mVal shiftRight:GN; allMask:1)
|
||||
[
|
||||
$self $b(GN).
|
||||
].
|
||||
].
|
||||
]
|
||||
for(int GN := 0, GN < (mLen + 1) * 2, GN += 1)
|
||||
{
|
||||
if ((mVal $shr GN).allMask:1)
|
||||
{
|
||||
self.b(GN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructor $difference(ZeckendorfNumber n, ZeckendorfNumber m)
|
||||
[
|
||||
int mVal := 0.
|
||||
int mLen := 0.
|
||||
internal constructor difference(ZeckendorfNumber n, ZeckendorfNumber m)
|
||||
{
|
||||
int mVal := 0;
|
||||
int mLen := 0;
|
||||
|
||||
n $readContent vint:dVal vint:dLen.
|
||||
m $readContent vint:mVal vint:mLen.
|
||||
n.readContent(ref dVal, ref dLen);
|
||||
m.readContent(ref mVal, ref mLen);
|
||||
|
||||
0 till((mLen + 1) * 2) do(:GN)
|
||||
[
|
||||
if (mVal shiftRight:GN; allMask:1)
|
||||
[
|
||||
$self $c(GN).
|
||||
].
|
||||
].
|
||||
for(int GN := 0, GN < (mLen + 1) * 2, GN += 1)
|
||||
{
|
||||
if ((mVal $shr GN).allMask:1)
|
||||
{
|
||||
self.c(GN)
|
||||
}
|
||||
};
|
||||
|
||||
while ((((dVal >> (dLen*2)) && 3) == 0) || (dLen == 0))
|
||||
[
|
||||
dLen -= 1.
|
||||
].
|
||||
]
|
||||
while (((dVal $shr (dLen*2)) && 3) == 0 || dLen == 0)
|
||||
{
|
||||
dLen -= 1
|
||||
}
|
||||
}
|
||||
|
||||
constructor $product(ZeckendorfNumber n, ZeckendorfNumber m)
|
||||
[
|
||||
n $readContent vint:dVal vint:dLen.
|
||||
internal constructor product(ZeckendorfNumber n, ZeckendorfNumber m)
|
||||
{
|
||||
n.readContent(ref dVal, ref dLen);
|
||||
|
||||
var Na := m.
|
||||
var Nb := m.
|
||||
var Nr := 0n.
|
||||
var Nt := 0n.
|
||||
ZeckendorfNumber Na := m;
|
||||
ZeckendorfNumber Nb := m;
|
||||
ZeckendorfNumber Nr := 0n;
|
||||
ZeckendorfNumber Nt := 0n;
|
||||
|
||||
0 to((dLen + 1) * 2) do(:i)
|
||||
[
|
||||
if (((dVal shiftRight:i) && 1) > 0)
|
||||
[
|
||||
for(int i := 0, i < (dLen + 1) * 2, i += 1)
|
||||
{
|
||||
if (((dVal $shr i) && 1) > 0)
|
||||
{
|
||||
Nr += Nb
|
||||
].
|
||||
Nt := Nb.
|
||||
Nb += Na.
|
||||
Na := Nt.
|
||||
].
|
||||
};
|
||||
Nt := Nb;
|
||||
Nb += Na;
|
||||
Na := Nt
|
||||
};
|
||||
|
||||
Nr $readContent vint:dVal vint:dLen.
|
||||
]
|
||||
Nr.readContent(ref dVal, ref dLen);
|
||||
}
|
||||
|
||||
constructor $new(IntNumber v, IntNumber l)
|
||||
[
|
||||
dVal := v.
|
||||
dLen := l.
|
||||
]
|
||||
internal constructor newInternal(int v, int l)
|
||||
{
|
||||
dVal := v;
|
||||
dLen := l
|
||||
}
|
||||
|
||||
literal
|
||||
[
|
||||
get string Printable()
|
||||
{
|
||||
if (dVal == 0)
|
||||
[ ^ "0". ].
|
||||
{ ^ "0" };
|
||||
|
||||
literal s := dig1[(dVal >> (dLen * 2)) && 3].
|
||||
int i := dLen - 1.
|
||||
//int n := dVal $shr (dLen * 2);
|
||||
//int r := (dVal $shr (dLen * 2)) && 3;
|
||||
|
||||
string s := dig1[(dVal $shr (dLen * 2)) && 3];
|
||||
int i := dLen - 1;
|
||||
while (i >= 0)
|
||||
[
|
||||
s := s + dig[(dVal >> (i * 2)) && 3].
|
||||
{
|
||||
s := s + dig[(dVal $shr (i * 2)) && 3];
|
||||
|
||||
i-=1
|
||||
].
|
||||
};
|
||||
|
||||
^ s.
|
||||
]
|
||||
^ s
|
||||
}
|
||||
|
||||
add(ZeckendorfNumber n)
|
||||
= ZeckendorfNumber $sum($self, n).
|
||||
= ZeckendorfNumber.sum(self, n);
|
||||
|
||||
subtract(ZeckendorfNumber n)
|
||||
= ZeckendorfNumber $difference($self, n).
|
||||
= ZeckendorfNumber.difference(self, n);
|
||||
|
||||
multiply(ZeckendorfNumber n)
|
||||
= ZeckendorfNumber $product($self, n).
|
||||
= ZeckendorfNumber.product(self, n);
|
||||
}
|
||||
|
||||
program =
|
||||
[
|
||||
console printLine("Addition:").
|
||||
var n := 10n.
|
||||
public program()
|
||||
{
|
||||
console.printLine("Addition:");
|
||||
var n := 10n;
|
||||
|
||||
n += 10n.
|
||||
console printLine(n).
|
||||
n += 10n.
|
||||
console printLine(n).
|
||||
n += 1001n.
|
||||
console printLine(n).
|
||||
n += 1000n.
|
||||
console printLine(n).
|
||||
n += 10101n.
|
||||
console printLine(n).
|
||||
n += 10n;
|
||||
console.printLine(n);
|
||||
n += 10n;
|
||||
console.printLine(n);
|
||||
n += 1001n;
|
||||
console.printLine(n);
|
||||
n += 1000n;
|
||||
console.printLine(n);
|
||||
n += 10101n;
|
||||
console.printLine(n);
|
||||
|
||||
console printLine("Subtraction:").
|
||||
n := 1000n.
|
||||
n -= 101n.
|
||||
console printLine(n).
|
||||
n := 10101010n.
|
||||
n -= 1010101n.
|
||||
console printLine(n).
|
||||
console.printLine("Subtraction:");
|
||||
n := 1000n;
|
||||
n -= 101n;
|
||||
console.printLine(n);
|
||||
n := 10101010n;
|
||||
n -= 1010101n;
|
||||
console.printLine(n);
|
||||
|
||||
console printLine("Multiplication:").
|
||||
n := 1001n.
|
||||
n *= 101n.
|
||||
console printLine(n).
|
||||
n := 101010n.
|
||||
n += 101n.
|
||||
console printLine(n).
|
||||
].
|
||||
console.printLine("Multiplication:");
|
||||
n := 1001n;
|
||||
n *= 101n;
|
||||
console.printLine(n);
|
||||
n := 101010n;
|
||||
n += 101n;
|
||||
console.printLine(n)
|
||||
}
|
||||
|
|
|
|||
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)
|
||||
}
|
||||
172
Task/Zeckendorf-arithmetic/Julia/zeckendorf-arithmetic.julia
Normal file
172
Task/Zeckendorf-arithmetic/Julia/zeckendorf-arithmetic.julia
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
import Base.*, Base.+, Base.-, Base./, Base.show, Base.!=, Base.==, Base.<=, Base.<, Base.>, Base.>=, Base.divrem
|
||||
|
||||
const z0 = "0"
|
||||
const z1 = "1"
|
||||
const flipordered = (z1 < z0)
|
||||
|
||||
mutable struct Z s::String end
|
||||
Z() = Z(z0)
|
||||
Z(z::Z) = Z(z.s)
|
||||
|
||||
pairlen(x::Z, y::Z) = max(length(x.s), length(y.s))
|
||||
tolen(x::Z, n::Int) = (s = x.s; while length(s) < n s = z0 * s end; s)
|
||||
|
||||
<(x::Z, y::Z) = (l = pairlen(x, y); flipordered ? tolen(x, l) > tolen(y, l) : tolen(x, l) < tolen(y, l))
|
||||
>(x::Z, y::Z) = (l = pairlen(x, y); flipordered ? tolen(x, l) < tolen(y, l) : tolen(x, l) > tolen(y, l))
|
||||
==(x::Z, y::Z) = (l = pairlen(x, y); tolen(x, l) == tolen(y, l))
|
||||
<=(x::Z, y::Z) = (l = pairlen(x, y); flipordered ? tolen(x, l) >= tolen(y, l) : tolen(x, l) <= tolen(y, l))
|
||||
>=(x::Z, y::Z) = (l = pairlen(x, y); flipordered ? tolen(x, l) <= tolen(y, l) : tolen(x, l) >= tolen(y, l))
|
||||
!=(x::Z, y::Z) = (l = pairlen(x, y); tolen(x, l) != tolen(y, l))
|
||||
|
||||
function tocanonical(z::Z)
|
||||
while occursin(z0 * z1 * z1, z.s)
|
||||
z.s = replace(z.s, z0 * z1 * z1 => z1 * z0 * z0)
|
||||
end
|
||||
len = length(z.s)
|
||||
if len > 1 && z.s[1:2] == z1 * z1
|
||||
z.s = z1 * z0 * z0 * ((len > 2) ? z.s[3:end] : "")
|
||||
end
|
||||
while (len = length(z.s)) > 1 && string(z.s[1]) == z0
|
||||
if len == 2
|
||||
if z.s == z0 * z0
|
||||
z.s = z0
|
||||
elseif z.s == z0 * z1
|
||||
z.s = z1
|
||||
end
|
||||
else
|
||||
z.s = z.s[2:end]
|
||||
end
|
||||
end
|
||||
z
|
||||
end
|
||||
|
||||
function inc(z)
|
||||
if z.s[end] == z0[1]
|
||||
z.s = z.s[1:end-1] * z1[1]
|
||||
elseif z.s[end] == z1[1]
|
||||
if length(z.s) > 1
|
||||
if z.s[end-1:end] == z0 * z1
|
||||
z.s = z.s[1:end-2] * z1 * z0
|
||||
end
|
||||
else
|
||||
z.s = z1 * z0
|
||||
end
|
||||
end
|
||||
tocanonical(z)
|
||||
end
|
||||
|
||||
function dec(z)
|
||||
if z.s[end] == z1[1]
|
||||
z.s = z.s[1:end-1] * z0
|
||||
else
|
||||
if (m = match(Regex(z1 * z0 * '+' * '$'), z.s)) != nothing
|
||||
len = length(m.match)
|
||||
if iseven(len)
|
||||
z.s = z.s[1:end-len] * (z0 * z1) ^ div(len, 2)
|
||||
else
|
||||
z.s = z.s[1:end-len] * (z0 * z1) ^ div(len, 2) * z0
|
||||
end
|
||||
end
|
||||
end
|
||||
tocanonical(z)
|
||||
z
|
||||
end
|
||||
|
||||
function +(x::Z, y::Z)
|
||||
a = Z(x.s)
|
||||
b = Z(y.s)
|
||||
while b.s != z0
|
||||
inc(a)
|
||||
dec(b)
|
||||
end
|
||||
a
|
||||
end
|
||||
|
||||
function -(x::Z, y::Z)
|
||||
a = Z(x.s)
|
||||
b = Z(y.s)
|
||||
while b.s != z0
|
||||
dec(a)
|
||||
dec(b)
|
||||
end
|
||||
a
|
||||
end
|
||||
|
||||
function *(x::Z, y::Z)
|
||||
if (x.s == z0) || (y.s == z0)
|
||||
return Z(z0)
|
||||
elseif x.s == z1
|
||||
return Z(y.s)
|
||||
elseif y.s == z1
|
||||
return Z(x.s)
|
||||
end
|
||||
a = Z(x.s)
|
||||
b = Z(z1)
|
||||
while b != y
|
||||
c = Z(z0)
|
||||
while c != x
|
||||
inc(a)
|
||||
inc(c)
|
||||
end
|
||||
inc(b)
|
||||
end
|
||||
a
|
||||
end
|
||||
|
||||
function divrem(x::Z, y::Z)
|
||||
if y.s == z0
|
||||
throw("Zeckendorf division by 0")
|
||||
elseif (y.s == z1) || (x.s == z0)
|
||||
return Z(x.s)
|
||||
end
|
||||
a = Z(x.s)
|
||||
b = Z(y.s)
|
||||
c = Z(z0)
|
||||
while a > b
|
||||
a = a - b
|
||||
inc(c)
|
||||
end
|
||||
tocanonical(c), tocanonical(a)
|
||||
end
|
||||
|
||||
function /(x::Z, y::Z)
|
||||
a, _ = divrem(x, y)
|
||||
a
|
||||
end
|
||||
|
||||
show(io::IO, z::Z) = show(io, parse(BigInt, tocanonical(z).s))
|
||||
|
||||
function zeckendorftest()
|
||||
a = Z("10")
|
||||
b = Z("1001")
|
||||
c = Z("1000")
|
||||
d = Z("10101")
|
||||
|
||||
println("Addition:")
|
||||
x = a
|
||||
println(x += a)
|
||||
println(x += a)
|
||||
println(x += b)
|
||||
println(x += c)
|
||||
println(x += d)
|
||||
|
||||
println("\nSubtraction:")
|
||||
x = Z("1000")
|
||||
println(x - Z("101"))
|
||||
x = Z("10101010")
|
||||
println(x - Z("1010101"))
|
||||
|
||||
println("\nMultiplication:")
|
||||
x = Z("1001")
|
||||
y = Z("101")
|
||||
println(x * y)
|
||||
println(Z("101010") * y)
|
||||
|
||||
println("\nDivision:")
|
||||
x = Z("1000101")
|
||||
y = Z("101")
|
||||
println(x / y)
|
||||
println(divrem(x, y))
|
||||
end
|
||||
|
||||
zeckendorftest()
|
||||
|
|
@ -17,7 +17,6 @@ sub infix:<eqz>($a, $b) { $a eq $b };
|
|||
# not equal
|
||||
sub infix:<nez>($a, $b) { $a ne $b };
|
||||
|
||||
|
||||
######## Operators for Zeckendorf arithmetic ########
|
||||
|
||||
# post increment
|
||||
|
|
@ -37,10 +36,10 @@ sub postfix:<--z>($a is rw) {
|
|||
}
|
||||
|
||||
# addition
|
||||
sub infix:<+z>($a is copy, $b is copy) { $a++z while $b--z nez $z0; $a };
|
||||
sub infix:<+z>($a is copy, $b is copy) { $a++z; $a++z while $b--z nez $z0; $a };
|
||||
|
||||
# subtraction
|
||||
sub infix:<-z>($a is copy, $b is copy) { $a--z while $b--z nez $z0; $a };
|
||||
sub infix:<-z>($a is copy, $b is copy) { $a--z; $a--z while $b--z nez $z0; $a };
|
||||
|
||||
# multiplication
|
||||
sub infix:<*z>($a, $b) {
|
||||
|
|
@ -65,13 +64,13 @@ sub infix:</z>($a is copy, $b is copy) {
|
|||
repeat {
|
||||
my $d = $b +z ($z1 ~ $z0);
|
||||
$c++z;
|
||||
$a++z;
|
||||
$a--z while $d--z nez $z0
|
||||
} until $a ltz $b;
|
||||
$c ~= " remainder $a" if $a nez $z0;
|
||||
$c
|
||||
};
|
||||
|
||||
|
||||
###################### Testing ######################
|
||||
|
||||
# helper sub to translate constants into the particular glyphs you used
|
||||
|
|
|
|||
267
Task/Zeckendorf-arithmetic/Phix/zeckendorf-arithmetic.phix
Normal file
267
Task/Zeckendorf-arithmetic/Phix/zeckendorf-arithmetic.phix
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
sequence fib = {1,1}
|
||||
|
||||
function zeckendorf(atom n)
|
||||
-- Same as [[Zeckendorf_number_representation#Phix]]
|
||||
atom r = 0
|
||||
while fib[$]<n do
|
||||
fib &= fib[$] + fib[$-1]
|
||||
end while
|
||||
integer k = length(fib)
|
||||
while k>2 and n<fib[k] do
|
||||
k -= 1
|
||||
end while
|
||||
for i=k to 2 by -1 do
|
||||
integer c = n>=fib[i]
|
||||
r += r+c
|
||||
n -= c*fib[i]
|
||||
end for
|
||||
return r
|
||||
end function
|
||||
|
||||
function decimal(object z)
|
||||
-- Convert Zeckendorf number(s) to decimal
|
||||
atom dec = 0, bit = 2
|
||||
if sequence(z) then
|
||||
for i=1 to length(z) do
|
||||
z[i] = decimal(z[i])
|
||||
end for
|
||||
return z
|
||||
end if
|
||||
while z do
|
||||
if and_bits(z,1) then
|
||||
dec += fib[bit]
|
||||
end if
|
||||
bit += 1
|
||||
if bit>length(fib) then
|
||||
fib &= fib[$] + fib[$-1]
|
||||
end if
|
||||
z = floor(z/2)
|
||||
end while
|
||||
return dec
|
||||
end function
|
||||
|
||||
function to_bits(integer x)
|
||||
-- Simplified copy of int_to_bits(), but in reverse order,
|
||||
-- and +ve only but (also only) as many bits as needed, and
|
||||
-- ensures there are *two* trailing 0 (most significant)
|
||||
sequence bits = {}
|
||||
if x<0 then ?9/0 end if -- sanity/avoid infinite loop
|
||||
while 1 do
|
||||
bits &= remainder(x,2)
|
||||
if x=0 then exit end if
|
||||
x = floor(x/2)
|
||||
end while
|
||||
bits &= 0 -- (since eg 101+101 -> 10000)
|
||||
return bits
|
||||
end function
|
||||
|
||||
function to_bits2(integer a,b)
|
||||
-- Apply to_bits() to a and b, and pad to the same length
|
||||
sequence sa = to_bits(a), sb = to_bits(b)
|
||||
integer diff = length(sa)-length(sb)
|
||||
if diff!=0 then
|
||||
if diff<0 then sa &= repeat(0,-diff)
|
||||
else sb &= repeat(0,+diff)
|
||||
end if
|
||||
end if
|
||||
return {sa,sb}
|
||||
end function
|
||||
|
||||
function to_int(sequence bits)
|
||||
-- Copy of bits_to_int(), but in reverse order (lsb last)
|
||||
atom val = 0, p = 1
|
||||
for i=length(bits) to 1 by -1 do
|
||||
if bits[i] then
|
||||
val += p
|
||||
end if
|
||||
p += p
|
||||
end for
|
||||
return val
|
||||
end function
|
||||
|
||||
function zstr(object z)
|
||||
if sequence(z) then
|
||||
for i=1 to length(z) do
|
||||
z[i] = zstr(z[i])
|
||||
end for
|
||||
return z
|
||||
end if
|
||||
return sprintf("%b",z)
|
||||
end function
|
||||
|
||||
function rep(sequence res, integer ds, sequence was, wth)
|
||||
-- helper for cleanup, validates replacements
|
||||
integer de = ds+length(was)-1
|
||||
if res[ds..de]!=was then ?9/0 end if
|
||||
if length(was)!=length(wth) then ?9/0 end if
|
||||
res[ds..de] = wth
|
||||
return res
|
||||
end function
|
||||
|
||||
function zcleanup(sequence res)
|
||||
-- (shared by zadd and zsub)
|
||||
integer l = length(res)
|
||||
-- first stage, left to right, {020x -> 100x', 030x -> 110x', 021x->110x, 012x->101x}
|
||||
for i=1 to l-3 do
|
||||
switch res[i..i+2]
|
||||
case {0,2,0}: res[i..i+2] = {1,0,0} res[i+3] += 1
|
||||
case {0,3,0}: res[i..i+2] = {1,1,0} res[i+3] += 1
|
||||
case {0,2,1}: res[i..i+2] = {1,1,0}
|
||||
case {0,1,2}: res[i..i+2] = {1,0,1}
|
||||
end switch
|
||||
end for
|
||||
-- first stage cleanup
|
||||
if l>1 then
|
||||
if res[l-1]=3 then res = rep(res,l-2,{0,3,0},{1,1,1}) -- 030 -> 111
|
||||
elsif res[l-1]=2 then
|
||||
if res[l-2]=0 then res = rep(res,l-2,{0,2,0},{1,0,1}) -- 020 -> 101
|
||||
else res = rep(res,l-3,{0,1,2,0},{1,0,1,0}) -- 0120 -> 1010
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
if res[l]=3 then res = rep(res,l-1,{0,3},{1,1}) -- 03 -> 11
|
||||
elsif res[l]=2 then
|
||||
if res[l-1]=0 then res = rep(res,l-1,{0,2},{1,0}) -- 02 -> 10
|
||||
else res = rep(res,l-2,{0,1,2},{1,0,1}) -- 012 -> 101
|
||||
end if
|
||||
end if
|
||||
-- second stage, pass 1, right to left, 011 -> 100
|
||||
for i=length(res)-2 to 1 by -1 do
|
||||
if res[i..i+2]={0,1,1} then res[i..i+2] = {1,0,0} end if
|
||||
end for
|
||||
-- second stage, pass 2, left to right, 011 -> 100
|
||||
for i=1 to length(res)-2 do
|
||||
if res[i..i+2]={0,1,1} then res[i..i+2] = {1,0,0} end if
|
||||
end for
|
||||
return to_int(res)
|
||||
end function
|
||||
|
||||
function zadd(integer a, b)
|
||||
sequence {sa,sb} = to_bits2(a,b)
|
||||
return zcleanup(reverse(sq_add(sa,sb)))
|
||||
end function
|
||||
|
||||
function zinc(integer a)
|
||||
return zadd(a,0b1)
|
||||
end function
|
||||
|
||||
function zsub(integer a, b)
|
||||
sequence {sa,sb} = to_bits2(a,b)
|
||||
sequence res = reverse(sq_sub(sa,sb))
|
||||
-- (/not/ combined with the first pass of the add routine!)
|
||||
for i=1 to length(res)-2 do
|
||||
switch res[i..i+2] do
|
||||
case {1, 0, 0}: res[i..i+2] = {0,1,1}
|
||||
case {1,-1, 0}: res[i..i+2] = {0,0,1}
|
||||
case {1,-1, 1}: res[i..i+2] = {0,0,2}
|
||||
case {1, 0,-1}: res[i..i+2] = {0,1,0}
|
||||
case {2, 0, 0}: res[i..i+2] = {1,1,1}
|
||||
case {2,-1, 0}: res[i..i+2] = {1,0,1}
|
||||
case {2,-1, 1}: res[i..i+2] = {1,0,2}
|
||||
case {2, 0,-1}: res[i..i+2] = {1,1,0}
|
||||
end switch
|
||||
end for
|
||||
-- copied from PicoLisp: {1,-1} -> {0,1} and {2,-1} -> {1,1}
|
||||
for i=1 to length(res)-1 do
|
||||
switch res[i..i+1] do
|
||||
case {1,-1}: res[i..i+1] = {0,1}
|
||||
case {2,-1}: res[i..i+1] = {1,1}
|
||||
end switch
|
||||
end for
|
||||
if find(-1,res) then ?9/0 end if -- sanity check
|
||||
return zcleanup(res)
|
||||
end function
|
||||
|
||||
function zdec(integer a)
|
||||
return zsub(a,0b1)
|
||||
end function
|
||||
|
||||
function zmul(integer a, b)
|
||||
integer res = 0
|
||||
sequence mult = {a,zadd(a,a)} -- (as per task desc)
|
||||
integer bits = 2
|
||||
while bits<b do
|
||||
mult = append(mult,zadd(mult[$],mult[$-1]))
|
||||
bits *= 2
|
||||
end while
|
||||
integer bit = 1
|
||||
while b do
|
||||
if and_bits(b,1) then
|
||||
res = zadd(res,mult[bit])
|
||||
end if
|
||||
b = floor(b/2)
|
||||
bit += 1
|
||||
end while
|
||||
return res
|
||||
end function
|
||||
|
||||
function zdiv(integer a, b)
|
||||
integer res = 0
|
||||
sequence mult = {b,zadd(b,b)}
|
||||
integer bits = 2
|
||||
while mult[$]<a do
|
||||
mult = append(mult,zadd(mult[$],mult[$-1]))
|
||||
bits *= 2
|
||||
end while
|
||||
for i=length(mult) to 1 by -1 do
|
||||
integer mi = mult[i]
|
||||
if mi<=a then
|
||||
res = zadd(res,bits)
|
||||
a = zsub(a,mi)
|
||||
if a=0 then exit end if
|
||||
end if
|
||||
bits = floor(bits/2)
|
||||
end for
|
||||
return {res,a} -- (a is the remainder)
|
||||
end function
|
||||
|
||||
for i=0 to 20 do
|
||||
integer zi = zeckendorf(i)
|
||||
atom d = decimal(zi)
|
||||
printf(1,"%2d: %7b (%d)\n",{i,zi,d})
|
||||
end for
|
||||
|
||||
procedure test(atom a, string op, atom b, object res, string expected)
|
||||
string zres = iff(atom(res)?zstr(res):join(zstr(res)," rem ")),
|
||||
dres = sprintf(iff(atom(res)?"%d":"%d rem %d"),decimal(res)),
|
||||
aka = sprintf("aka %d %s %d = %s",{decimal(a),op,decimal(b),dres}),
|
||||
ok = iff(zres=expected?"":" *** ERROR ***!!")
|
||||
printf(1,"%s %s %s = %s, %s %s\n",{zstr(a),op,zstr(b),zres,aka,ok})
|
||||
end procedure
|
||||
|
||||
test(0b0,"+",0b0,zadd(0b0,0b0),"0")
|
||||
test(0b101,"+",0b101,zadd(0b101,0b101),"10000")
|
||||
test(0b10100,"-",0b1000,zsub(0b10100,0b1000),"1001")
|
||||
test(0b100100,"-",0b1000,zsub(0b100100,0b1000),"10100")
|
||||
test(0b1001,"*",0b101,zmul(0b1001,0b101),"1000100")
|
||||
test(0b1000101,"/",0b101,zdiv(0b1000101,0b101),"1001 rem 1")
|
||||
|
||||
test(0b10,"+",0b10,zadd(0b10,0b10),"101")
|
||||
test(0b101,"+",0b10,zadd(0b101,0b10),"1001")
|
||||
test(0b1001,"+",0b1001,zadd(0b1001,0b1001),"10101")
|
||||
test(0b10101,"+",0b1000,zadd(0b10101,0b1000),"100101")
|
||||
test(0b100101,"+",0b10101,zadd(0b100101,0b10101),"1010000")
|
||||
test(0b1000,"-",0b101,zsub(0b1000,0b101),"1")
|
||||
test(0b10101010,"-",0b1010101,zsub(0b10101010,0b1010101),"1000000")
|
||||
test(0b1001,"*",0b101,zmul(0b1001,0b101),"1000100")
|
||||
test(0b101010,"+",0b101,zadd(0b101010,0b101),"1000100")
|
||||
|
||||
test(0b10100,"+",0b1010,zadd(0b10100,0b1010),"101000")
|
||||
test(0b101000,"-",0b1010,zsub(0b101000,0b1010),"10100")
|
||||
|
||||
test(0b100010,"*",0b100101,zmul(0b100010,0b100101),"100001000001")
|
||||
test(0b100001000001,"/",0b100,zdiv(0b100001000001,0b100),"101010001 rem 0")
|
||||
test(0b101000101,"*",0b101001,zmul(0b101000101,0b101001),"101010000010101")
|
||||
test(0b101010000010101,"/",0b100,zdiv(0b101010000010101,0b100),"1001010001001 rem 10")
|
||||
|
||||
test(0b10100010010100,"+",0b1001000001,zadd(0b10100010010100,0b1001000001),"100000000010101")
|
||||
test(0b10100010010100,"-",0b1001000001,zsub(0b10100010010100,0b1001000001),"10010001000010")
|
||||
test(0b10000,"*",0b1001000001,zmul(0b10000,0b1001000001),"10100010010100")
|
||||
test(0b1010001010000001001,"/",0b100000000100000,zdiv(0b1010001010000001001,0b100000000100000),"10001 rem 10100001010101")
|
||||
|
||||
test(0b10100,"+",0b1010,zadd(0b10100,0b1010),"101000")
|
||||
test(0b10100,"-",0b1010,zsub(0b10100,0b1010),"101")
|
||||
test(0b10100,"*",0b1010,zmul(0b10100,0b1010),"101000001")
|
||||
test(0b10100,"/",0b1010,zdiv(0b10100,0b1010),"1 rem 101")
|
||||
integer m = zmul(0b10100,0b1010)
|
||||
test(m,"/",0b1010,zdiv(m,0b1010),"10100 rem 0")
|
||||
144
Task/Zeckendorf-arithmetic/Python/zeckendorf-arithmetic.py
Normal file
144
Task/Zeckendorf-arithmetic/Python/zeckendorf-arithmetic.py
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
import copy
|
||||
|
||||
class Zeckendorf:
|
||||
def __init__(self, x='0'):
|
||||
q = 1
|
||||
i = len(x) - 1
|
||||
self.dLen = int(i / 2)
|
||||
self.dVal = 0
|
||||
while i >= 0:
|
||||
self.dVal = self.dVal + (ord(x[i]) - ord('0')) * q
|
||||
q = q * 2
|
||||
i = i -1
|
||||
|
||||
def a(self, n):
|
||||
i = n
|
||||
while True:
|
||||
if self.dLen < i:
|
||||
self.dLen = i
|
||||
j = (self.dVal >> (i * 2)) & 3
|
||||
if j == 0 or j == 1:
|
||||
return
|
||||
if j == 2:
|
||||
if (self.dVal >> ((i + 1) * 2) & 1) != 1:
|
||||
return
|
||||
self.dVal = self.dVal + (1 << (i * 2 + 1))
|
||||
return
|
||||
if j == 3:
|
||||
temp = 3 << (i * 2)
|
||||
temp = temp ^ -1
|
||||
self.dVal = self.dVal & temp
|
||||
self.b((i + 1) * 2)
|
||||
i = i + 1
|
||||
|
||||
def b(self, pos):
|
||||
if pos == 0:
|
||||
self.inc()
|
||||
return
|
||||
if (self.dVal >> pos) & 1 == 0:
|
||||
self.dVal = self.dVal + (1 << pos)
|
||||
self.a(int(pos / 2))
|
||||
if pos > 1:
|
||||
self.a(int(pos / 2) - 1)
|
||||
else:
|
||||
temp = 1 << pos
|
||||
temp = temp ^ -1
|
||||
self.dVal = self.dVal & temp
|
||||
self.b(pos + 1)
|
||||
self.b(pos - (2 if pos > 1 else 1))
|
||||
|
||||
def c(self, pos):
|
||||
if (self.dVal >> pos) & 1 == 1:
|
||||
temp = 1 << pos
|
||||
temp = temp ^ -1
|
||||
self.dVal = self.dVal & temp
|
||||
return
|
||||
self.c(pos + 1)
|
||||
if pos > 0:
|
||||
self.b(pos - 1)
|
||||
else:
|
||||
self.inc()
|
||||
|
||||
def inc(self):
|
||||
self.dVal = self.dVal + 1
|
||||
self.a(0)
|
||||
|
||||
def __add__(self, rhs):
|
||||
copy = self
|
||||
rhs_dVal = rhs.dVal
|
||||
limit = (rhs.dLen + 1) * 2
|
||||
for gn in range(0, limit):
|
||||
if ((rhs_dVal >> gn) & 1) == 1:
|
||||
copy.b(gn)
|
||||
return copy
|
||||
|
||||
def __sub__(self, rhs):
|
||||
copy = self
|
||||
rhs_dVal = rhs.dVal
|
||||
limit = (rhs.dLen + 1) * 2
|
||||
for gn in range(0, limit):
|
||||
if (rhs_dVal >> gn) & 1 == 1:
|
||||
copy.c(gn)
|
||||
while (((copy.dVal >> ((copy.dLen * 2) & 31)) & 3) == 0) or (copy.dLen == 0):
|
||||
copy.dLen = copy.dLen - 1
|
||||
return copy
|
||||
|
||||
def __mul__(self, rhs):
|
||||
na = copy.deepcopy(rhs)
|
||||
nb = copy.deepcopy(rhs)
|
||||
nr = Zeckendorf()
|
||||
dVal = self.dVal
|
||||
for i in range(0, (self.dLen + 1) * 2):
|
||||
if ((dVal >> i) & 1) > 0:
|
||||
nr = nr + nb
|
||||
nt = copy.deepcopy(nb)
|
||||
nb = nb + na
|
||||
na = copy.deepcopy(nt)
|
||||
return nr
|
||||
|
||||
def __str__(self):
|
||||
dig = ["00", "01", "10"]
|
||||
dig1 = ["", "1", "10"]
|
||||
|
||||
if self.dVal == 0:
|
||||
return '0'
|
||||
idx = (self.dVal >> ((self.dLen * 2) & 31)) & 3
|
||||
sb = dig1[idx]
|
||||
i = self.dLen - 1
|
||||
while i >= 0:
|
||||
idx = (self.dVal >> (i * 2)) & 3
|
||||
sb = sb + dig[idx]
|
||||
i = i - 1
|
||||
return sb
|
||||
|
||||
# main
|
||||
print "Addition:"
|
||||
g = Zeckendorf("10")
|
||||
g = g + Zeckendorf("10")
|
||||
print g
|
||||
g = g + Zeckendorf("10")
|
||||
print g
|
||||
g = g + Zeckendorf("1001")
|
||||
print g
|
||||
g = g + Zeckendorf("1000")
|
||||
print g
|
||||
g = g + Zeckendorf("10101")
|
||||
print g
|
||||
print
|
||||
|
||||
print "Subtraction:"
|
||||
g = Zeckendorf("1000")
|
||||
g = g - Zeckendorf("101")
|
||||
print g
|
||||
g = Zeckendorf("10101010")
|
||||
g = g - Zeckendorf("1010101")
|
||||
print g
|
||||
print
|
||||
|
||||
print "Multiplication:"
|
||||
g = Zeckendorf("1001")
|
||||
g = g * Zeckendorf("101")
|
||||
print g
|
||||
g = Zeckendorf("101010")
|
||||
g = g + Zeckendorf("101")
|
||||
print g
|
||||
Loading…
Add table
Add a link
Reference in a new issue