  import java.awt.*;
  import java.awt.event.*;
  import java.awt.geom.*;
  import javax.swing.JApplet;
  import javax.swing.JFrame;
  public class Plot2d extends JApplet {
    double[] xi;
    double[] yi;
    public Plot2d(double[] x, double[] y) {
        this.xi = x;
        this.yi = y;
    }
    public static double max(double[] t) {
        double maximum = t[0];
        for (int i = 1; i < t.length; i++) {
            if (t[i] > maximum) {
                maximum = t[i];
            }
        }
        return maximum;
    }
    public static double min(double[] t) {
        double minimum = t[0];
        for (int i = 1; i < t.length; i++) {
            if (t[i] < minimum) {
                minimum = t[i];
            }
        }
        return minimum;
    }
    public void init() {
        setBackground(Color.white);
        setForeground(Color.white);
    }
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(Color.black);
        int x0 = 70;
        int y0 = 10;
        int xm = 670;
        int ym = 410;
        int xspan = xm - x0;
        int yspan = ym - y0;
        double xmax = max(xi);
        double xmin = min(xi);
        double ymax = max(yi);
        double ymin = min(yi);
        g2.draw(new double+java.sun.com&btnI=I%27m%20Feeling%20Lucky">Line2D.Double(x0, ym, xm, ym));
        g2.draw(new double+java.sun.com&btnI=I%27m%20Feeling%20Lucky">Line2D.Double(x0, ym, x0, y0));
        for (int j = 0; j < 5; j++) {
            int interv = 4;
            g2.drawString("" + (j * (xmax - xmin) / interv + xmin), j * xspan / interv + x0 - 10, ym + 20);
            g2.drawString("" + (j * (ymax - ymin) / interv + ymin), x0 - 20 - (int) (9 * Math.log10(ymax)),
 ym - j * yspan / interv + y0 - 5);
            g2.draw(new double+java.sun.com&btnI=I%27m%20Feeling%20Lucky">Line2D.Double(j * xspan / interv + x0, ym, j * xspan / interv + x0, ym + 5));
            g2.draw(new double+java.sun.com&btnI=I%27m%20Feeling%20Lucky">Line2D.Double(x0 - 5, j * yspan / interv + y0, x0, j * yspan / interv + y0));
        }
        for (int i = 0; i < xi.length; i++) {
            int f = (int) ((xi[i] - xmin) * xspan / (xmax - xmin));
            int h = (int) (((ymax - ymin) - (yi[i] - ymin)) * yspan / (ymax - ymin));
            g2.drawString("o", x0 + f - 3, h + 14);
        }
        for (int i = 0; i < xi.length - 1; i++) {
            int f = (int) ((xi[i] - xmin) * xspan / (xmax - xmin));
            int f2 = (int) ((xi[i + 1] - xmin) * xspan / (xmax - xmin));
            int h = (int) (((ymax - ymin) - (yi[i] - ymin)) * yspan / (ymax - ymin));
            int h2 = (int) (((ymax - ymin) - (yi[i + 1] - ymin)) * yspan / (ymax - ymin));
            g2.draw(new double+java.sun.com&btnI=I%27m%20Feeling%20Lucky">Line2D.Double(f + x0, h + y0, f2 + x0, h2 + y0));
        }
    }
    public static void main(String args[]) {
        JFrame f = new JFrame("ShapesDemo2D");
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        double[] r = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        double[] t = {2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.09};
        JApplet applet = new Plot2d(r, t);
        f.getContentPane().add("Center", applet);
        applet.init();
        f.pack();
        f.setSize(new Dimension(720, 480));
        f.show();
    }
  }


div←{
    {
        q r d←⍵
        (≢d) > n←≢r : q r
        c ← (⊃⌽r) ÷ ⊃⌽d
        ∇ (c,q) ((¯1↓r) - c × ¯1↓(-n)↑d) d
    } ⍬ ⍺ ⍵
}


      DIM N%(3) : N%() = -42, 0, -12, 1
      DIM D%(3) : D%() =  -3, 1,   0, 0
      DIM q%(3), r%(3)
      PROC_poly_long_div(N%(), D%(), q%(), r%())
      PRINT "Quotient = "; FNcoeff(q%(2)) "x^2" FNcoeff(q%(1)) "x" FNcoeff(q%(0))
      PRINT "Remainder = " ; r%(0)
      END

      DEF PROC_poly_long_div(N%(), D%(), q%(), r%())
      LOCAL d%(), i%, s%
      DIM d%(DIM(N%(),1))
      s% = FNdegree(N%()) - FNdegree(D%())
      IF s% >= 0 THEN
        q%() = 0
        WHILE s% >= 0
          FOR i% = 0 TO DIM(d%(),1) - s%
            d%(i%+s%) = D%(i%)
          NEXT
          q%(s%) = N%(FNdegree(N%())) DIV d%(FNdegree(d%()))
          d%() = d%() * q%(s%)
          N%() -= d%()
          s% = FNdegree(N%()) - FNdegree(D%())
        ENDWHILE
        r%() = N%()
      ELSE
        q%() = 0
        r%() = N%()
      ENDIF
      ENDPROC

      DEF FNdegree(a%())
      LOCAL i%
      i% = DIM(a%(),1)
      WHILE a%(i%)=0
        i% -= 1
        IF i%<0 EXIT WHILE
      ENDWHILE
      = i%

      DEF FNcoeff(n%)
      IF n%=0 THEN = ""
      IF n%<0 THEN = " - " + STR$(-n%)
      IF n%=1 THEN = " + "
      = " + " + STR$(n%)


jq -n -M -r -f plot.jq | R CMD BATCH plot.R


// Version 1.2.31

import org.jfree.chart.ChartFactory
import org.jfree.chart.ChartPanel
import org.jfree.data.xy.XYSeries
import org.jfree.data.xy.XYSeriesCollection
import org.jfree.chart.plot.PlotOrientation
import javax.swing.JFrame
import javax.swing.SwingUtilities
import java.awt.BorderLayout

fun main(args: Array<String>) {
    val x = intArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    val y = doubleArrayOf(
        2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0
    )
    val series = XYSeries("plots")
    (0 until x.size).forEach { series.add(x[it], y[it]) }
    val labels = arrayOf("Plot Demo", "X", "Y")
    val data = XYSeriesCollection(series)
    val options = booleanArrayOf(false, true, false)
    val orient = PlotOrientation.VERTICAL
    val chart = ChartFactory.createXYLineChart(
        labels[0], labels[1], labels[2], data, orient, options[0], options[1], options[2]
    )
    val chartPanel = ChartPanel(chart)
    SwingUtilities.invokeLater {
        val f = JFrame()
        with(f) {
            defaultCloseOperation = JFrame.EXIT_ON_CLOSE
            add(chartPanel, BorderLayout.CENTER)
            title = "Plot coordinate pairs"
            isResizable = false
            pack()
            setLocationRelativeTo(null)
            isVisible = true
        }
    }
}


#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
#include <gsl/gsl_vector.h>

#define MAX(A,B) (((A)>(B))?(A):(B))

void reoshift(gsl_vector *v, int h)
{
  if ( h > 0 ) {
    gsl_vector *temp = gsl_vector_alloc(v->size);
    gsl_vector_view p = gsl_vector_subvector(v, 0, v->size - h);
    gsl_vector_view p1 = gsl_vector_subvector(temp, h, v->size - h);
    gsl_vector_memcpy(&p1.vector, &p.vector);
    p = gsl_vector_subvector(temp, 0, h);
    gsl_vector_set_zero(&p.vector);
    gsl_vector_memcpy(v, temp);
    gsl_vector_free(temp);
  }
}

gsl_vector *poly_long_div(gsl_vector *n, gsl_vector *d, gsl_vector **r)
{
  gsl_vector *nt = NULL, *dt = NULL, *rt = NULL, *d2 = NULL, *q = NULL;
  int gn, gt, gd;

  if ( (n->size >= d->size) && (d->size > 0) && (n->size > 0) ) {
    nt = gsl_vector_alloc(n->size); assert(nt != NULL);
    dt = gsl_vector_alloc(n->size); assert(dt != NULL);
    rt = gsl_vector_alloc(n->size); assert(rt != NULL);
    d2 = gsl_vector_alloc(n->size); assert(d2 != NULL);
    gsl_vector_memcpy(nt, n);
    gsl_vector_set_zero(dt); gsl_vector_set_zero(rt);
    gsl_vector_view p = gsl_vector_subvector(dt, 0, d->size);
    gsl_vector_memcpy(&p.vector, d);
    gsl_vector_memcpy(d2, dt);
    gn = n->size - 1;
    gd = d->size - 1;
    gt = 0;

    while( gsl_vector_get(d, gd) == 0 ) gd--;

    while ( gn >= gd ) {
      reoshift(dt, gn-gd);
      double v = gsl_vector_get(nt, gn)/gsl_vector_get(dt, gn);
      gsl_vector_set(rt, gn-gd, v);
      gsl_vector_scale(dt, v);
      gsl_vector_sub(nt, dt);
      gt = MAX(gt, gn-gd);
      while( (gn>=0) && (gsl_vector_get(nt, gn) == 0.0) ) gn--;
      gsl_vector_memcpy(dt, d2);
    }

    q = gsl_vector_alloc(gt+1); assert(q != NULL);
    p = gsl_vector_subvector(rt, 0, gt+1);
    gsl_vector_memcpy(q, &p.vector);
    if ( r != NULL ) {
      if ( (gn+1) > 0 ) {
	*r = gsl_vector_alloc(gn+1); assert( *r != NULL );
	p = gsl_vector_subvector(nt, 0, gn+1);
	gsl_vector_memcpy(*r, &p.vector);
      } else {
	*r = gsl_vector_alloc(1); assert( *r != NULL );
	gsl_vector_set_zero(*r);
      }
    }
    gsl_vector_free(nt); gsl_vector_free(dt);
    gsl_vector_free(rt); gsl_vector_free(d2);
    return q;
  } else {
    q = gsl_vector_alloc(1); assert( q != NULL );
    gsl_vector_set_zero(q);
    if ( r != NULL ) {
      *r = gsl_vector_alloc(n->size); assert( *r != NULL );
      gsl_vector_memcpy(*r, n);
    }
    return q;
  }
}

void poly_print(gsl_vector *p)
{
  int i;
  for(i=p->size-1; i >= 0; i--) {
    if ( i > 0 )
      printf("%lfx^%d + ",
	     gsl_vector_get(p, i), i);
    else
      printf("%lf\n", gsl_vector_get(p, i));
  }
}

gsl_vector *create_poly(int d, ...)
{
  va_list al;
  int i;
  gsl_vector *r = NULL;

  va_start(al, d);
  r = gsl_vector_alloc(d); assert( r != NULL );

  for(i=0; i < d; i++)
    gsl_vector_set(r, i, va_arg(al, double));

  return r;
}


1) define X & Y:

{def X 0 1 2 3 4 5 7 8 9}
-> X
{def Y 2.7 2.8 31.4 38.1 58.0 76.2 100.5 130.0 149.3 180.0}
-> Y

2) define a function returning a sequence of SVG points

{def curve
 {lambda {:curve :kx :ky}
  {S.map {{lambda {:curve :kx :ky :i}
                  {* :kx {S.get :i {{car :curve}}}}
                  {* :ky {S.get :i {{cdr :curve}}}} } :curve :kx :ky}
         {S.serie 0 {- {S.length {X}} 1}} }}}

3) draw a polyline in a SVG context

{svg {@ width="580" height="300" style="background:#eee"}
 {g {AXES 580 300}
  {polyline {@ points="{curve {cons X Y} 30 0.9}"
               stroke="#000" fill="transparent" stroke-width="1"}} }}

where

{def AXES
 {lambda {:w :h}
  {@ transform="translate({/ :w 2},{/ :h 2}) scale(1,-1)"}
  {line {@ x1="-{/ :w 2}:w" y1="0"
           x2="{/ :w 2}" y2="0"
           stroke="red" fill="transparent"}}
  {line {@ x1="0" y1="-{/ :h 2}"
           x2="0" y2="{/ :h 2}"
           stroke="green" fill="transparent"}} }}

4) the result can be seen in http://lambdaway.free.fr/lambdawalks/?view=plot4


using System;

namespace PolynomialLongDivision {
    class Solution {
        public Solution(double[] q, double[] r) {
            Quotient = q;
            Remainder = r;
        }

        public double[] Quotient { get; }
        public double[] Remainder { get; }
    }

    class Program {
        static int PolyDegree(double[] p) {
            for (int i = p.Length - 1; i >= 0; --i) {
                if (p[i] != 0.0) return i;
            }
            return int.MinValue;
        }

        static double[] PolyShiftRight(double[] p, int places) {
            if (places <= 0) return p;
            int pd = PolyDegree(p);
            if (pd + places >= p.Length) {
                throw new ArgumentOutOfRangeException("The number of places to be shifted is too large");
            }
            double[] d = new double[p.Length];
            p.CopyTo(d, 0);
            for (int i = pd; i >= 0; --i) {
                d[i + places] = d[i];
                d[i] = 0.0;
            }
            return d;
        }

        static void PolyMultiply(double[] p, double m) {
            for (int i = 0; i < p.Length; ++i) {
                p[i] *= m;
            }
        }

        static void PolySubtract(double[] p, double[] s) {
            for (int i = 0; i < p.Length; ++i) {
                p[i] -= s[i];
            }
        }

        static Solution PolyLongDiv(double[] n, double[] d) {
            if (n.Length != d.Length) {
                throw new ArgumentException("Numerator and denominator vectors must have the same size");
            }
            int nd = PolyDegree(n);
            int dd = PolyDegree(d);
            if (dd < 0) {
                throw new ArgumentException("Divisor must have at least one one-zero coefficient");
            }
            if (nd < dd) {
                throw new ArgumentException("The degree of the divisor cannot exceed that of the numerator");
            }
            double[] n2 = new double[n.Length];
            n.CopyTo(n2, 0);
            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);
        }

        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) {
                        Console.Write(" + ");
                    }
                } else if (coeff == -1.0) {
                    if (i < pd) {
                        Console.Write(" - ");
                    } else {
                        Console.Write("-");
                    }
                } else if (coeff < 0.0) {
                    if (i < pd) {
                        Console.Write(" - {0:F1}", -coeff);
                    } else {
                        Console.Write("{0:F1}", coeff);
                    }
                } else {
                    if (i < pd) {
                        Console.Write(" + {0:F1}", coeff);
                    } else {
                        Console.Write("{0:F1}", coeff);
                    }
                }
                if (i > 1) Console.Write("x^{0}", i);
                else if (i == 1) Console.Write("x");
            }
            Console.WriteLine();
        }

        static void Main(string[] args) {
            double[] n = { -42.0, 0.0, -12.0, 1.0 };
            double[] d = { -3.0, 1.0, 0.0, 0.0 };
            Console.Write("Numerator   : ");
            PolyShow(n);
            Console.Write("Denominator : ");
            PolyShow(d);
            Console.WriteLine("-------------------------------------");
            Solution sol = PolyLongDiv(n, d);
            Console.Write("Quotient    : ");
            PolyShow(sol.Quotient);
            Console.Write("Remainder   : ");
            PolyShow(sol.Remainder);
        }
    }
}


on plotGraphic
    local tCoordinates
    local x = "0,   1,    2,    3,    4,    5,     6,     7,     8,     9"
    local y = "2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0"
    if there is a graphic "graph" then delete graphic "graph"
    repeat with i = 1 to the  number of items of x
        put item i of x into item 1 of line i of tCoordinates
        put item i of y into item 2 of line i of tCoordinates
    end repeat
    create graphic "graph"
    set the style of graphic "graph" to "polygon"
    set the points of graphic "graph" to tCoordinates

    repeat with i = 1 to the number of lines of tCoordinates
        put the top of grc "graph" + the height of grc "graph" - item 2 of line i of tCoordinates into item 2 of line i of tCoordinates
    end repeat
    set the points of graphic "graph" to tCoordinates

    set the height of graphic "graph" to 200
    set the width of graphic "graph" to 300
    set the loc of grc "graph" to the loc of this card
end plotGraphic


#include <iostream>
#include <iterator>
#include <vector>

using namespace std;
typedef vector<double> Poly;

// does:  prints all members of vector
// input: c - ASCII char with the name of the vector
//        A - reference to polynomial (vector)
void Print(char name, const Poly &A) {
	cout << name << "(" << A.size()-1 << ") = [ ";
	copy(A.begin(), A.end(), ostream_iterator<decltype(A[0])>(cout, " "));
	cout << "]\n";
}

int main() {
	Poly N, D, d, q, r;        // vectors - N / D == q && N % D == r
	size_t dN, dD, dd, dq, dr; // degrees of vectors
	size_t i;                  // loop counter

	// setting the degrees of vectors
	cout << "Enter the degree of N: ";
	cin >> dN;
	cout << "Enter the degree of D: ";
	cin >> dD;
	dq = dN-dD;
	dr = dN-dD;

	if( dD < 1 || dN < 1 ) {
		cerr << "Error: degree of D and N must be positive.\n";
		return 1;
	}

	// allocation and initialization of vectors
	N.resize(dN+1);
	cout << "Enter the coefficients of N:"<<endl;
	for ( i = 0; i <= dN; i++ ) {
		cout << "N[" << i << "]= ";
		cin >> N[i];
	}

	D.resize(dN+1);
	cout << "Enter the coefficients of D:"<<endl;
	for ( i = 0; i <= dD; i++ ) {
		cout << "D[" << i << "]= ";
		cin >> D[i];
	}

	d.resize(dN+1);
	q.resize(dq+1);
	r.resize(dr+1);

	cout << "-- Procedure --" << endl << endl;
	if( dN >= dD ) {
		while(dN >= dD) {
			// d equals D shifted right
			d.assign(d.size(), 0);

			for( i = 0 ; i <= dD ; i++ )
				d[i+dN-dD] = D[i];
			dd = dN;

			Print( 'd', d );

			// calculating one element of q
			q[dN-dD] = N[dN]/d[dd];

			Print( 'q', q );

			// d equals d * q[dN-dD]
			for( i = 0 ; i < dq + 1 ; i++ )
				d[i] = d[i] * q[dN-dD];

			Print( 'd', d );

			// N equals N - d
			for( i = 0 ; i < dN + 1 ; i++ )
				N[i] = N[i] - d[i];
			dN--;

			Print( 'N', N );
			cout << "-----------------------" << endl << endl;

		}
	}

	// r equals N
	for( i = 0 ; i <= dN ; i++ )
		r[i] = N[i];

	cout << "=========================" << endl << endl;
	cout << "-- Result --" << endl << endl;

	Print( 'q', q );
	Print( 'r', r );
}


w_width = love.graphics.getWidth()
w_height = love.graphics.getHeight()

x = {0,1,2,3,4,5,6,7,8,9}
y = {2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0}
origin = {24,24}
points = {}
x_unit = w_width/x[10]/2
y_unit = w_height/10

--add points to an array properly formatted for the line function
for i=1,10,1 do
  table.insert(points, (x[i]*x_unit) + origin[1])
  table.insert(points, (w_height-(y[i]*2)) - origin[2])
end

function love.draw()

  --draw axes and grid
  love.graphics.setColor(0, 0.8, 0)
  --draw x axis
  love.graphics.line(origin[1], w_height-origin[2], w_width, w_height-origin[2])
  --draw y axis
  love.graphics.line(origin[1], w_height-origin[2], origin[1], origin[2])
  --draw grid
  for i=1,20,1 do
    love.graphics.line(origin[1], (w_height-origin[2])-(i*y_unit), w_width, (w_height-origin[2])-(i*y_unit))
    love.graphics.line(origin[1]+(i*x_unit), origin[2], origin[1]+(i*x_unit), w_height-origin[2])
  end

  --draw line plot
  love.graphics.setColor(0.8, 0, 0)
  love.graphics.line(points)

  --draw labels
  love.graphics.setColor(0.8, 0.8, 0.8)
  for i=0,9,1 do
    --draw x axis labels
    love.graphics.print(i, (x_unit*i) + origin[1], love.graphics.getHeight()-origin[2])
    --draw y axis labels
    love.graphics.print(i*y_unit/2, origin[1], ((love.graphics.getHeight()-i*y_unit)-origin[2]))
  end

end


(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} {}))))


Module Pairs {
      \\ written in version 9.5 rev. 13
      \\ use Gdi+ antialiasing (not work with Wine in Linux, but we get no error)
      smooth on
      Const center=2, right=3, left=1, blue=1, angle=0, dotline=3
      Const size9pt=9, size11pt=11
      Cls ,0    ' use current background color, set split screen from line 0
      Cursor 0,3
      Report center, "Coordinate pairs"
      x = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
      y = (2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0)
      dx=scale.x/2/len(x)
      dy=dx 'ratio 1:1
      graH=dy*len(x)
      Basex=scale.x/4
      Basey=(scale.y+graH)/2
      Move Basex, Basey
      \\ draw use relative coordinates
      Draw 0,-graH
      \\ Step just move graphic cursor
      Step 0, graH
      Draw scale.x/2
      Step -scale.x/2
      \\ scX is 1, not used
      max=Y#max()
      \\ Auto scale for Y, using 0 for start of axis Y
      scY=-graH/((max+5^log(max) ) div 100)/100
      \\ make vertical axis using dots with numbers center per dx
      j=1
      For i=basex+dx to basex+dx*x#max() Step dx
            Move i, basey
            Step 0, twipsy*10
            Legend format$("{0}",array(x,j)), "courier", size9pt, angle, center
            Width 1, dotline { draw 0, -graH-twipsy*10,7}
            j++
      Next i
      \\ the same for horizontal axis
      HalfTextHeight=Size.y("1","courier", size9pt)/2
      For i=basey-dy to basey-dy*x#max() Step dy
            Move  basex, i
            Step -twipsx*10
            Width 1, dotline { draw scale.x/2+twipsx*10,,7}
            Move basex-100, i+HalfTextHeight
            Legend format$("{0}",(i-basey)/scY), "courier", size9pt, angle, left
      Next i
      ex=each(x) : ey=each(y)
     \\ start from first point. We use Draw to for absolute coordinates
      Move array(x,0)*dx+Basex, array(y,0)*scy+Basey
      While ex, ey {
            Width 2 {
                  Draw to array(ex)*dx+Basex, array(ey)*scy+Basey, blue
            }
      }
      \\ second pass for marks and labels
      ex=each(x) : ey=each(y)
      While ex, ey {
            Move array(ex)*dx+Basex, array(ey)*scy+Basey
            Step -75, -75
            Pen 12 {draw 150: draw 0,150 : draw -150 : draw 0,-150}
            Pen 13 {
                  Step 200, -200
                  Legend format$("({0}-{1})",array(ex),array(ey) ), "courier bold", size11pt, angle, right
            }
      }
      \\ screenshot to clipboard
      Screenshot$=""
      Move 0,0
      Copy scale.x, scale.y to Screenshot$
      Clipboard Screenshot$
      a$=key$
}
Pairs


(defun add (p1 p2)
  (do ((sum '())) ((and (endp p1) (endp p2)) (nreverse sum))
    (let ((pd1 (if (endp p1) -1 (caar p1)))
          (pd2 (if (endp p2) -1 (caar p2))))
      (multiple-value-bind (c1 c2)
          (cond
           ((> pd1 pd2) (values (cdr (pop p1)) 0))
           ((< pd1 pd2) (values 0 (cdr (pop p2))))
           (t  (values (cdr (pop p1)) (cdr (pop p2)))))
        (let ((csum (+ c1 c2)))
          (unless (zerop csum)
            (setf sum (acons (max pd1 pd2) csum sum))))))))

(defun multiply (p1 p2)
  (flet ((*p2 (p)
           (destructuring-bind (d . c) p
             (loop for (pd . pc) in p2
                   collecting (cons (+ d pd) (* c pc))))))
    (reduce 'add (mapcar #'*p2 p1) :initial-value '())))

(defun subtract (p1 p2)
  (add p1 (multiply '((0 . -1)) p2)))

(defun divide (dividend divisor &aux (sum '()))
  (assert (not (endp divisor)) (divisor)
    'division-by-zero
    :operation 'divide
    :operands (list dividend divisor))
  (flet ((floor1 (dividend divisor)
           (if (endp dividend) (values '() ())
             (destructuring-bind (d1 . c1) (first dividend)
               (destructuring-bind (d2 . c2) (first divisor)
                 (if (> d2 d1) (values '() dividend)
                   (let* ((quot (list (cons (- d1 d2) (/ c1 c2))))
                          (rem (subtract dividend (multiply divisor quot))))
                     (values quot rem))))))))
    (loop (multiple-value-bind (quotient remainder)
              (floor1 dividend divisor)
            (if (endp quotient) (return (values sum remainder))
              (setf dividend remainder
                    sum (add quotient sum)))))))


import gnuplot

let
  x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  y = [2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0]

plot(x, y, "Coordinate pairs")
discard stdin.readChar  # Needed as when the program exits, “gnuplot” is closed.


#load "graphics.cma"
open Graphics

let round x = int_of_float (floor(x +. 0.5))

let x = [0; 1; 2; 3; 4; 5; 6; 7; 8; 9]
and y = [2.7; 2.8; 31.4; 38.1; 58.0; 76.2; 100.5; 130.0; 149.3; 180.0]

let () =
  open_graph "";
  List.iter2
    (fun x y ->
      (* scale to fit in the window *)
      let _x = x * 30
      and _y = round(y *. 2.0) in
      plot _x _y)
    x y;
  ignore(wait_next_event [Key_pressed]);
  close_graph();
;;


import std.stdio, std.range, std.algorithm, std.typecons, std.conv;

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

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

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

void main() {
    immutable N = [-42.0, 0.0, -12.0, 1.0];
    immutable D = [-3.0, 1.0, 0.0, 0.0];
    writefln("%s / %s = %s  remainder %s", N, D, polyDiv(N, D)[]);
}


program Polynomial_long_division;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

type
  PPolySolution = ^TPolySolution;

  TPolynomio = record
  private
    class function Degree(p: TPolynomio): Integer; static;
    class function ShiftRight(p: TPolynomio; places: Integer): TPolynomio; static;
    class function PolyMultiply(p: TPolynomio; m: double): TPolynomio; static;
    class function PolySubtract(p, s: TPolynomio): TPolynomio; static;
    class function PolyLongDiv(n, d: TPolynomio): PPolySolution; static;
    function GetSize: Integer;
  public
    value: TArray<Double>;
    class operator RightShift(p: TPolynomio; b: Integer): TPolynomio;
    class operator Multiply(p: TPolynomio; m: double): TPolynomio;
    class operator Subtract(p, s: TPolynomio): TPolynomio;
    class operator Divide(p, s: TPolynomio): PPolySolution;
    class operator Implicit(a: TArray<Double>): TPolynomio;
    class operator Implicit(a: TPolynomio): string;
    procedure Assign(other: TPolynomio); overload;
    procedure Assign(other: TArray<Double>); overload;
    property Size: Integer read GetSize;
    function ToString: string;
  end;

  TPolySolution = record
    Quotient, Remainder: TPolynomio;
    constructor Create(q, r: TPolynomio);
  end;

{ TPolynomio }

procedure TPolynomio.Assign(other: TPolynomio);
begin
  Assign(other.value);
end;

procedure TPolynomio.Assign(other: TArray<Double>);
begin
  SetLength(value, length(other));
  for var i := 0 to High(other) do
    value[i] := other[i];
end;

class function TPolynomio.Degree(p: TPolynomio): Integer;
begin
  var len := high(p.value);

  for var i := len downto 0 do
  begin
    if p.value[i] <> 0.0 then
      exit(i);
  end;
  Result := -1;
end;

class operator TPolynomio.Divide(p, s: TPolynomio): PPolySolution;
begin
  Result := PolyLongDiv(p, s);
end;

function TPolynomio.GetSize: Integer;
begin
  Result := Length(value);
end;

class operator TPolynomio.Implicit(a: TPolynomio): string;
begin
  Result := a.toString;
end;

class operator TPolynomio.Implicit(a: TArray<Double>): TPolynomio;
begin
  Result.Assign(a);
end;

class operator TPolynomio.Multiply(p: TPolynomio; m: double): TPolynomio;
begin
  Result := TPolynomio.PolyMultiply(p, m);
end;

class function TPolynomio.PolyLongDiv(n, d: TPolynomio): PPolySolution;
var
  Solution: TPolySolution;
begin
  if length(n.value) <> Length(d.value) then
    raise Exception.Create('Numerator and denominator vectors must have the same size');

  var nd := Degree(n);
  var dd := Degree(d);

  if dd < 0 then
    raise Exception.Create('Divisor must have at least one one-zero coefficient');

  if nd < dd then
    raise Exception.Create('The degree of the divisor cannot exceed that of the numerator');

  var n2, q: TPolynomio;
  n2.Assign(n);
  SetLength(q.value, length(n.value));

  while nd >= dd do
  begin
    var d2 := d shr (nd - dd);
    q.value[nd - dd] := n2.value[nd] / d2.value[nd];
    d2 := d2 * q.value[nd - dd];
    n2 := n2 - d2;
    nd := Degree(n2);
  end;
  new(Result);
  Result^.Create(q, n2);
end;

class function TPolynomio.PolyMultiply(p: TPolynomio; m: double): TPolynomio;
begin
  Result.Assign(p);
  for var i := 0 to High(p.value) do
    Result.value[i] := p.value[i] * m;
end;

class operator TPolynomio.RightShift(p: TPolynomio; b: Integer): TPolynomio;
begin
  Result := TPolynomio.ShiftRight(p, b);
end;

class function TPolynomio.ShiftRight(p: TPolynomio; places: Integer): TPolynomio;
begin
  Result.Assign(p);
  if places <= 0 then
    exit;

  var pd := Degree(p);

  Result.Assign(p);
  for var i := pd downto 0 do
  begin
    Result.value[i + places] := Result.value[i];
    Result.value[i] := 0.0;
  end;
end;

class operator TPolynomio.Subtract(p, s: TPolynomio): TPolynomio;
begin
  Result := TPolynomio.PolySubtract(p, s);
end;

class function TPolynomio.PolySubtract(p, s: TPolynomio): TPolynomio;
begin
  Result.Assign(p);
  for var i := 0 to High(p.value) do
    Result.value[i] := p.value[i] - s.value[i];
end;

function TPolynomio.ToString: string;
begin
  Result := '';
  var pd := Degree(self);
  for var i := pd downto 0 do
  begin
    var coeff := value[i];
    if coeff = 0.0 then
      Continue;
    if coeff = 1.0 then
    begin
      if i < pd then
        Result := Result + ' + ';
    end
    else
    begin
      if coeff = -1 then
      begin
        if i < pd then
          Result := Result + ' - '
        else
          Result := Result + '-';
      end
      else
      begin
        if coeff < 0.0 then
        begin
          if i < pd then
            Result := Result + format(' - %.1f', [-coeff])
          else
            Result := Result + format('%.1f', [coeff]);
        end
        else
        begin
          if i < pd then
            Result := Result + format(' + %.1f', [coeff])
          else
            Result := Result + format('%.1f', [coeff]);
        end;
      end;
    end;
    if i > 1 then
      Result := Result + 'x^' + i.tostring
    else if i = 1 then
      Result := Result + 'x';
  end;
end;

{ TPolySolution }

constructor TPolySolution.Create(q, r: TPolynomio);
begin
  Quotient.Assign(q);
  Remainder.Assign(r);
end;

// Just for force implicitty string conversion
procedure Writeln(s: string);
begin
  System.Writeln(s);
end;

var
  n, d: TPolynomio;
  Solution: PPolySolution;

begin
  n := [-42.0, 0.0, -12.0, 1.0];
  d := [-3.0, 1.0, 0.0, 0.0];

  Write('Numerator   : ');
  Writeln(n);
  Write('Denominator : ');
  Writeln(d);
  Writeln('-------------------------------------');
  Solution := n / d;
  Write('Quotient    : ');
  Writeln(Solution^.Quotient);
  Write('Remainder   : ');
  Writeln(Solution^.Remainder);
  FreeMem(Solution, sizeof(TPolySolution));
  Readln;
end.


; define input arrays
(define x '(0 1 2 3 4 5 6 7 8 9))
(define y '(2.7 2.8 31.4 38.1 58.0 76.2 100.5 130.0 149.3 180.0))

; render
(import (lib gl2))
(glOrtho 0 10 0 200 0 1)

(gl:set-renderer (lambda (mouse)
   (glClear GL_COLOR_BUFFER_BIT)
   (glColor3f 0 1 0)
   (glBegin GL_LINE_STRIP)
      (map glVertex2f x y)
   (glEnd)))


pragma.syntax("0.9")
pragma.enable("accumulator")

def superscript(x, out) {
    if (x >= 10) { superscript(x // 10) }
    out.print("⁰¹²³⁴⁵⁶⁷⁸⁹"[x %% 10])
}

def makePolynomial(initCoeffs :List) {
    def degree := {
        var i := initCoeffs.size() - 1
        while (i >= 0 && initCoeffs[i] <=> 0) { i -= 1 }
        if (i < 0) { -Infinity } else { i }
    }
    def coeffs := initCoeffs(0, if (degree == -Infinity) { [] } else { degree + 1 })

    def polynomial {
      /** Print the polynomial (not necessary for the task) */
        to __printOn(out) {
            out.print("(λx.")
            var first := true
            for i in (0..!(coeffs.size())).descending() {
                def coeff := coeffs[i]
                if (coeff <=> 0) { continue }
                out.print(" ")
                if (coeff <=> 1 && !(i <=> 0)) {
                  # no coefficient written if it's 1 and not the constant term
                } else if (first) {      out.print(coeff)
                } else if (coeff > 0) {  out.print("+ ", coeff)
                } else {                 out.print("- ", -coeff)
                }
                if (i <=> 0) {         # no x if it's the constant term
                } else if (i <=> 1) {  out.print("x")
                } else {               out.print("x"); superscript(i, out)
                }
                first := false
            }
            out.print(")")
        }

        /** Evaluate the polynomial (not necessary for the task) */
        to run(x) {
          return accum 0 for i => c in coeffs { _ + c * x**i }
        }

        to degree() { return degree }
        to coeffs() { return coeffs }
        to highestCoeff() { return coeffs[degree] }

        /** Could support another polynomial, but not part of this task.
            Computes this * x**power. */
        to timesXToThe(power) {
            return makePolynomial([0] * power + coeffs)
        }

        /** Multiply (by a scalar only). */
        to multiply(scalar) {
            return makePolynomial(accum [] for x in coeffs { _.with(x * scalar) })
        }

        /** Subtract (by another polynomial only). */
        to subtract(other) {
            def oc := other.coeffs() :List
            return makePolynomial(accum [] for i in 0..(coeffs.size().max(oc.size())) { _.with(coeffs.fetch(i, fn{0}) - oc.fetch(i, fn{0})) })
        }

        /** Polynomial long division. */
        to quotRem(denominator, trace) {
            var numerator := polynomial
            require(denominator.degree() >= 0)
            if (numerator.degree() < denominator.degree()) {
                return [makePolynomial([]), denominator]
            } else {
                var quotientCoeffs := [0] * (numerator.degree() - denominator.degree())
                while (numerator.degree() >= denominator.degree()) {
                    trace.print("  ", numerator, "\n")

                    def qCoeff := numerator.highestCoeff() / denominator.highestCoeff()
                    def qPower := numerator.degree() - denominator.degree()
                    quotientCoeffs with= (qPower, qCoeff)

                    def d := denominator.timesXToThe(qPower) * qCoeff
                    trace.print("- ", d,  "          (= ", denominator, " * ", qCoeff, "x"); superscript(qPower, trace); trace.print(")\n")
                    numerator -= d

                    trace.print("  -------------------------- (Quotient so far: ",  makePolynomial(quotientCoeffs), ")\n")
                }
                return [makePolynomial(quotientCoeffs), numerator]
            }
        }
    }
    return polynomial
}


defmodule Polynomial do
  def division(_, []), do: raise ArgumentError, "denominator is zero"
  def division(_, [0]), do: raise ArgumentError, "denominator is zero"
  def division(f, g) when length(f) < length(g), do: {[0], f}
  def division(f, g) do
    {q, r} = division(g, [], f)
    if q==[], do: q = [0]
    if r==[], do: r = [0]
    {q, r}
  end

  defp division(g, q, r) when length(r) < length(g), do: {q, r}
  defp division(g, q, r) do
    p = hd(r) / hd(g)
    r2 = Enum.zip(r, g)
         |> Enum.with_index
         |> Enum.reduce(r, fn {{pn,pg},i},acc ->
              List.replace_at(acc, i, pn - p * pg)
            end)
    division(g, q++[p], tl(r2))
  end
end

[ { [1, -12, 0, -42], [1, -3] },
  { [1, -12, 0, -42], [1, 1, -3] },
  { [1, 3, 2],        [1, 1] },
  { [1, -4, 6, 5, 3], [1, 2, 1] } ]
|> Enum.each(fn {f,g} ->
     {q, r} = Polynomial.division(f, g)
     IO.puts "#{inspect f} / #{inspect g} => #{inspect q} remainder #{inspect r}"
   end)


let rec shift n l = if n <= 0 then l else shift (n-1) (l @ [0.0])
let rec pad n l = if n <= 0 then l else pad (n-1) (0.0 :: l)
let rec norm = function | 0.0 :: tl -> norm tl | x -> x
let deg l = List.length (norm l) - 1

let zip op p q =
  let d = (List.length p) - (List.length q) in
  List.map2 op (pad (-d) p) (pad d q)

let polydiv f g =
  let rec aux f s q =
    let ddif = (deg f) - (deg s) in
    if ddif < 0 then (q, f) else
      let k = (List.head f) / (List.head s) in
      let ks = List.map ((*) k) (shift ddif s) in
      let q' = zip (+) q (shift ddif [k])
      let f' = norm (List.tail (zip (-) f ks)) in
      aux f' s q' in
  aux (norm f) (norm g) []

let str_poly l =
  let term v p = match (v, p) with
    | (  _, 0) -> string v
    | (1.0, 1) -> "x"
    | (  _, 1) -> (string v) + "*x"
    | (1.0, _) -> "x^" + (string p)
    | _ -> (string v) + "*x^" + (string p) in
  let rec terms = function
    | [] -> []
    | h :: t ->
       if h = 0.0 then (terms t) else (term h (List.length t)) :: (terms t) in
  String.concat " + " (terms l)

let _ =
  let f,g = [1.0; -4.0; 6.0; 5.0; 3.0], [1.0; 2.0; 1.0] in
  let q, r = polydiv f g in
  Printf.printf
    " (%s) div (%s)\ngives\nquotient:\t(%s)\nremainder:\t(%s)\n"
    (str_poly f) (str_poly g) (str_poly q) (str_poly r)


USE: math.polynomials

{ -42 0 -12 1 } { -3 1 } p/mod ptrim [ . ] [email protected]


module Polynom
  implicit none

contains

  subroutine poly_long_div(n, d, q, r)
    real, dimension(:), intent(in) :: n, d
    real, dimension(:), intent(out), allocatable :: q
    real, dimension(:), intent(out), allocatable, optional :: r

    real, dimension(:), allocatable :: nt, dt, rt
    integer :: gn, gt, gd

    if ( (size(n) >= size(d)) .and. (size(d) > 0) .and. (size(n) > 0) ) then
       allocate(nt(size(n)), dt(size(n)), rt(size(n)))

       nt = n
       dt = 0
       dt(1:size(d)) = d
       rt = 0
       gn = size(n)-1
       gd = size(d)-1
       gt = 0

       do while ( d(gd+1) == 0 )
          gd = gd - 1
       end do

       do while( gn >= gd )
          dt = eoshift(dt, -(gn-gd))
          rt(gn-gd+1) = nt(gn+1) / dt(gn+1)
          nt = nt - dt * rt(gn-gd+1)
          gt = max(gt, gn-gd)
          do
             gn = gn - 1
             if ( nt(gn+1) /= 0 ) exit
          end do
          dt = 0
          dt(1:size(d)) = d
       end do

       allocate(q(gt+1))
       q = rt(1:gt+1)
       if ( present(r) ) then
          if ( (gn+1) > 0 ) then
             allocate(r(gn+1))
             r = nt(1:gn+1)
          else
             allocate(r(1))
             r = 0.0
          end if
       end if
       deallocate(nt, dt, rt)
    else
       allocate(q(1))
       q = 0
       if ( present(r) ) then
          allocate(r(size(n)))
          r = n
       end if
    end if

  end subroutine poly_long_div

  subroutine poly_print(p)
    real, dimension(:), intent(in) :: p

    integer :: i

    do i = size(p), 1, -1
       if ( i > 1 ) then
          write(*, '(F0.2,"x^",I0," + ")', advance="no") p(i), i-1
       else
          write(*, '(F0.2)') p(i)
       end if
    end do

  end subroutine poly_print

end module Polynom


--
-- demo\rosetta\Plot_coordinate_pairs.exw
-- ======================================
--
with javascript_semantics
include pGUI.e
include IupGraph.e

constant x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
         y = {2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0}

function get_data(Ihandle graph) return {{x,y,CD_BLUE}} end function

IupOpen()
Ihandle graph = IupGraph(get_data),
        dlg = IupDialog(graph,`TITLE="Plot coordinate pairs"`)
IupSetAttributes(dlg,"RASTERSIZE=320x240,MINSIZE=320x200")
IupSetAttributes(graph,"XTICK=1,XMIN=0,XMAX=9")
IupSetAttributes(graph,"YTICK=20,YMIN=0,YMAX=180")
IupShow(dlg)
if platform()!=JS then
    IupMainLoop()
    IupClose()
end if


(load "@lib/ps.l")

(scl 1)

(de plot (PsFile DX DY Lst)
   (let (SX (length Lst)  SY (apply max Lst)  N 0 Val)
      (out PsFile
         (psHead (+ DX 20) (+ DY 40))
         (font (9 . "Helvetica"))
         (if (or (=0 SX) (=0 SY))
            (window 60 12 DX DY
               (font 24 ,"Not enough Data") )
            (setq Lst  # Build coordinates
               (let X -1
                  (mapcar
                     '((Y)
                        (cons
                           (*/ (inc 'X) DX SX)
                           (- DY (*/ Y DY SY)) ) )
                     Lst ) ) )
            (color 55 95 55  # Background color
               (let (X (+ DX 40) Y (+ DY 40))
                  (poly T  0 0  X 0  X Y  0 Y  0 0) ) )
            (window 20 20 DX DY  # Plot coordinates
               (poly NIL 0 0  0 DY  (- DX 20) DY)
               (color 76 24 24
                  (poly NIL (caar Lst) (cdar Lst) (cdr Lst)) ) )
            (window 4 4 60 12 (ps (format SY *Scl)))
            (for X SX
               (window (+ 6 (*/ (dec X) DX SX)) (+ 24 DY) 30 12
                  (ps (format (dec X)) 0) ) ) )
         (page) ) ) )

(plot "plot.ps" 300 200 (2.7 2.8 31.4 38.1 58.0 76.2 100.5 130.0 149.3 180.0))
(call 'display "plot.ps")


#define EPS 1.0e-20

type polyterm
    degree as uinteger
    coeff as double
end type

sub poly_print( P() as double )
    dim as string outstr = "", sri
    for i as integer = ubound(P) to 0 step -1
        if outstr<>"" then
            if P(i)>0 then outstr = outstr + " + "
            if P(i)<0 then outstr = outstr + " - "
        end if
        if P(i)=0 then continue for
        if abs(P(i))<>1 or i=0 then
            if outstr="" then
                outstr = outstr + str((P(i)))
            else
                outstr = outstr + str(abs(P(i)))
            end if
        end if
        if i>0 then outstr=outstr+"x"
        sri= str(i)
        if i>1 then outstr=outstr + "^" + sri
    next i
    print outstr
end sub

function lc_deg( B() as double ) as polyterm
    'gets the coefficent and degree of the leading term in a polynomial
    dim as polyterm ret
    for i as uinteger = ubound(B) to 0 step -1
        if B(i)<>0 then
            ret.degree = i
            ret.coeff = B(i)
            return ret
        end if
    next i
    return ret
end function

sub poly_multiply( byval k as polyterm, P() as double )
    'in-place multiplication of polynomial by a polynomial term
    dim i as integer
    for i = ubound(P) to k.degree step -1
        P(i) = k.coeff*P(i-k.degree)
    next i
    for i = k.degree-1 to 0 step -1
        P(i)=0
    next i
end sub

sub poly_subtract( P() as double, Q() as double )
    'in place subtraction of one polynomial from another
    dim as uinteger deg = ubound(P)
    for i as uinteger = 0 to deg
        P(i) -= Q(i)
        if abs(P(i))<EPS then P(i)=0   'stupid floating point subtraction, grumble grumble
    next i
end sub

sub poly_add( P() as double, byval t as polyterm )
    'in-place addition of a polynomial term to a polynomial
    P(t.degree) += t.coeff
end sub

sub poly_copy( source() as double, target() as double )
    for i as uinteger = 0 to ubound(source)
        target(i) = source(i)
    next i
end sub

sub polydiv( A() as double, B() as double, Q() as double, R() as double )
    dim as polyterm s
    dim as double sB(0 to ubound(B))
    poly_copy A(), R()
    dim as uinteger d = ubound(B), degr = lc_deg(R()).degree
    dim as double c = lc_deg(B()).coeff
    while degr >= d
        s.coeff = lc_deg(R()).coeff/c
        s.degree = degr - d
        poly_add Q(), s
        poly_copy B(), sB()
        redim preserve sB(0 to s.degree+ubound(sB)) as double
        poly_multiply s, sB()
        poly_subtract R(), sB()
        degr = lc_deg(R()).degree
        redim sB(0 to ubound(B))
    wend
end sub

dim as double N(0 to 4) = {-42, 0, -12, 1}    'x^3 - 12x^2 - 42
dim as double D(0 to 2) = {-3, 1}             '        x   -  3
dim as double Q(0 to ubound(N)), R(0 to ubound(N))

polydiv( N(), D(), Q(), R() )

poly_print Q()   'quotient
poly_print R()   'remainder


/x [0 1 2 3 4 5 6 7 8 9] def
/y [2.7 2.8 31.4 38.1 58.0 76.2 100.5 130.0 149.3 180.0] def
/i 1 def

newpath
x 0 get y 0 get moveto
x length 1 sub{
x i get y i get lineto
/i i 1 add def
}repeat
stroke


Structure PlotData
  x.i
  y.f
EndStructure

Global i, x, y.f, max_x, max_y, min_x = #MAXLONG, min_y = Infinity()
Define count = (?serie_y - ?serie_x) / SizeOf(Integer) - 1
Global Dim MyData.PlotData(count)

Restore serie_x
For i = 0 To count
  Read.i x
  MyData(i)\x = x
  If x > max_x: max_x = x:  EndIf
  If x < min_x: min_x = x:  EndIf
Next
Restore serie_y
For i = 0 To count
  Read.f  y
  MyData(i)\y = y
  If y > max_y: max_y = y:  EndIf
  If y < min_y: min_y = y:  EndIf
Next

Procedure UpdatePlot(Win, w, h)
  Static gblm = 20, gtrm = 5 ;graph's bottom-left and top-right margin

  Protected count = ArraySize(MyData())
  If w > gblm And h > gblm And count > 0
    SetWindowTitle(Win, "PureBasic Plot " + Str(w) + "x" + Str(h))
    Protected gw = w - gblm, gh = h - gblm ;graph's width and height
    Protected i, yf.f, xf.f
    yf = (gh - gtrm) / max_y
    xf = (gw - gtrm) / max_x

    CreateImage(0, w, h)
    Protected OutputID = ImageOutput(0)
    StartDrawing(OutputID)
      DrawingMode(#PB_2DDrawing_Transparent)
      ;- Draw grid
      For i = 0 To count
        y = gh - max_y * i / count * yf
        LineXY(gblm, y, w - gtrm, y, $467E3E)
        ; Y-scale
        DrawText(1, y - 5, RSet(StrD(i / count * max_y, 1), 5))
        x = gblm + max_x * i / count * xf
        y = gh
        ; X-Scale
        LineXY(x, y, x, gtrm, $467E3E)
        If i: DrawText(x - 5, y + 2, Str(i)): EndIf
      Next

      ;- Draw curve
      Protected ox = gblm, oy = gh, x, y
      For i = 0 To count
        x = gblm + MyData(i)\x * xf
        y = gh - MyData(i)\y * yf
        LineXY(ox, oy, x, y, $0133EE)
        ox = x: oy = y
      Next
    StopDrawing()
    ImageGadget(0, 0, 0, w, h, ImageID(0))
  EndIf
EndProcedure

Define Win = OpenWindow(#PB_Any, 0, 0, 600, 400,"", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
If Win
  SmartWindowRefresh(Win, 1)
  UpdatePlot(Win, WindowWidth(Win), WindowHeight(Win))
  Repeat
    Define event = WaitWindowEvent()
    Select event
      Case #PB_Event_SizeWindow
        UpdatePlot(Win, WindowWidth(Win), WindowHeight(Win))
    EndSelect
  Until event = #PB_Event_CloseWindow

  ; Save the plot if the user wants to
  If MessageRequester("Question", "Save it?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
    Define File$=SaveFileRequester("Save as", "PB.png", "PNG (*.png)|*.png", 0)
    UsePNGImageEncoder()
    SaveImage(0, File$, #PB_ImagePlugin_PNG)
  EndIf
EndIf

DataSection
  serie_x:
  Data.i 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
  serie_y:
  Data.f 2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0
EndDataSection


package main

import "fmt"

func main() {
    n := []float64{-42, 0, -12, 1}
    d := []float64{-3, 1}
    fmt.Println("N:", n)
    fmt.Println("D:", d)
    q, r, ok := pld(n, d)
    if ok {
        fmt.Println("Q:", q)
        fmt.Println("R:", r)
    } else {
        fmt.Println("error")
    }
}

func degree(p []float64) int {
    for d := len(p) - 1; d >= 0; d-- {
        if p[d] != 0 {
            return d
        }
    }
    return -1
}

func pld(nn, dd []float64) (q, r []float64, ok bool) {
    if degree(dd) < 0 {
        return
    }
    nn = append(r, nn...)
    if degree(nn) >= degree(dd) {
        q = make([]float64, degree(nn)-degree(dd)+1)
        for degree(nn) >= degree(dd) {
            d := make([]float64, degree(nn)+1)
            copy(d[degree(nn)-degree(dd):], dd)
            q[degree(nn)-degree(dd)] = nn[degree(nn)] / d[degree(d)]
            for i := range d {
                d[i] *= q[degree(nn)-degree(dd)]
                nn[i] -= d[i]
            }
        }
    }
    return q, nn, true
}


#lang racket
(require plot)

(define x (build-list 10 values))
(define y (list 2.7 2.8 31.4 38.1 58.0 76.2 100.5 130.0 149.3 180.0))

(plot-new-window? #t)
(plot (points (map vector x y)))


import Data.List

shift n l = l ++ replicate n 0

pad n l = replicate n 0 ++ l

norm :: Fractional a => [a] -> [a]
norm = dropWhile (== 0)

deg l = length (norm l) - 1

zipWith' op p q = zipWith op (pad (-d) p) (pad d q)
  where d = (length p) - (length q)

polydiv f g = aux (norm f) (norm g) []
  where aux f s q | ddif < 0 = (q, f)
                  | otherwise = aux f' s q'
           where ddif = (deg f) - (deg s)
                 k = (head f) / (head s)
                 ks = map (* k) $ shift ddif s
                 q' = zipWith' (+) q $ shift ddif [k]
                 f' = norm $ tail $ zipWith' (-) f ks


/*REXX program plots X,Y   coördinate pairs  of  numbers  with plain (ASCII) characters.*/
x = 0      1       2       3       4       5        6        7        8        9
y = 2.7    2.8    31.4    38.1    58.0    76.2    100.5    130.0    149.3    180.0
$=
                  do j=1  for words(x)           /*build a list suitable for $PLOT subr.*/
                  $=$   word(x, j)','word(y, j)  /*add this X,Y coördinate to the $ list*/
                  end   /*j*/                    /*$≡ 0,2.7  1,2.8  2,31.4 3,38.1  ···  */
call '$PLOT'  $                                  /*invoke the REXX program:  $PLOT      */
exit rc                                          /*stick a fork in it,  we're all done. */


#!/usr/bin/awk -f

function clamp(val, a, b) { return (val<a) ? a : (val>b) ? b : val }

## return a timestamp with centisecond precision
function timex() {
  getline < "/proc/uptime"
  close("/proc/uptime")
  return $1
}

## draw image to terminal
function draw(src, xpos, ypos,    w,h, x,y, up,dn, line,screen) {
  w = src["width"]
  h = src["height"]

  for (y=0; y<h; y+=2) {
    line = sprintf("\033[%0d;%0dH", y/2+ypos+1, xpos+1)
    for (x=0; x<w; x++) {
      up = src[x,y+0]
      dn = src[x,y+1]
      line = line "\033[38;2;" palette[up] ";48;2;" palette[dn] "m▀"
    }
    screen = screen line "\033[0m"
  }
  printf("%s", screen)
}

## generate a palette
function paletteGen(    i, r,g,b) {
  # generate palette
  for (i=0; i<256; i++) {
    r = 128 + 128 * sin(3.14159265 * i / 32.0)
    g = 128 + 128 * sin(3.14159265 * i / 64.0)
    b = 128 + 128 * sin(3.14159265 * i / 128.0)
    palette[i] = sprintf("%d;%d;%d", clamp(r,0,255), clamp(g,0,255), clamp(b,0,255))
  }
}

## generate a plasma
function plasmaGen(plasma, w, h,    x,y, color) {
  for (y=0; y<h; y++) {
    for (x=0; x<w; x++) {
      color = ( \
          128.0 + (128.0 * sin((x / 8.0) - cos(now/2) )) \
        + 128.0 + (128.0 * sin((y / 16.0) - sin(now)*2 )) \
        + 128.0 + (128.0 * sin(sqrt((x - w / 2.0) * (x - w / 2.0) + (y - h / 2.0) * (y - h / 2.0)) / 4.0)) \
        + 128.0 + (128.0 * sin((sqrt(x * x + y * y) / 4.0) - sin(now/4) )) \
      ) / 4;

      plasma[x,y] = int(color)
    }
  }
}

BEGIN {
  "stty size" | getline
  buffer["height"] = h = ($1 ? $1 : 24) * 2
  buffer["width"]  = w = ($2 ? $2 : 80)

  paletteGen()
  start = timex()

  while (elapsed < 30) {
    elapsed = (now = timex()) - start

    plasmaGen(plasma, w, h)

    # copy plasma to buffer
    for (y=0; y<h; y++)
      for (x=0; x<w; x++)
        buffer[x,y] = int(plasma[x,y] + now * 100) % 256

    # draw buffer to terminal
    draw(buffer)
  }

  printf("\n")
}


import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class PolynomialLongDivision {

    public static void main(String[] args) {
        RunDivideTest(new Polynomial(1, 3, -12, 2, -42, 0), new Polynomial(1, 1, -3, 0));
        RunDivideTest(new Polynomial(5, 2, 4, 1, 1, 0), new Polynomial(2, 1, 3, 0));
        RunDivideTest(new Polynomial(5, 10, 4, 7, 1, 0), new Polynomial(2, 4, 2, 2, 3, 0));
        RunDivideTest(new Polynomial(2,7,-24,6,2,5,-108,4,3,3,-120,2,-126,0), new Polynomial(2, 4, 2, 2, 3, 0));
    }

    private static void RunDivideTest(Polynomial p1, Polynomial p2) {
        Polynomial[] result = p1.divide(p2);
        System.out.printf("Compute: (%s) / (%s) = %s reminder %s%n", p1, p2, result[0], result[1]);
        System.out.printf("Test:    (%s) * (%s) + (%s) = %s%n%n", result[0], p2, result[1], result[0].multiply(p2).add(result[1]));
    }

    private static final class Polynomial {

        private List<Term> polynomialTerms;

        //  Format - coeff, exp, coeff, exp, (repeating in pairs) . . .
        public Polynomial(long ... values) {
            if ( values.length % 2 != 0 ) {
                throw new IllegalArgumentException("ERROR 102:  Polynomial constructor.  Length must be even.  Length = " + values.length);
            }
            polynomialTerms = new ArrayList<>();
            for ( int i = 0 ; i < values.length ; i += 2 ) {
                polynomialTerms.add(new Term(BigInteger.valueOf(values[i]), values[i+1]));
            }
            Collections.sort(polynomialTerms, new TermSorter());
        }

        public Polynomial() {
            //  zero
            polynomialTerms = new ArrayList<>();
            polynomialTerms.add(new Term(BigInteger.ZERO, 0));
        }

        private Polynomial(List<Term> termList) {
            if ( termList.size() != 0 ) {
                //  Remove zero terms if needed
                for ( int i = 0 ; i < termList.size() ; i++ ) {
                    if ( termList.get(i).coefficient.compareTo(Integer.ZERO_INT) == 0 ) {
                        termList.remove(i);
                    }
                }
            }
            if ( termList.size() == 0 ) {
                //  zero
                termList.add(new Term(BigInteger.ZERO,0));
            }
            polynomialTerms = termList;
            Collections.sort(polynomialTerms, new TermSorter());
        }

        public Polynomial[] divide(Polynomial v) {
            Polynomial q = new Polynomial();
            Polynomial r = this;
            Number lcv = v.leadingCoefficient();
            long dv = v.degree();
            while ( r.degree() >= dv ) {
                Number lcr = r.leadingCoefficient();
                Number s = lcr.divide(lcv);
                Term term = new Term(s, r.degree() - dv);
                q = q.add(term);
                r = r.add(v.multiply(term.negate()));
            }
            return new Polynomial[] {q, r};
        }

        public Polynomial add(Polynomial polynomial) {
            List<Term> termList = new ArrayList<>();
            int thisCount = polynomialTerms.size();
            int polyCount = polynomial.polynomialTerms.size();
            while ( thisCount > 0 || polyCount > 0 ) {
                Term thisTerm = thisCount == 0 ? null : polynomialTerms.get(thisCount-1);
                Term polyTerm = polyCount == 0 ? null : polynomial.polynomialTerms.get(polyCount-1);
                if ( thisTerm == null ) {
                    termList.add(polyTerm);
                    polyCount--;
                }
                else if (polyTerm == null ) {
                    termList.add(thisTerm);
                    thisCount--;
                }
                else if ( thisTerm.degree() == polyTerm.degree() ) {
                    Term t = thisTerm.add(polyTerm);
                    if ( t.coefficient.compareTo(Integer.ZERO_INT) != 0 ) {
                        termList.add(t);
                    }
                    thisCount--;
                    polyCount--;
                }
                else if ( thisTerm.degree() < polyTerm.degree() ) {
                    termList.add(thisTerm);
                    thisCount--;
                }
                else {
                    termList.add(polyTerm);
                    polyCount--;
                }
            }
            return new Polynomial(termList);
        }

        public Polynomial add(Term term) {
            List<Term> termList = new ArrayList<>();
            boolean added = false;
            for ( int index = 0 ; index < polynomialTerms.size() ; index++ ) {
                Term currentTerm = polynomialTerms.get(index);
                if ( currentTerm.exponent == term.exponent ) {
                    added = true;
                    if ( currentTerm.coefficient.add(term.coefficient).compareTo(Integer.ZERO_INT) != 0 ) {
                        termList.add(currentTerm.add(term));
                    }
                }
                else {
                    termList.add(currentTerm);
                }
            }
            if ( ! added ) {
                termList.add(term);
            }
            return new Polynomial(termList);
        }

        public Polynomial multiply(Polynomial polynomial) {
            List<Term> termList = new ArrayList<>();
            for ( int i = 0 ; i < polynomialTerms.size() ; i++ ) {
                Term ci = polynomialTerms.get(i);
                for ( int j = 0 ; j < polynomial.polynomialTerms.size() ; j++ ) {
                    Term cj = polynomial.polynomialTerms.get(j);
                    Term currentTerm = ci.multiply(cj);
                    boolean added = false;
                    for ( int k = 0 ; k < termList.size() ; k++ ) {
                        if ( currentTerm.exponent == termList.get(k).exponent ) {
                            added = true;
                            Term t = termList.remove(k).add(currentTerm);
                            if ( t.coefficient.compareTo(Integer.ZERO_INT) != 0 ) {
                                termList.add(t);
                            }
                            break;
                        }
                    }
                    if ( ! added ) {
                        termList.add(currentTerm);
                    }
                }
            }
            return new Polynomial(termList);
        }

        public Polynomial multiply(Term term) {
            List<Term> termList = new ArrayList<>();
            for ( int index = 0 ; index < polynomialTerms.size() ; index++ ) {
                Term currentTerm = polynomialTerms.get(index);
                termList.add(currentTerm.multiply(term));
            }
            return new Polynomial(termList);
        }

        public Number leadingCoefficient() {
            return polynomialTerms.get(0).coefficient;
        }

        public long degree() {
            return polynomialTerms.get(0).exponent;
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            boolean first = true;
            for ( Term term : polynomialTerms ) {
                if ( first ) {
                    sb.append(term);
                    first = false;
                }
                else {
                    sb.append(" ");
                    if ( term.coefficient.compareTo(Integer.ZERO_INT) > 0 ) {
                        sb.append("+ ");
                        sb.append(term);
                    }
                    else {
                        sb.append("- ");
                        sb.append(term.negate());
                    }
                }
            }
            return sb.toString();
        }
    }

    private static final class TermSorter implements Comparator<Term> {
        @Override
        public int compare(Term o1, Term o2) {
            return (int) (o2.exponent - o1.exponent);
        }
    }

    private static final class Term {
        Number coefficient;
        long exponent;

        public Term(BigInteger c, long e) {
            coefficient = new Integer(c);
            exponent = e;
        }

        public Term(Number c, long e) {
            coefficient = c;
            exponent = e;
        }

        public Term multiply(Term term) {
            return new Term(coefficient.multiply(term.coefficient), exponent + term.exponent);
        }

        public Term add(Term term) {
            if ( exponent != term.exponent ) {
                throw new RuntimeException("ERROR 102:  Exponents not equal.");
            }
            return new Term(coefficient.add(term.coefficient), exponent);
        }

        public Term negate() {
            return new Term(coefficient.negate(), exponent);
        }

        public long degree() {
            return exponent;
        }

        @Override
        public String toString() {
            if ( coefficient.compareTo(Integer.ZERO_INT) == 0 ) {
                return "0";
            }
            if ( exponent == 0 ) {
                return "" + coefficient;
            }
            if ( coefficient.compareTo(Integer.ONE_INT) == 0 ) {
                if ( exponent == 1 ) {
                    return "x";
                }
                else {
                    return "x^" + exponent;
                }
            }
            if ( exponent == 1 ) {
                return coefficient + "x";
            }
            return coefficient + "x^" + exponent;
        }
    }

    private static abstract class Number {
        public abstract int compareTo(Number in);
        public abstract Number negate();
        public abstract Number add(Number in);
        public abstract Number multiply(Number in);
        public abstract Number inverse();
        public abstract boolean isInteger();
        public abstract boolean isFraction();

        public Number subtract(Number in) {
            return add(in.negate());
        }

        public Number divide(Number in) {
            return multiply(in.inverse());
        }
    }

    public static class Fraction extends Number {

        private final Integer numerator;
        private final Integer denominator;

        public Fraction(Integer n, Integer d) {
            numerator = n;
            denominator = d;
        }

        @Override
        public int compareTo(Number in) {
            if ( in.isInteger() ) {
                Integer result = ((Integer) in).multiply(denominator);
                return numerator.compareTo(result);
            }
            else if ( in.isFraction() ) {
                Fraction inFrac = (Fraction) in;
                Integer left = numerator.multiply(inFrac.denominator);
                Integer right = denominator.multiply(inFrac.numerator);
                return left.compareTo(right);
            }
            throw new RuntimeException("ERROR:  Unknown number type in Fraction.compareTo");
        }

        @Override
        public Number negate() {
            if ( denominator.integer.signum() < 0 ) {
                return new Fraction(numerator, (Integer) denominator.negate());
            }
            return new Fraction((Integer) numerator.negate(), denominator);
        }

        @Override
        public Number add(Number in) {
            if ( in.isInteger() ) {
                //x/y+z = (x+yz)/y
                return new Fraction((Integer) ((Integer) in).multiply(denominator).add(numerator), denominator);
            }
            else if ( in.isFraction() ) {
                Fraction inFrac = (Fraction) in;
                //  compute a/b + x/y
                //  Let q = gcd(b,y)
                //  Result = ( (a*y + x*b)/q ) / ( b*y/q )
                Integer x = inFrac.numerator;
                Integer y = inFrac.denominator;
                Integer q = y.gcd(denominator);
                Integer temp1 = numerator.multiply(y);
                Integer temp2 = denominator.multiply(x);
                Integer newDenom = denominator.multiply(y).divide(q);
                if ( newDenom.compareTo(Integer.ONE_INT) == 0 ) {
                    return temp1.add(temp2);
                }
                Integer newNum = (Integer) temp1.add(temp2).divide(q);
                Integer gcd2 = newDenom.gcd(newNum);
                if ( gcd2.compareTo(Integer.ONE_INT) == 0 ) {
                    return new Fraction(newNum, newDenom);
                }
                newNum = newNum.divide(gcd2);
                newDenom = newDenom.divide(gcd2);
                if ( newDenom.compareTo(Integer.ONE_INT) == 0 ) {
                    return newNum;
                }
                else if ( newDenom.compareTo(Integer.MINUS_ONE_INT) == 0 ) {
                    return newNum.negate();
                }
                return new Fraction(newNum, newDenom);
            }
            throw new RuntimeException("ERROR:  Unknown number type in Fraction.compareTo");
        }

        @Override
        public Number multiply(Number in) {
            if ( in.isInteger() ) {
                //x/y*z = x*z/y
                Integer temp = numerator.multiply((Integer) in);
                Integer gcd = temp.gcd(denominator);
                if ( gcd.compareTo(Integer.ONE_INT) == 0 || gcd.compareTo(Integer.MINUS_ONE_INT) == 0 ) {
                    return new Fraction(temp, denominator);
                }
                Integer newTop = temp.divide(gcd);
                Integer newBot = denominator.divide(gcd);
                if ( newBot.compareTo(Integer.ONE_INT) == 0 ) {
                    return newTop;
                }
                if ( newBot.compareTo(Integer.MINUS_ONE_INT) == 0 ) {
                    return newTop.negate();
                }
                return new Fraction(newTop, newBot);
            }
            else if ( in.isFraction() ) {
                Fraction inFrac = (Fraction) in;
                //  compute a/b * x/y
                Integer tempTop = numerator.multiply(inFrac.numerator);
                Integer tempBot = denominator.multiply(inFrac.denominator);
                Integer gcd = tempTop.gcd(tempBot);
                if ( gcd.compareTo(Integer.ONE_INT) == 0 || gcd.compareTo(Integer.MINUS_ONE_INT) == 0 ) {
                    return new Fraction(tempTop, tempBot);
                }
                Integer newTop = tempTop.divide(gcd);
                Integer newBot = tempBot.divide(gcd);
                if ( newBot.compareTo(Integer.ONE_INT) == 0 ) {
                    return newTop;
                }
                if ( newBot.compareTo(Integer.MINUS_ONE_INT) == 0 ) {
                    return newTop.negate();
                }
                return new Fraction(newTop, newBot);
            }
            throw new RuntimeException("ERROR:  Unknown number type in Fraction.compareTo");
        }

        @Override
        public boolean isInteger() {
            return false;
        }

        @Override
        public boolean isFraction() {
            return true;
        }

        @Override
        public String toString() {
            return numerator.toString() + "/" + denominator.toString();
        }

        @Override
        public Number inverse() {
            if ( numerator.equals(Integer.ONE_INT) ) {
                return denominator;
            }
            else if ( numerator.equals(Integer.MINUS_ONE_INT) ) {
                return denominator.negate();
            }
            else if ( numerator.integer.signum() < 0 ) {
                return new Fraction((Integer) denominator.negate(), (Integer) numerator.negate());
            }
            return new Fraction(denominator, numerator);
        }
    }

    public static class Integer extends Number {

        private BigInteger integer;
        public static final Integer MINUS_ONE_INT = new Integer(new BigInteger("-1"));
        public static final Integer ONE_INT = new Integer(new BigInteger("1"));
        public static final Integer ZERO_INT = new Integer(new BigInteger("0"));

        public Integer(BigInteger number) {
            this.integer = number;
        }

        public int compareTo(Integer val) {
            return integer.compareTo(val.integer);
        }

        @Override
        public int compareTo(Number in) {
            if ( in.isInteger() ) {
                return compareTo((Integer) in);
            }
            else if ( in.isFraction() ) {
                Fraction frac = (Fraction) in;
                BigInteger result = integer.multiply(frac.denominator.integer);
                return result.compareTo(frac.numerator.integer);
            }
            throw new RuntimeException("ERROR:  Unknown number type in Integer.compareTo");
        }

        @Override
        public Number negate() {
            return new Integer(integer.negate());
        }

        public Integer add(Integer in) {
            return new Integer(integer.add(in.integer));
        }

        @Override
        public Number add(Number in) {
            if ( in.isInteger() ) {
                return add((Integer) in);
            }
            else if ( in.isFraction() ) {
                Fraction f = (Fraction) in;
                Integer top = f.numerator;
                Integer bot = f.denominator;
                return new Fraction((Integer) multiply(bot).add(top), bot);
            }
            throw new RuntimeException("ERROR:  Unknown number type in Integer.add");
        }

        @Override
        public Number multiply(Number in) {
            if ( in.isInteger() ) {
                return multiply((Integer) in);
            }
            else if ( in.isFraction() ) {
                //  a * x/y = ax/y
                Integer x = ((Fraction) in).numerator;
                Integer y = ((Fraction) in).denominator;
                Integer temp = (Integer) multiply(x);
                Integer gcd = temp.gcd(y);
                if ( gcd.compareTo(Integer.ONE_INT) == 0 || gcd.compareTo(Integer.MINUS_ONE_INT) == 0 ) {
                    return new Fraction(temp, y);
                }
                Integer newTop = temp.divide(gcd);
                Integer newBot = y.divide(gcd);
                if ( newBot.compareTo(Integer.ONE_INT) == 0 ) {
                    return newTop;
                }
                if ( newBot.compareTo(Integer.MINUS_ONE_INT) == 0 ) {
                    return newTop.negate();
                }
                return new Fraction(newTop, newBot);
            }
            throw new RuntimeException("ERROR:  Unknown number type in Integer.add");
        }

        public Integer gcd(Integer in) {
            return new Integer(integer.gcd(in.integer));
        }

        public Integer divide(Integer in) {
            return new Integer(integer.divide(in.integer));
        }

        public Integer multiply(Integer in) {
            return new Integer(integer.multiply(in.integer));
        }

        @Override
        public boolean isInteger() {
            return true;
        }

        @Override
        public boolean isFraction() {
            return false;
        }

        @Override
        public String toString() {
            return integer.toString();
        }

        @Override
        public Number inverse() {
            if ( equals(ZERO_INT) ) {
                throw new RuntimeException("Attempting to take the inverse of zero in IntegerExpression");
            }
            else if ( this.compareTo(ONE_INT) == 0 ) {
                return ONE_INT;
            }
            else if ( this.compareTo(MINUS_ONE_INT) == 0 ) {
                return MINUS_ONE_INT;
            }
            return new Fraction(ONE_INT, this);
        }

    }
}


# Project : Plot coordinate pairs

load "guilib.ring"

paint = null

new qapp
        {
        win1 = new qwidget() {
                  setwindowtitle("Plot coordinate pairs")
                  setgeometry(100,100,1024,900)
                  label1 = new qlabel(win1) {
                              setgeometry(10,10,1024,900)
                              settext("")
                  }
                  new qpushbutton(win1) {
                          setgeometry(50,50,100,30)
                          settext("draw")
                          setclickevent("draw()")
                  }
                  show()
        }
        exec()
        }

func draw
        p1 = new qpicture()
               color = new qcolor() {
               setrgb(0,0,255,255)
        }
        pen = new qpen() {
                 setcolor(color)
                 setwidth(1)
        }
        paint = new qpainter() {
                  begin(p1)
                  setpen(pen)

        old = 0
        yold = 0
        xnew = 0
        ynew = 0
        x2 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        y2 = [2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0]

        for x = 1 to 9
              drawline(100*x,720,100*x,0)
              drawtext(100*x,750,string(x))
        next

        for y = 20 to 180 step 20
             drawline(900,4*y,0,4*y)
             drawtext(0,720-4*y,string(y))
        next

        drawline(0,0,0,720)
        drawline(0,0,900,0)

        for i = 1 to 10
             if i=1
                xold = 100*x2[i]
                yold = 720-4*y2[i]
             else
                xnew = 100*x2[i]
                ynew = 720-4*y2[i]
                drawline(xold,yold,xnew,ynew)
                xold = xnew
                yold = ynew
             ok
        next

        endpaint()
        }
        label1 { setpicture(p1) show() }
        return


require 'gnuplot'

x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
y = [2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0]
Gnuplot.open do |gp|
  Gnuplot::Plot.new( gp ) do |plot|
    plot.data << Gnuplot::DataSet.new( [x, y] ) do |ds|
      ds.with = "linespoints"
      ds.notitle
    end
  end
end


#include<windows.h>
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include<math.h>

#define pi M_PI

int main()
{
	CONSOLE_SCREEN_BUFFER_INFO info;
    int cols, rows;
	time_t t;
	int i,j;

    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
    cols = info.srWindow.Right - info.srWindow.Left + 1;
    rows = info.srWindow.Bottom - info.srWindow.Top + 1;

	HANDLE console;

	console = GetStdHandle(STD_OUTPUT_HANDLE);

	system("@clear||cls");

	srand((unsigned)time(&t));

	for(i=0;i<rows;i++)
		for(j=0;j<cols;j++){
			SetConsoleTextAttribute(console,fabs(sin(pi*(rand()%254 + 1)/255.0))*254);
			printf("%c",219);
		}

	getchar();

	return 0;
}


#include <windows.h>
#include <math.h>
#include <string>

const int BMP_SIZE = 240, MY_TIMER = 987654;

class myBitmap {
public:
    myBitmap() : pen( NULL ), brush( NULL ), clr( 0 ), wid( 1 ) {}
    ~myBitmap() {
        DeleteObject( pen ); DeleteObject( brush );
        DeleteDC( hdc ); DeleteObject( bmp );
    }
    bool create( int w, int h ) {
        BITMAPINFO bi;
        ZeroMemory( &bi, sizeof( bi ) );
        bi.bmiHeader.biSize        = sizeof( bi.bmiHeader );
        bi.bmiHeader.biBitCount    = sizeof( DWORD ) * 8;
        bi.bmiHeader.biCompression = BI_RGB;
        bi.bmiHeader.biPlanes      = 1;
        bi.bmiHeader.biWidth       =  w;
        bi.bmiHeader.biHeight      = -h;

        HDC dc = GetDC( GetConsoleWindow() );
        bmp = CreateDIBSection( dc, &bi, DIB_RGB_COLORS, &pBits, NULL, 0 );
        if( !bmp ) return false;

        hdc = CreateCompatibleDC( dc );
        SelectObject( hdc, bmp );
        ReleaseDC( GetConsoleWindow(), dc );

        width = w; height = h;
        return true;
    }
    void clear( BYTE clr = 0 ) {
        memset( pBits, clr, width * height * sizeof( DWORD ) );
    }
    void setBrushColor( DWORD bClr ) {
        if( brush ) DeleteObject( brush );
        brush = CreateSolidBrush( bClr );
        SelectObject( hdc, brush );
    }
    void setPenColor( DWORD c ) {
        clr = c; createPen();
    }
    void setPenWidth( int w ) {
        wid = w; createPen();
    }
    void saveBitmap( std::string path ) {
        BITMAPFILEHEADER fileheader;
        BITMAPINFO       infoheader;
        BITMAP           bitmap;
        DWORD            wb;

        GetObject( bmp, sizeof( bitmap ), &bitmap );
        DWORD* dwpBits = new DWORD[bitmap.bmWidth * bitmap.bmHeight];

        ZeroMemory( dwpBits, bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD ) );
        ZeroMemory( &infoheader, sizeof( BITMAPINFO ) );
        ZeroMemory( &fileheader, sizeof( BITMAPFILEHEADER ) );

        infoheader.bmiHeader.biBitCount = sizeof( DWORD ) * 8;
        infoheader.bmiHeader.biCompression = BI_RGB;
        infoheader.bmiHeader.biPlanes = 1;
        infoheader.bmiHeader.biSize = sizeof( infoheader.bmiHeader );
        infoheader.bmiHeader.biHeight = bitmap.bmHeight;
        infoheader.bmiHeader.biWidth = bitmap.bmWidth;
        infoheader.bmiHeader.biSizeImage = bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD );

        fileheader.bfType    = 0x4D42;
        fileheader.bfOffBits = sizeof( infoheader.bmiHeader ) + sizeof( BITMAPFILEHEADER );
        fileheader.bfSize    = fileheader.bfOffBits + infoheader.bmiHeader.biSizeImage;

        GetDIBits( hdc, bmp, 0, height, ( LPVOID )dwpBits, &infoheader, DIB_RGB_COLORS );

        HANDLE file = CreateFile( path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
        WriteFile( file, &fileheader, sizeof( BITMAPFILEHEADER ), &wb, NULL );
        WriteFile( file, &infoheader.bmiHeader, sizeof( infoheader.bmiHeader ), &wb, NULL );
        WriteFile( file, dwpBits, bitmap.bmWidth * bitmap.bmHeight * 4, &wb, NULL );
        CloseHandle( file );

        delete [] dwpBits;
    }
    HDC getDC() const     { return hdc; }
    DWORD* bits()          { return ( DWORD* )pBits; }
private:
    void createPen() {
        if( pen ) DeleteObject( pen );
        pen = CreatePen( PS_SOLID, wid, clr );
        SelectObject( hdc, pen );
    }
    HBITMAP bmp; HDC    hdc;
    HPEN    pen; HBRUSH brush;
    void    *pBits; int width, height, wid;
    DWORD    clr;
};
class plasma
{
public:
    plasma() {
        currentTime = 0; _WD = BMP_SIZE >> 1; _WV = BMP_SIZE << 1;
        _bmp.create( BMP_SIZE, BMP_SIZE ); _bmp.clear();
        plasma1 = new BYTE[BMP_SIZE * BMP_SIZE * 4];
        plasma2 = new BYTE[BMP_SIZE * BMP_SIZE * 4];
        int i, j, dst = 0;
        double temp;
        for( j = 0; j < BMP_SIZE * 2; j++ ) {
            for( i = 0; i < BMP_SIZE * 2; i++ ) {
                plasma1[dst] = ( BYTE )( 128.0 + 127.0 * ( cos( ( double )hypot( BMP_SIZE - j, BMP_SIZE - i ) / 64.0 ) ) );
                plasma2[dst] = ( BYTE )( ( sin( ( sqrt( 128.0 + ( BMP_SIZE - i ) * ( BMP_SIZE - i ) +
                               ( BMP_SIZE - j ) * ( BMP_SIZE - j ) ) - 4.0 ) / 32.0 ) + 1 ) * 90.0 );
                dst++;
            }
        }
    }
    void update() {
        DWORD dst;
        BYTE a, c1,c2, c3;
        currentTime += ( double )( rand() % 2 + 1 );

        int x1 = _WD + ( int )( ( _WD - 1 ) * sin( currentTime  / 137 ) ),
            x2 = _WD + ( int )( ( _WD - 1 ) * sin( -currentTime /  75 ) ),
            x3 = _WD + ( int )( ( _WD - 1 ) * sin( -currentTime / 125 ) ),
            y1 = _WD + ( int )( ( _WD - 1 ) * cos( currentTime  / 123 ) ),
            y2 = _WD + ( int )( ( _WD - 1 ) * cos( -currentTime /  85 ) ),
            y3 = _WD + ( int )( ( _WD - 1 ) * cos( -currentTime / 108 ) );

        int src1 = y1 * _WV + x1, src2 = y2 * _WV + x2, src3 = y3 * _WV + x3;

        DWORD* bits = _bmp.bits();
        for( int j = 0; j < BMP_SIZE; j++ ) {
            dst = j * BMP_SIZE;
            for( int i= 0; i < BMP_SIZE; i++ ) {
                a = plasma2[src1] + plasma1[src2] + plasma2[src3];
                c1 = a << 1; c2 = a << 2; c3 = a << 3;
                bits[dst + i] = RGB( c1, c2, c3 );
                src1++; src2++; src3++;
            }
            src1 += BMP_SIZE; src2 += BMP_SIZE; src3 += BMP_SIZE;
        }
        draw();
    }
    void setHWND( HWND hwnd ) { _hwnd = hwnd; }
private:
    void draw() {
        HDC dc = _bmp.getDC(), wdc = GetDC( _hwnd );
        BitBlt( wdc, 0, 0, BMP_SIZE, BMP_SIZE, dc, 0, 0, SRCCOPY );
        ReleaseDC( _hwnd, wdc );
    }
    myBitmap _bmp; HWND _hwnd; float _ang;
    BYTE *plasma1, *plasma2;
    double currentTime; int _WD, _WV;
};
class wnd
{
public:
    wnd() { _inst = this; }
    int wnd::Run( HINSTANCE hInst ) {
        _hInst = hInst; _hwnd = InitAll();
        SetTimer( _hwnd, MY_TIMER, 15, NULL );
        _plasma.setHWND( _hwnd );
        ShowWindow( _hwnd, SW_SHOW );
        UpdateWindow( _hwnd );
        MSG msg;
        ZeroMemory( &msg, sizeof( msg ) );
        while( msg.message != WM_QUIT ) {
            if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) != 0 ) {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
            }
        }
        return UnregisterClass( "_MY_PLASMA_", _hInst );
    }
private:
    void wnd::doPaint( HDC dc ) { _plasma.update(); }
    void wnd::doTimer()         { _plasma.update(); }
    static int WINAPI wnd::WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {
        switch( msg ) {
            case WM_PAINT: {
                    PAINTSTRUCT ps;
                    _inst->doPaint( BeginPaint( hWnd, &ps ) );
                    EndPaint( hWnd, &ps );
                    return 0;
                }
            case WM_DESTROY: PostQuitMessage( 0 ); break;
            case WM_TIMER: _inst->doTimer(); break;
            default: return DefWindowProc( hWnd, msg, wParam, lParam );
        }
        return 0;
    }
    HWND InitAll() {
        WNDCLASSEX wcex;
        ZeroMemory( &wcex, sizeof( wcex ) );
        wcex.cbSize        = sizeof( WNDCLASSEX );
        wcex.style         = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc   = ( WNDPROC )WndProc;
        wcex.hInstance     = _hInst;
        wcex.hCursor       = LoadCursor( NULL, IDC_ARROW );
        wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
        wcex.lpszClassName = "_MY_PLASMA_";

        RegisterClassEx( &wcex );

        RECT rc = { 0, 0, BMP_SIZE, BMP_SIZE };
        AdjustWindowRect( &rc, WS_SYSMENU | WS_CAPTION, FALSE );
        int w = rc.right - rc.left, h = rc.bottom - rc.top;
        return CreateWindow( "_MY_PLASMA_", ".: Plasma -- PJorente :.", WS_SYSMENU, CW_USEDEFAULT, 0, w, h, NULL, NULL, _hInst, NULL );
    }
    static wnd* _inst; HINSTANCE _hInst; HWND _hwnd; plasma _plasma;
};
wnd* wnd::_inst = 0;
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) {
    wnd myWnd;
    return myWnd.Run( hInstance );
}


using Polynomials

p = Poly([-42,0,-12,1])
q = Poly([-3,1])

d, r = divrem(p,q)

println(p, " divided by ", q, " is ", d, " with remainder ", r, ".")


// 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)
}


import scala.swing.Swing.pair2Dimension
import scala.swing.{ MainFrame, Panel, Rectangle }
import java.awt.{ Color, Graphics2D, geom }

object PlotCoordPairs extends scala.swing.SimpleSwingApplication {

  //min/max of display-x resp. y
  val (dx0, dy0) = (70, 30)
  val (dxm, dym) = (670, 430)

  val (prefSizeX, prefSizeY) = (720, 480)

  private def ui = new Panel {

    import math._
    val xmax = {
      val f1 = pow(10, log10(xs.max).toInt)
      val f2 = if (f1 < 10) 10 else round(xs.max / f1) * f1
      if (f2 >= xs.max) f2 else (round(xs.max / f1) + 1) * f1
    }
    val ymax = {
      val f1 = pow(10, log10(ys.max).toInt)
      val f2 = if (f1 < 10) 10 else round(ys.max / f1) * f1
      if (f2 >= ys.max) f2 else (round(ys.max / f1) + 1) * f1
    }

    val (xinterv, yinterv) = (xmax / xs.size, ymax / xs.size)

    case class Coord(x: Double, y: Double) {
      val (dx, dy) = ((x / xmax * (dxm - dx0) + dx0).toInt, (dym - y / ymax * (dym - dy0)).toInt)
    }

    val pcentre = Coord(0, 0)
    val pxmax = Coord(xmax, 0)
    val pymax = Coord(0, ymax)

    background = Color.white
    preferredSize = (prefSizeX, prefSizeY)

    //axes:
    val a_path = new geom.GeneralPath
    a_path.moveTo(pxmax.dx, pxmax.dy)
    a_path.lineTo(pcentre.dx, pcentre.dy) //x-axis
    a_path.lineTo(pymax.dx, pymax.dy) //y-axis
    // interval ticks:
    xs.map(i => Coord(i * xinterv, 0)).map(p => {
      a_path.moveTo(p.dx, p.dy)
      a_path.lineTo(p.dx, p.dy + 5)
    })
    xs.map(i => Coord(0, i * yinterv)).map(p => {
      a_path.moveTo(p.dx, p.dy)
      a_path.lineTo(p.dx - 5, p.dy)
    })

    //grid:
    val g_path = new geom.GeneralPath
    (1 to xs.size).
      map(i => Coord(i * xinterv, 0)).map(p => {
        g_path.moveTo(p.dx, p.dy);
        g_path.lineTo(Coord(p.x, ymax).dx, Coord(p.x, ymax).dy)
      })
    (1 to xs.size).map(i => Coord(0, i * yinterv)).map(p => {
      g_path.moveTo(p.dx, p.dy);
      g_path.lineTo(Coord(xmax, p.y).dx, Coord(xmax, p.y).dy)
    })

    //labeling:
    val xlabels = (0 to xs.size).map(i => {
      val p = Coord(i * xinterv, 0)
      Triple(p.x.toInt.toString, p.dx - 3, p.dy + 20)
    })
    val ylabels = (0 to xs.size).map(i => {
      val p = Coord(0, i * yinterv)
      Triple(p.y.toInt.toString, p.dx - 30, p.dy + 5)
    })

    //curve:
    val path = new geom.GeneralPath
    val curve = xs.map(i => Coord(xs(i), ys(i)))
    path.moveTo(curve.head.dx, curve.head.dy)
    curve.map(p => path.lineTo(p.dx, p.dy))
    //...flag all function values:
    val rects = curve.map(p => new Rectangle(p.dx - 3, p.dy - 3, 6, 6))

    override def paintComponent(g: Graphics2D) = {
      super.paintComponent(g)

      g.setColor(Color.lightGray)
      g.draw(g_path)
      g.setColor(Color.black)
      g.draw(a_path)
      xlabels.map(t => g.drawString(t._1, t._2, t._3))
      ylabels.map(t => g.drawString(t._1, t._2, t._3))
      g.draw(path)
      rects.map(g.draw(_))
    }
  }

  val xs = 0 to 9
  val ys: List[Double] = List(2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0)

  def top = new MainFrame {
    title = "Rosetta Code >>> Task: Plot coordinate pairs | Language: Scala"
    contents = ui
  }
}


import javafx.application {
    Application
}
import javafx.stage {
    Stage
}
import javafx.scene {
    Scene
}
import javafx.scene.layout {
    BorderPane
}
import javafx.scene.image {
    WritableImage,
    ImageView
}
import ceylon.numeric.float {
    sin,
    sqrt,
    remainder
}
import javafx.scene.paint {
    Color
}
import javafx.animation {
    AnimationTimer
}

shared void run() {
    Application.launch(`Plasma`);
}

shared class Plasma() extends Application() {

    function createPlasma(Integer width, Integer height) => [
        for (j in 0:height) [
            for (i in 0:width)
            let (x = i.float, y = j.float)
            ( sin(x / 16.0)
            + sin(y / 8.0)
            + sin((x + y) / 16.0)
            + sin(sqrt(x ^ 2.0 + y ^ 2.0) / 8.0)
            + 4.0 )
            / 8.0
        ]
    ];

    void writeImage(Float[][] plasma, WritableImage img, Float hueShift = 0.0) {
        value writer = img.pixelWriter;
        for(j->row in plasma.indexed) {
            for(i->percent in row.indexed) {
                value hue = remainder(hueShift + percent, 1.0)  * 360.0;
                writer.setColor(i, j, Color.hsb(hue, 1.0, 1.0));
            }
        }
    }

    shared actual void start(Stage primaryStage) {

        value w = 500;
        value h = 500;
        value plasma = createPlasma(w, h);
        value img = WritableImage(w, h);
        writeImage(plasma, img);

        value root = BorderPane();
        root.center = ImageView(img);

        variable value hueShift = 0.0;
        value timer = object extends AnimationTimer() {
            shared actual void handle(Integer now) {
                hueShift = remainder(hueShift + 0.02, 1.0);
                writeImage(plasma, img, hueShift);
            }
        };
        timer.start();

        value scene = Scene(root);
        primaryStage.title = "Plasma";
        primaryStage.setScene(scene);
        primaryStage.sizeToScene();
        primaryStage.show();
    }

}


(require :lispbuilder-sdl)
(require :simple-rgb)

(defparameter *palette*
  (let ((palette-aux (make-array 256 :element-type 'fixnum)))
    (dotimes (i 256)
      (let ((color_i (simple-rgb:hsv->rgb (simple-rgb:hsv (/ i 255.0) 1.0 1.0))))
        (setf (aref palette-aux i) (loop :for component :across color_i
                                       :for i :from 0
                                       :sum (ash component (* 8 i))))))
    palette-aux)
  "palette")

(defun value->color (palette palette-shift index)
  (aref palette (mod (+ index palette-shift) (length palette))))

(defun return-color-by-pos (x y &optional w h)
  "returns a color index"
  (floor
   (/ (+ (+ 128.0 (* 128.0 (sin (/ x 16.0))))
         (+ 128.0 (* 128.0 (sin (/ y 8.0))))
         (+ 128.0 (* 128.0 (sin (/ (+ x y) 16.0))))
         (+ 128.0 (* 128.0 (sin (/ (sqrt (+ (* x x) (* y y))) 8.0)))))
      4.0)))

(defun return-color-by-pos-another (x y &optional w h)
  "a different function that returns a color index"
  (floor
   (/ (+ (+ 128.0 (* 128.0 (sin (/ x 16.0))))
         (+ 128.0 (* 128.0 (sin (/ y 32.0))))
         (+ 128.0 (* 128.0 (sin (/ (sqrt (+ (expt (/ (- x w) 2.0) 2) (expt (/ (- y h) 2.0) 2))) 8.0))))
         (+ 128.0 (* 128.0 (sin (/ (sqrt (+ (* x x) (* y y))) 8.0)))))
      4.0)))

(defun plasma-render (surface palette-shift)
  "render plasma"
  (let ((width (sdl:width surface))
        (height (sdl:height surface)))
    (sdl-base::with-pixel (s (sdl:fp surface))
      (dotimes (h height)
        (dotimes (w width)
          (sdl-base::write-pixel s w h (value->color *palette* palette-shift (funcall #'return-color-by-pos-another w h width height)))))))
  surface)

(defun demo/plasma ()
  "main function: shows a window rendering a plasma efect"
  (sdl:with-init ()
    (let ((win (sdl:window 320 240
                           :bpp 24
                           :resizable nil
                           :title-caption "demo/plasma"
                           :icon-caption "demo/plasma")))
      (let ((palette-shift 0))
      (sdl:update-display win)
      (sdl:with-events ()
        (:idle
         (plasma-render win palette-shift)
         (sdl:update-display win)
         (incf palette-shift))
        (:video-expose-event () (sdl:update-display win))
        (:key-down-event (:key key)
                         (when (or
                                (sdl:key= key :sdl-key-escape)
                                (sdl:key= key :sdl-key-q))
                           (sdl:push-quit-event)))
        (:quit-event () t))))))

(demo/plasma)


const MinusInfinity = -1

type
  Polynomial = seq[int]
  Term = tuple[coeff, exp: int]

func degree(p: Polynomial): int =
  ## Return the degree of a polynomial.
  ## "p" is supposed to be normalized.
  result = if p.len > 0: p.len - 1 else: MinusInfinity

func normalize(p: var Polynomial) =
  ## Normalize a polynomial, removing useless zeroes.
  while p[^1] == 0: discard p.pop()

func `shr`(p: Polynomial; n: int): Polynomial =
  ## Shift a polynomial of "n" positions to the right.
  result.setLen(p.len + n)
  result[n..^1] = p

func `*=`(p: var Polynomial; n: int) =
  ## Multiply in place a polynomial by an integer.
  for item in p.mitems: item *= n
  p.normalize()

func `-=`(a: var Polynomial; b: Polynomial) =
  ## Substract in place a polynomial from another polynomial.
  for i, val in b: a[i] -= val
  a.normalize()

func longdiv(a, b: Polynomial): tuple[q, r: Polynomial] =
  ## Compute the long division of a polynomial by another.
  ## Return the quotient and the remainder as polynomials.
  result.r = a
  if b.degree < 0: raise newException(DivByZeroDefect, "divisor cannot be zero.")
  result.q.setLen(a.len)
  while (let k = result.r.degree - b.degree; k >= 0):
    var d = b shr k
    result.q[k] = result.r[^1] div d[^1]
    d *= result.q[k]
    result.r -= d
  result.q.normalize()

const Superscripts: array['0'..'9', string] = ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"]

func superscript(n: Natural): string =
  ## Return the Unicode string to use to represent an exponent.
  if n == 1:
    return ""
  for d in $n:
    result.add(Superscripts[d])

func `$`(term: Term): string =
  ## Return the string representation of a term.
  if term.coeff == 0: "0"
  elif term.exp == 0: $term.coeff
  else:
    let base = 'x' & superscript(term.exp)
    if term.coeff == 1: base
    elif term.coeff == -1: '-' & base
    else: $term.coeff & base

func `$`(poly: Polynomial): string =
  ## return the string representation of a polynomial.
  for idx in countdown(poly.high, 0):
    let coeff = poly[idx]
    var term: Term = (coeff: coeff, exp: idx)
    if result.len == 0:
      result.add $term
    else:
      if coeff > 0:
        result.add '+'
        result.add $term
      elif coeff < 0:
        term.coeff = -term.coeff
        result.add '-'
        result.add $term

const
  N = @[-42, 0, -12, 1]
  D = @[-3, 1]

let (q, r) = longdiv(N, D)
echo "N = ", N
echo "D = ", D
echo "q = ", q
echo "r = ", r


: sqrt ( u -- sqrt )            ( Babylonian method                 )
  dup 2/                        ( first square root guess is half   )
  dup 0= if drop exit then      ( sqrt[0]=0, sqrt[1]=1              )
  begin dup >r 2dup / r> + 2/   ( stack: square old-guess new-guess )
  2dup > while                  ( as long as guess is decreasing    )
  nip repeat                    ( forget old-guess and repeat       )
  drop nip ;

: sgn 0< if -1 else 1 then ;
: isin
  256 mod 128 -                 \ full circle is 255 "degrees"
  dup dup sgn * 128 swap - *    \ second order approximation
  negate 32 / ;                 \ amplitude is +/-128

: color-shape 256 mod 6 * 765 - abs 256 - 0 max 255 min ;  \ trapezes
: hue
  dup color-shape .          \ red
  dup 170 + color-shape .    \ green
  85 + color-shape . ;       \ blue

: plasma
  outfile-id >r
  s" plasma.ppm" w/o create-file throw to outfile-id
  s\" P3\n500 500\n255\n" type
  500 0 do
    500 0 do
      i 2 * isin 128 +
      j 4 * isin 128 + +
      i j + isin 2 * 128 + +
      i i * j j * + sqrt 4 * isin 128 + +
      4 /
      hue
      s\" \n" type
    loop
    s\" \n" type
  loop

  outfile-id close-file throw
  r> to outfile-id ;

plasma


' version 12-04-2017
' compile with: fbc -s gui
' Computer Graphics Tutorial (lodev.org), last example

#Define dist(a, b, c, d) Sqr(((a - c) * (a - c) + (b - d) * (b - d)))

Const As ULong w = 256
Const As ULong h = 256
ScreenRes w, h, 24
WindowTitle ("Plasma effect")

Dim As ULong x, y
Dim As UByte c
Dim As Double time_, value

Do
    time_ += .99
    ScreenLock
    For x = 0 To w -1
        For y = 0 To h -1
            value = Sin(dist(x + time_, y, 128, 128) / 8) _
            + Sin(dist(x, y, 64, 64) / 8) _
            + Sin(dist(x, y + time_ / 7, 192, 64) / 7) _
            + Sin(dist(x, y, 192, 100) / 8) + 4
            ' c = Int(value) * 32
            c = int(value * 32)
            PSet(x, y), RGB(c, c * 2, 255 - c)
        Next
    Next
    ScreenUnLock
    Sleep 1

    If Inkey <> "" Or Inkey = Chr(255) + "k" Then
        End
    End If

Loop


  $ convert plasma.gif -coalesce plasma2.gif
  $ eog plasma2.gif


let rec shift n l = if n <= 0 then l else shift (pred n) (l @ [0.0])
let rec pad n l = if n <= 0 then l else pad (pred n) (0.0 :: l)
let rec norm = function | 0.0 :: tl -> norm tl | x -> x
let deg l = List.length (norm l) - 1

let zip op p q =
  let d = (List.length p) - (List.length q) in
  List.map2 op (pad (-d) p) (pad d q)