254 lines
5 KiB
Text
254 lines
5 KiB
Text
import extensions;
|
|
|
|
const dig = new string[]::("00","01","10");
|
|
const dig1 = new string[]::("","1","10");
|
|
|
|
sealed struct ZeckendorfNumber
|
|
{
|
|
int dVal;
|
|
int dLen;
|
|
|
|
clone()
|
|
= ZeckendorfNumber.newInternal(dVal,dLen);
|
|
|
|
cast n(string s)
|
|
{
|
|
int i := s.Length - 1;
|
|
int q := 1;
|
|
|
|
dLen := i / 2;
|
|
dVal := 0;
|
|
|
|
while (i >= 0)
|
|
{
|
|
dVal += ((intConvertor.convert(s[i]) - 48) * q);
|
|
q *= 2;
|
|
|
|
i -= 1
|
|
}
|
|
}
|
|
|
|
internal readContent(ref int val, ref int len)
|
|
{
|
|
val := dVal;
|
|
len := dLen;
|
|
}
|
|
|
|
private a(int n)
|
|
{
|
|
int i := n;
|
|
|
|
while (true)
|
|
{
|
|
if (dLen < i)
|
|
{
|
|
dLen := i
|
|
};
|
|
|
|
int v2 := dVal $shr (i * 2);
|
|
int v := (dVal $shr (i * 2)) && 3;
|
|
|
|
((dVal $shr (i * 2)) && 3) =>
|
|
0 { ^ self }
|
|
1 { ^ self }
|
|
2 {
|
|
ifnot ((dVal $shr ((i + 1) * 2)).allMask:1)
|
|
{
|
|
^ self
|
|
};
|
|
|
|
dVal += (1 $shl (i*2 + 1));
|
|
|
|
^ self
|
|
}
|
|
3 {
|
|
int tmp := 3 $shl (i * 2);
|
|
tmp := tmp.xor(-1);
|
|
dVal := dVal && tmp;
|
|
|
|
self.b((i+1)*2)
|
|
};
|
|
|
|
i += 1
|
|
}
|
|
}
|
|
|
|
inc()
|
|
{
|
|
dVal += 1;
|
|
self.a(0)
|
|
}
|
|
|
|
private b(int pos)
|
|
{
|
|
if (pos == 0) { ^ self.inc() };
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|
|
else
|
|
{
|
|
self.inc()
|
|
}
|
|
}
|
|
|
|
internal constructor sum(ZeckendorfNumber n, ZeckendorfNumber m)
|
|
{
|
|
int mVal := 0;
|
|
int mLen := 0;
|
|
|
|
n.readContent(ref dVal, ref dLen);
|
|
m.readContent(ref mVal, ref mLen);
|
|
|
|
for(int GN := 0, GN < (mLen + 1) * 2, GN += 1)
|
|
{
|
|
if ((mVal $shr GN).allMask:1)
|
|
{
|
|
self.b(GN)
|
|
}
|
|
}
|
|
}
|
|
|
|
internal constructor difference(ZeckendorfNumber n, ZeckendorfNumber m)
|
|
{
|
|
int mVal := 0;
|
|
int mLen := 0;
|
|
|
|
n.readContent(ref dVal, ref dLen);
|
|
m.readContent(ref mVal, ref mLen);
|
|
|
|
for(int GN := 0, GN < (mLen + 1) * 2, GN += 1)
|
|
{
|
|
if ((mVal $shr GN).allMask:1)
|
|
{
|
|
self.c(GN)
|
|
}
|
|
};
|
|
|
|
while (((dVal $shr (dLen*2)) && 3) == 0 || dLen == 0)
|
|
{
|
|
dLen -= 1
|
|
}
|
|
}
|
|
|
|
internal constructor product(ZeckendorfNumber n, ZeckendorfNumber m)
|
|
{
|
|
n.readContent(ref dVal, ref dLen);
|
|
|
|
ZeckendorfNumber Na := m;
|
|
ZeckendorfNumber Nb := m;
|
|
ZeckendorfNumber Nr := 0n;
|
|
ZeckendorfNumber Nt := 0n;
|
|
|
|
for(int i := 0, i < (dLen + 1) * 2, i += 1)
|
|
{
|
|
if (((dVal $shr i) && 1) > 0)
|
|
{
|
|
Nr += Nb
|
|
};
|
|
Nt := Nb;
|
|
Nb += Na;
|
|
Na := Nt
|
|
};
|
|
|
|
Nr.readContent(ref dVal, ref dLen);
|
|
}
|
|
|
|
internal constructor newInternal(int v, int l)
|
|
{
|
|
dVal := v;
|
|
dLen := l
|
|
}
|
|
|
|
get string Printable()
|
|
{
|
|
if (dVal == 0)
|
|
{ ^ "0" };
|
|
|
|
//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 $shr (i * 2)) && 3];
|
|
|
|
i-=1
|
|
};
|
|
|
|
^ s
|
|
}
|
|
|
|
add(ZeckendorfNumber n)
|
|
= ZeckendorfNumber.sum(self, n);
|
|
|
|
subtract(ZeckendorfNumber n)
|
|
= ZeckendorfNumber.difference(self, n);
|
|
|
|
multiply(ZeckendorfNumber n)
|
|
= ZeckendorfNumber.product(self, n);
|
|
}
|
|
|
|
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);
|
|
|
|
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)
|
|
}
|