Polynomial long division: Difference between revisions

Content added Content deleted
(Updated D entry)
Line 687: Line 687:
((0 . -123)) ; -123</lang>
((0 . -123)) ; -123</lang>
=={{header|D}}==
=={{header|D}}==
<lang d>import std.stdio, std.range, std.algorithm, std.typecons;
<lang d>import std.stdio, std.range, std.algorithm, std.typecons, std.array;


Tuple!(double[],double[]) polyDiv(in double[] inN, in double[] inD)
Tuple!(double[], double[]) polyDiv(in double[] inN, in double[] inD)
/*pure nothrow*/ {
pure /*nothrow*/ {
// code smell: a function that does two things
// Code smell: a function that does two things.
static int trimAndDegree(T)(ref T[] poly) /*nothrow pure*/ {
static int trimAndDegree(T)(ref T[] poly) nothrow pure {
poly.length -= poly.retro().countUntil!q{a != 0}();
poly = poly.retro.find!q{ a != b }(0.0).retro;
return (cast(int)poly.length) - 1;
return (cast(int)poly.length) - 1;
}
}


double[] N = inN.dup;
double[] N = inN.dup; // Not nothrow.
const(double)[] D = inD;
const(double)[] D = inD;
const dD = trimAndDegree(D);
const dD = trimAndDegree(D);
auto dN = trimAndDegree(N);
auto dN = trimAndDegree(N);
double[] q, r;
double[] q;
if (dD < 0)
if (dD < 0)
throw new Exception("ZeroDivisionError");
throw new Error("ZeroDivisionError");
if (dN >= dD) {
if (dN >= dD) {
q = repeat(0.0).take(dN).array();
//q = [0.0].replicate(dN);
q = std.array.replicate([0.0], dN);
while (dN >= dD) {
while (dN >= dD) {
auto d = repeat(0.0).take(dN - dD).array() ~ D;
auto d = std.array.replicate([0.0], dN - dD) ~ D;
const mult = q[dN - dD] = N[$ - 1] / d[$ - 1];
immutable mult = q[dN - dD] = N[$ - 1] / d[$ - 1];
d[] *= mult;
d[] *= mult;
N[] -= d[];
N[] -= d[];
dN = trimAndDegree(N);
dN = trimAndDegree(N);
}
}
} else {
} else
q = [0.0];
q = [0.0];
return tuple(q, N);
}
}
r = N;

return tuple(q, r);

int trimAndDegree1(T)(ref T[] poly) nothrow pure {
poly.length -= poly.retro.countUntil!q{ a != 0 };
return (cast(int)poly.length) - 1;
}
}


Line 723: Line 728:
immutable N = [-42.0, 0.0, -12.0, 1.0];
immutable N = [-42.0, 0.0, -12.0, 1.0];
immutable D = [-3.0, 1.0, 0.0, 0.0];
immutable D = [-3.0, 1.0, 0.0, 0.0];
writefln("%s / %s = %s remainder %s", N, D, polyDiv(N,D).tupleof);
writefln("%s / %s = %s remainder %s", N, D, polyDiv(N, D)[]);
}</lang>
}</lang>
{{out}}
{{out}}