Time for an 2014 update…
This commit is contained in:
parent
372c577f83
commit
09687c4926
2520 changed files with 34227 additions and 7318 deletions
|
|
@ -1,47 +1,47 @@
|
|||
import std.stdio, std.bigint, std.range, std.algorithm, std.array,
|
||||
std.conv, std.exception;
|
||||
import std.stdio, std.bigint, std.range, std.algorithm;
|
||||
|
||||
struct BalancedTernary {
|
||||
enum Dig : byte { N=-1, Z=0, P=+1 } // Digits.
|
||||
Dig[] digits;
|
||||
// Represented as a list of 0, 1 or -1s,
|
||||
// with least significant digit first.
|
||||
enum Dig : byte { N=-1, Z=0, P=+1 } // Digit.
|
||||
const Dig[] digits;
|
||||
|
||||
static string dig2str = "-0+";
|
||||
// This could also be a BalancedTernary template argument.
|
||||
static immutable string dig2str = "-0+";
|
||||
|
||||
const static Dig[dchar] str2dig; // = ['+': Dig.P, ...];
|
||||
static this() {
|
||||
immutable static Dig[dchar] str2dig; // = ['+': Dig.P, ...];
|
||||
nothrow static this() {
|
||||
str2dig = ['+': Dig.P, '-': Dig.N, '0': Dig.Z];
|
||||
}
|
||||
|
||||
immutable static Dig[2][] table =
|
||||
immutable pure nothrow static Dig[2][] table =
|
||||
[[Dig.Z, Dig.N], [Dig.P, Dig.N], [Dig.N, Dig.Z],
|
||||
[Dig.Z, Dig.Z], [Dig.P, Dig.Z], [Dig.N, Dig.P],
|
||||
[Dig.Z, Dig.P]];
|
||||
|
||||
this(string inp) {
|
||||
this.digits = inp.retro().map!(c => cast()str2dig[c]).array;
|
||||
this(in string inp) const pure {
|
||||
this.digits = inp.retro.map!(c => str2dig[c]).array;
|
||||
}
|
||||
|
||||
this(long inp) {
|
||||
this(in long inp) const pure /*nothrow*/ {
|
||||
this.digits = _bint2ternary(inp.BigInt);
|
||||
}
|
||||
|
||||
this(BigInt inp) {
|
||||
this(in BigInt inp) const pure /*nothrow*/ {
|
||||
this.digits = _bint2ternary(inp);
|
||||
}
|
||||
|
||||
this(BalancedTernary inp) {
|
||||
this(in BalancedTernary inp) const pure nothrow {
|
||||
// No need to dup, they are virtually immutable.
|
||||
this.digits = inp.digits;
|
||||
}
|
||||
|
||||
private this(Dig[] inp) {
|
||||
private this(in Dig[] inp) /*inout*/ pure nothrow {
|
||||
this.digits = inp;
|
||||
}
|
||||
|
||||
static Dig[] _bint2ternary(/*in*/ BigInt n) {
|
||||
static py_div(T1, T2)(T1 a, T2 b) {
|
||||
static Dig[] _bint2ternary(in BigInt n) pure /*nothrow*/ {
|
||||
static py_div(T1, T2)(in T1 a, in T2 b) pure /*nothrow*/ {
|
||||
if (a < 0) {
|
||||
return (b < 0) ?
|
||||
-a / -b :
|
||||
|
|
@ -54,33 +54,34 @@ struct BalancedTernary {
|
|||
}
|
||||
|
||||
if (n == 0) return [];
|
||||
switch (((n % 3) + 3) % 3) { // (n % 3) is the remainder.
|
||||
// This final switch in D v.2.064 is fake, not enforced.
|
||||
final switch (((n % 3) + 3) % 3) { // (n % 3) is the remainder.
|
||||
case 0: return Dig.Z ~ _bint2ternary(py_div(n, 3));
|
||||
case 1: return Dig.P ~ _bint2ternary(py_div(n, 3));
|
||||
case 2: return Dig.N ~ _bint2ternary(py_div(n + 1, 3));
|
||||
default: assert(0, "Can't happen");
|
||||
}
|
||||
}
|
||||
|
||||
@property BigInt toBint() const {
|
||||
@property BigInt toBint() const pure /*nothrow*/ {
|
||||
return reduce!((y, x) => x + 3 * y)(0.BigInt, digits.retro);
|
||||
}
|
||||
|
||||
string toString() const {
|
||||
string toString() const pure nothrow {
|
||||
if (digits.empty) return "0";
|
||||
return digits.retro.map!(d => dig2str[d + 1]).array;
|
||||
}
|
||||
|
||||
static Dig[] neg_(Dig[] digs) {
|
||||
return digs.map!q{ -a }.array;
|
||||
static const(Dig)[] neg_(in Dig[] digs) pure nothrow {
|
||||
return digs.map!(a => -a).array;
|
||||
}
|
||||
|
||||
BalancedTernary opUnary(string op:"-")() {
|
||||
BalancedTernary opUnary(string op:"-")() const pure nothrow {
|
||||
return BalancedTernary(neg_(this.digits));
|
||||
}
|
||||
|
||||
static Dig[] add_(Dig[] a, Dig[] b, Dig c=Dig.Z) {
|
||||
auto a_or_b = a.length ? a : b;
|
||||
static const(Dig)[] add_(in Dig[] a, in Dig[] b, in Dig c=Dig.Z)
|
||||
pure nothrow {
|
||||
const a_or_b = a.length ? a : b;
|
||||
if (a.empty || b.empty) {
|
||||
if (c == Dig.Z)
|
||||
return a_or_b;
|
||||
|
|
@ -90,7 +91,7 @@ struct BalancedTernary {
|
|||
// (const d, c) = table[...];
|
||||
const dc = table[3 + (a.length ? a[0] : 0) +
|
||||
(b.length ? b[0] : 0) + c];
|
||||
auto res = add_(a[1 .. $], b[1 .. $], dc[1]);
|
||||
const res = add_(a[1 .. $], b[1 .. $], dc[1]);
|
||||
// Trim leading zeros.
|
||||
if (res.length || dc[0] != Dig.Z)
|
||||
return [dc[0]] ~ res;
|
||||
|
|
@ -99,19 +100,21 @@ struct BalancedTernary {
|
|||
}
|
||||
}
|
||||
|
||||
BalancedTernary opBinary(string op:"+")(BalancedTernary b) {
|
||||
BalancedTernary opBinary(string op:"+")(in BalancedTernary b)
|
||||
const pure nothrow {
|
||||
return BalancedTernary(add_(this.digits, b.digits));
|
||||
}
|
||||
|
||||
BalancedTernary opBinary(string op:"-")(BalancedTernary b) {
|
||||
BalancedTernary opBinary(string op:"-")(in BalancedTernary b)
|
||||
const pure nothrow {
|
||||
return this + (-b);
|
||||
}
|
||||
|
||||
static Dig[] mul_(in Dig[] a, /*in*/ Dig[] b) {
|
||||
static const(Dig)[] mul_(in Dig[] a, in Dig[] b) pure nothrow {
|
||||
if (a.empty || b.empty) {
|
||||
return [];
|
||||
} else {
|
||||
Dig[] y = Dig.Z ~ mul_(a[1 .. $], b);
|
||||
const y = Dig.Z ~ mul_(a[1 .. $], b);
|
||||
final switch (a[0]) {
|
||||
case Dig.N: return add_(neg_(b), y);
|
||||
case Dig.Z: return add_([], y);
|
||||
|
|
@ -120,21 +123,22 @@ struct BalancedTernary {
|
|||
}
|
||||
}
|
||||
|
||||
BalancedTernary opBinary(string op:"*")(BalancedTernary b) {
|
||||
BalancedTernary opBinary(string op:"*")(in BalancedTernary b)
|
||||
const pure nothrow {
|
||||
return BalancedTernary(mul_(this.digits, b.digits));
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto a = BalancedTernary("+-0++0+");
|
||||
writeln("a: ", a.toBint, " ", a);
|
||||
immutable a = BalancedTernary("+-0++0+");
|
||||
writeln("a: ", a.toBint, ' ', a);
|
||||
|
||||
auto b = BalancedTernary(-436);
|
||||
writeln("b: ", b.toBint, " ", b);
|
||||
immutable b = BalancedTernary(-436);
|
||||
writeln("b: ", b.toBint, ' ', b);
|
||||
|
||||
auto c = BalancedTernary("+-++-");
|
||||
writeln("c: ", c.toBint, " ", c);
|
||||
immutable c = BalancedTernary("+-++-");
|
||||
writeln("c: ", c.toBint, ' ', c);
|
||||
|
||||
auto r = a * (b - c);
|
||||
writeln("a * (b - c): ", r.toBint, " ", r);
|
||||
immutable r = a * (b - c);
|
||||
writeln("a * (b - c): ", r.toBint, ' ', r);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue