June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
|
|
@ -0,0 +1,8 @@
|
|||
div←{
|
||||
{
|
||||
q r d←⍵
|
||||
(≢d) > n←≢r : q r
|
||||
c ← (⊃⌽r) ÷ ⊃⌽d
|
||||
∇ (c,q) ((¯1↓r) - c × ¯1↓(-n)↑d) d
|
||||
} ⍬ ⍺ ⍵
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
(defn grevlex [term1 term2]
|
||||
(let [grade1 (reduce +' term1)
|
||||
grade2 (reduce +' term2)
|
||||
comp (- grade2 grade1)] ;; total degree
|
||||
(if (not= 0 comp)
|
||||
comp
|
||||
(loop [term1 term1
|
||||
term2 term2]
|
||||
(if (empty? term1)
|
||||
0
|
||||
(let [grade1 (last term1)
|
||||
grade2 (last term2)
|
||||
comp (- grade1 grade2)] ;; differs from grlex because terms are flipped from above
|
||||
(if (not= 0 comp)
|
||||
comp
|
||||
(recur (pop term1)
|
||||
(pop term2)))))))))
|
||||
|
||||
(defn mul
|
||||
;; transducer
|
||||
([poly1] ;; completion
|
||||
(fn
|
||||
([] poly1)
|
||||
([poly2] (mul poly1 poly2))
|
||||
([poly2 & more] (mul poly1 poly2 more))))
|
||||
([poly1 poly2]
|
||||
(let [product (atom (transient (sorted-map-by grevlex)))]
|
||||
(doall ;; `for` is lazy so must to be forced for side-effects
|
||||
(for [term1 poly1
|
||||
term2 poly2
|
||||
:let [vars (mapv +' (key term1) (key term2))
|
||||
coeff (* (val term1) (val term2))]]
|
||||
(if (contains? @product vars)
|
||||
(swap! product assoc! vars (+ (get @product vars) coeff))
|
||||
(swap! product assoc! vars coeff))))
|
||||
(->> product
|
||||
(deref)
|
||||
(persistent!)
|
||||
(denull))))
|
||||
([poly1 poly2 & more]
|
||||
(reduce mul (mul poly1 poly2) more)))
|
||||
|
||||
(defn compl [term1 term2]
|
||||
(map (fn [x y]
|
||||
(cond
|
||||
(and (zero? x) (not= 0 y)) nil
|
||||
(< x y) nil
|
||||
(>= x y) (- x y)))
|
||||
term1
|
||||
term2))
|
||||
|
||||
(defn s-poly [f g]
|
||||
(let [f-vars (first f)
|
||||
g-vars (first g)
|
||||
lcm (compl f-vars g-vars)]
|
||||
(if (not-any? nil? lcm)
|
||||
{(vec lcm)
|
||||
(/ (second f) (second g))})))
|
||||
|
||||
(defn divide [f g]
|
||||
(loop [f f
|
||||
g g
|
||||
result (transient {})
|
||||
remainder {}]
|
||||
(if (empty? f)
|
||||
(list (persistent! result)
|
||||
(->> remainder
|
||||
(filter #(not (nil? %)))
|
||||
(into (sorted-map-by grevlex))))
|
||||
(let [term1 (first f)
|
||||
term2 (first g)
|
||||
s-term (s-poly term1 term2)]
|
||||
(if (nil? s-term)
|
||||
(recur (dissoc f (first term1))
|
||||
(dissoc g (first term2))
|
||||
result
|
||||
(conj remainder term1))
|
||||
(recur (sub f (mul g s-term))
|
||||
g
|
||||
(conj! result s-term)
|
||||
remainder))))))
|
||||
|
||||
(deftest divide-tests
|
||||
(is (= (divide {[1 1] 2, [1 0] 3, [0 1] 5, [0 0] 7}
|
||||
{[1 1] 2, [1 0] 3, [0 1] 5, [0 0] 7})
|
||||
'({[0 0] 1} {})))
|
||||
(is (= (divide {[1 1] 2, [1 0] 3, [0 1] 5, [0 0] 7}
|
||||
{[0 0] 1})
|
||||
'({[1 1] 2, [1 0] 3, [0 1] 5, [0 0] 7} {})))
|
||||
(is (= (divide {[1 1] 2, [1 0] 10, [0 1] 3, [0 0] 15}
|
||||
{[0 1] 1, [0 0] 5})
|
||||
'({[1 0] 2, [0 0] 3} {})))
|
||||
(is (= (divide {[1 1] 2, [1 0] 10, [0 1] 3, [0 0] 15}
|
||||
{[1 0] 2, [0 0] 3})
|
||||
'({[0 1] 1, [0 0] 5} {}))))
|
||||
118
Task/Polynomial-long-division/Java/polynomial-long-division.java
Normal file
118
Task/Polynomial-long-division/Java/polynomial-long-division.java
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
import java.util.Arrays;
|
||||
|
||||
public class PolynomialLongDivision {
|
||||
private static class Solution {
|
||||
double[] quotient, remainder;
|
||||
|
||||
Solution(double[] q, double[] r) {
|
||||
this.quotient = q;
|
||||
this.remainder = r;
|
||||
}
|
||||
}
|
||||
|
||||
private static int polyDegree(double[] p) {
|
||||
for (int i = p.length - 1; i >= 0; --i) {
|
||||
if (p[i] != 0.0) return i;
|
||||
}
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
private static double[] polyShiftRight(double[] p, int places) {
|
||||
if (places <= 0) return p;
|
||||
int pd = polyDegree(p);
|
||||
if (pd + places >= p.length) {
|
||||
throw new IllegalArgumentException("The number of places to be shifted is too large");
|
||||
}
|
||||
double[] d = Arrays.copyOf(p, p.length);
|
||||
for (int i = pd; i >= 0; --i) {
|
||||
d[i + places] = d[i];
|
||||
d[i] = 0.0;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
private static void polyMultiply(double[] p, double m) {
|
||||
for (int i = 0; i < p.length; ++i) {
|
||||
p[i] *= m;
|
||||
}
|
||||
}
|
||||
|
||||
private static void polySubtract(double[] p, double[] s) {
|
||||
for (int i = 0; i < p.length; ++i) {
|
||||
p[i] -= s[i];
|
||||
}
|
||||
}
|
||||
|
||||
private static Solution polyLongDiv(double[] n, double[] d) {
|
||||
if (n.length != d.length) {
|
||||
throw new IllegalArgumentException("Numerator and denominator vectors must have the same size");
|
||||
}
|
||||
int nd = polyDegree(n);
|
||||
int dd = polyDegree(d);
|
||||
if (dd < 0) {
|
||||
throw new IllegalArgumentException("Divisor must have at least one one-zero coefficient");
|
||||
}
|
||||
if (nd < dd) {
|
||||
throw new IllegalArgumentException("The degree of the divisor cannot exceed that of the numerator");
|
||||
}
|
||||
double[] n2 = Arrays.copyOf(n, n.length);
|
||||
double[] q = new double[n.length];
|
||||
while (nd >= dd) {
|
||||
double[] d2 = polyShiftRight(d, nd - dd);
|
||||
q[nd - dd] = n2[nd] / d2[nd];
|
||||
polyMultiply(d2, q[nd - dd]);
|
||||
polySubtract(n2, d2);
|
||||
nd = polyDegree(n2);
|
||||
}
|
||||
return new Solution(q, n2);
|
||||
}
|
||||
|
||||
private static void polyShow(double[] p) {
|
||||
int pd = polyDegree(p);
|
||||
for (int i = pd; i >= 0; --i) {
|
||||
double coeff = p[i];
|
||||
if (coeff == 0.0) continue;
|
||||
if (coeff == 1.0) {
|
||||
if (i < pd) {
|
||||
System.out.print(" + ");
|
||||
}
|
||||
} else if (coeff == -1.0) {
|
||||
if (i < pd) {
|
||||
System.out.print(" - ");
|
||||
} else {
|
||||
System.out.print("-");
|
||||
}
|
||||
} else if (coeff < 0.0) {
|
||||
if (i < pd) {
|
||||
System.out.printf(" - %.1f", -coeff);
|
||||
} else {
|
||||
System.out.print(coeff);
|
||||
}
|
||||
} else {
|
||||
if (i < pd) {
|
||||
System.out.printf(" + %.1f", coeff);
|
||||
} else {
|
||||
System.out.print(coeff);
|
||||
}
|
||||
}
|
||||
if (i > 1) System.out.printf("x^%d", i);
|
||||
else if (i == 1) System.out.print("x");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
double[] n = new double[]{-42.0, 0.0, -12.0, 1.0};
|
||||
double[] d = new double[]{-3.0, 1.0, 0.0, 0.0};
|
||||
System.out.print("Numerator : ");
|
||||
polyShow(n);
|
||||
System.out.print("Denominator : ");
|
||||
polyShow(d);
|
||||
System.out.println("-------------------------------------");
|
||||
Solution sol = polyLongDiv(n, d);
|
||||
System.out.print("Quotient : ");
|
||||
polyShow(sol.quotient);
|
||||
System.out.print("Remainder : ");
|
||||
polyShow(sol.remainder);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
// version 1.1.51
|
||||
|
||||
typealias IAE = IllegalArgumentException
|
||||
|
||||
data class Solution(val quotient: DoubleArray, val remainder: DoubleArray)
|
||||
|
||||
fun polyDegree(p: DoubleArray): Int {
|
||||
for (i in p.size - 1 downTo 0) {
|
||||
if (p[i] != 0.0) return i
|
||||
}
|
||||
return Int.MIN_VALUE
|
||||
}
|
||||
|
||||
fun polyShiftRight(p: DoubleArray, places: Int): DoubleArray {
|
||||
if (places <= 0) return p
|
||||
val pd = polyDegree(p)
|
||||
if (pd + places >= p.size) {
|
||||
throw IAE("The number of places to be shifted is too large")
|
||||
}
|
||||
val d = p.copyOf()
|
||||
for (i in pd downTo 0) {
|
||||
d[i + places] = d[i]
|
||||
d[i] = 0.0
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
fun polyMultiply(p: DoubleArray, m: Double) {
|
||||
for (i in 0 until p.size) p[i] *= m
|
||||
}
|
||||
|
||||
fun polySubtract(p: DoubleArray, s: DoubleArray) {
|
||||
for (i in 0 until p.size) p[i] -= s[i]
|
||||
}
|
||||
|
||||
fun polyLongDiv(n: DoubleArray, d: DoubleArray): Solution {
|
||||
if (n.size != d.size) {
|
||||
throw IAE("Numerator and denominator vectors must have the same size")
|
||||
}
|
||||
var nd = polyDegree(n)
|
||||
val dd = polyDegree(d)
|
||||
if (dd < 0) {
|
||||
throw IAE("Divisor must have at least one one-zero coefficient")
|
||||
}
|
||||
if (nd < dd) {
|
||||
throw IAE("The degree of the divisor cannot exceed that of the numerator")
|
||||
}
|
||||
val n2 = n.copyOf()
|
||||
val q = DoubleArray(n.size) // all elements zero by default
|
||||
while (nd >= dd) {
|
||||
val d2 = polyShiftRight(d, nd - dd)
|
||||
q[nd - dd] = n2[nd] / d2[nd]
|
||||
polyMultiply(d2, q[nd - dd])
|
||||
polySubtract(n2, d2)
|
||||
nd = polyDegree(n2)
|
||||
}
|
||||
return Solution(q, n2)
|
||||
}
|
||||
|
||||
fun polyShow(p: DoubleArray) {
|
||||
val pd = polyDegree(p)
|
||||
for (i in pd downTo 0) {
|
||||
val coeff = p[i]
|
||||
if (coeff == 0.0) continue
|
||||
print (when {
|
||||
coeff == 1.0 -> if (i < pd) " + " else ""
|
||||
coeff == -1.0 -> if (i < pd) " - " else "-"
|
||||
coeff < 0.0 -> if (i < pd) " - ${-coeff}" else "$coeff"
|
||||
else -> if (i < pd) " + $coeff" else "$coeff"
|
||||
})
|
||||
if (i > 1) print("x^$i")
|
||||
else if (i == 1) print("x")
|
||||
}
|
||||
println()
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val n = doubleArrayOf(-42.0, 0.0, -12.0, 1.0)
|
||||
val d = doubleArrayOf( -3.0, 1.0, 0.0, 0.0)
|
||||
print("Numerator : ")
|
||||
polyShow(n)
|
||||
print("Denominator : ")
|
||||
polyShow(d)
|
||||
println("-------------------------------------")
|
||||
val (q, r) = polyLongDiv(n, d)
|
||||
print("Quotient : ")
|
||||
polyShow(q)
|
||||
print("Remainder : ")
|
||||
polyShow(r)
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/* REXX needed by some... */
|
||||
z='1 -12 0 -42' /* Numerator */
|
||||
n='1 -3' /* Denominator */
|
||||
zx=z
|
||||
nx=n copies('0 ',words(z)-words(n))
|
||||
qx='' /* Quotient */
|
||||
Do Until words(zx)<words(n)
|
||||
Parse Value div(zx,nx) With q zx
|
||||
qx=qx q
|
||||
nx=subword(nx,1,words(nx)-1)
|
||||
End
|
||||
Say '('show(z)')/('show(n)')=('show(qx)')'
|
||||
Say 'Remainder:' show(zx)
|
||||
Exit
|
||||
div: Procedure
|
||||
Parse Arg z,n
|
||||
q=word(z,1)/word(n,1)
|
||||
zz=''
|
||||
Do i=1 To words(z)
|
||||
zz=zz word(z,i)-q*word(n,i)
|
||||
End
|
||||
Return q subword(zz,2)
|
||||
|
||||
show: Procedure
|
||||
Parse Arg poly
|
||||
d=words(poly)-1
|
||||
res=''
|
||||
Do i=1 To words(poly)
|
||||
Select
|
||||
When d>1 Then fact='*x**'d
|
||||
When d=1 Then fact='*x'
|
||||
Otherwise fact=''
|
||||
End
|
||||
Select
|
||||
When word(poly,i)=0 Then p=''
|
||||
When word(poly,i)=1 Then p='+'substr(fact,2)
|
||||
When word(poly,i)=-1 Then p='-'substr(fact,2)
|
||||
When word(poly,i)<0 Then p=word(poly,i)||fact
|
||||
Otherwise p='+'word(poly,i)||fact
|
||||
End
|
||||
res=res p
|
||||
d=d-1
|
||||
End
|
||||
Return strip(space(res,0),'L','+')
|
||||
Loading…
Add table
Add a link
Reference in a new issue