function [q, r] = poly_long_div(n, d)
  gd = length(d);
  pv = zeros(1, length(n));
  pv(1:gd) = d;
  if ( length(n) >= gd )
    q = [];
    while ( length(n) >= gd )
      q = [q, n(1)/pv(1)];
      n = n - pv .* (n(1)/pv(1));
      n = shift(n, -1);           %
      tn = n(1:length(n)-1);      % eat the higher power term
      n = tn;                     %
      tp = pv(1:length(pv)-1);
      pv = tp;                    % make pv the same length of n
    endwhile
    r = n;
  else
    q = [0];
    r = n;
  endif
endfunction

[q, r] = poly_long_div([1,-12,0,-42], [1,-3]);
polyout(q, 'x');
polyout(r, 'x');
disp("");
[q, r] = poly_long_div([1,-12,0,-42], [1,1,-3]);
polyout(q, 'x');
polyout(r, 'x');
disp("");
[q, r] = poly_long_div([1,3,2], [1,1]);
polyout(q, 'x');
polyout(r, 'x');
disp("");
[q, r] = poly_long_div([1,3], [1,-12,0,-42]);
polyout(q, 'x');
polyout(r, 'x');


package require Tk

# The actual plotting engine
proc plotxy {canvas xs ys} {
    global xfac yfac
    set maxx [tcl::mathfunc::max {*}$xs]
    set maxy [tcl::mathfunc::max {*}$ys]
    set xfac [expr {[winfo width $canvas] * 0.8/$maxx}]
    set yfac [expr {[winfo height $canvas] * 0.8/$maxy}]
    scale $canvas x 0 $maxx $xfac
    scale $canvas y 0 $maxy $yfac
    foreach x $xs y $ys {
        dot $canvas [expr {$x*$xfac}] [expr {$y*$yfac}] -fill red
    }
}
# Rescales the contents of the given canvas
proc scale {canvas direction from to fac} {
    set f [expr {$from*$fac}]
    set t [expr {$to*$fac}]
    switch -- $direction {
        x {
            set f [expr {$from * $fac}]
            set t [expr {$to * $fac}]
            $canvas create line $f 0 $t 0
            $canvas create text $f 0 -anchor nw -text $from
            $canvas create text $t 0 -anchor n -text $to

        }
        y {
            set f [expr {$from * -$fac}]
            set t [expr {$to * -$fac}]
            $canvas create line 0 $f 0 $t
            $canvas create text 0 $f -anchor se -text $from
            $canvas create text 0 $t -anchor e -text $to
        }
    }
}
# Helper to make points, which are otherwise not a native item type
proc dot {canvas x y args} {
    set id [$canvas create oval [expr {$x-3}] [expr {-$y-3}] \
                [expr {$x+3}] [expr {-$y+3}]]
    $canvas itemconfigure $id {*}$args
}

pack [canvas .c -background white]
update
set xs {0   1    2    3    4    5     6     7     8     9}
set ys {2.7 2.8 31.4 38.1 58.0 76.2 100.5 130.0 149.3 180.0}
plotxy .c $xs $ys
.c config -scrollregion [.c bbox all]
.c move all 20 20

# Save image (this is the only part that requires an external library)
package require Img
set im [image create photo -data .c]
$im write plotxy.png -format PNG


uses javax.swing.*
uses java.awt.*
uses java.awt.image.*
uses java.awt.event.ActionEvent
uses java.awt.image.BufferedImage#*
uses java.lang.Math#*

var size = 400
EventQueue.invokeLater(\ -> showPlasma())

function showPlasma() {
  var frame = new JFrame("Plasma") {:Resizable = false, :DefaultCloseOperation = JFrame.EXIT_ON_CLOSE}
  frame.add(new Plasma(), BorderLayout.CENTER)
  frame.pack()
  frame.setLocationRelativeTo(null)
  frame.Visible = true
}

class Plasma extends JPanel  {
  var hueShift: float
  property get plasma: float[][] = createPlasma(size, size)
  property get img: BufferedImage = new BufferedImage(size, size, TYPE_INT_RGB)

  construct() {
    PreferredSize = new Dimension(size, size)
    new Timer(50, \ e -> {hueShift+=0.02 repaint()}).start()
  }

  private function createPlasma(w: int, h: int): float[][] {
    var buffer = new float[h][w]
    for(y in 0..|h)
      for(x in 0..|w) {
        var value = (sin(x / 16) + sin(y / 8) + sin((x + y) / 16) + sin(sqrt(x * x + y * y) / 8) + 4) / 8
        buffer[y][x] = value as float
      }
    return buffer
  }

  override function paintComponent(g: Graphics) {
    for(y in 0..|plasma.length)
      for(x in 0..|plasma[0].length)
        img.setRGB(x, y, Color.HSBtoRGB(hueShift + plasma[y][x], 1, 1))
    g.drawImage(img, 0, 0, null)
  }
}


poldiv(a,b)={
  my(rem=a%b);
  [(a - rem)/b, rem]
};
poldiv(x^9+1, x^3+x-3)


use strict;
use List::Util qw(min);

sub poly_long_div
{
    my ($rn, $rd) = @_;

    my @n = @$rn;
    my $gd = scalar(@$rd);
    if ( scalar(@n) >= $gd ) {
	my @q = ();
	while ( scalar(@n) >= $gd ) {
	    my $piv = $n[0]/$rd->[0];
	    push @q, $piv;
	    $n[$_] -= $rd->[$_] * $piv foreach ( 0 .. min(scalar(@n), $gd)-1 );
	    shift @n;
	}
	return ( \@q, \@n );
    } else {
	return ( [0], $rn );
    }
}


FnOff
PlotsOff
NewPlot 1, 1, x, y
ZoomData


Private Sub plot_coordinate_pairs(x As Variant, y As Variant)
    Dim chrt As Chart
    Set chrt = ActiveSheet.Shapes.AddChart.Chart
    With chrt
        .ChartType = xlLine
        .HasLegend = False
        .HasTitle = True
        .ChartTitle.Text = "Time"
        .SeriesCollection.NewSeries
        .SeriesCollection.Item(1).XValues = x
        .SeriesCollection.Item(1).Values = y
        .Axes(xlValue, xlPrimary).HasTitle = True
        .Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "microseconds"
    End With
End Sub
Public Sub main()
    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_coordinate_pairs x, y
End Sub


import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import static java.awt.image.BufferedImage.*;
import static java.lang.Math.*;
import javax.swing.*;

public class PlasmaEffect extends JPanel {
    float[][] plasma;
    float hueShift = 0;
    BufferedImage img;

    public PlasmaEffect() {
        Dimension dim = new Dimension(640, 640);
        setPreferredSize(dim);
        setBackground(Color.white);

        img = new BufferedImage(dim.width, dim.height, TYPE_INT_RGB);
        plasma = createPlasma(dim.height, dim.width);

        // animate about 24 fps and shift hue value with every frame
        new Timer(42, (ActionEvent e) -> {
            hueShift = (hueShift + 0.02f) % 1;
            repaint();
        }).start();
    }

    float[][] createPlasma(int w, int h) {
        float[][] buffer = new float[h][w];

        for (int y = 0; y < h; y++)
            for (int x = 0; x < w; x++) {

                double value = sin(x / 16.0);
                value += sin(y / 8.0);
                value += sin((x + y) / 16.0);
                value += sin(sqrt(x * x + y * y) / 8.0);
                value += 4; // shift range from -4 .. 4 to 0 .. 8
                value /= 8; // bring range down to 0 .. 1

                // requires VM option -ea
                assert (value >= 0.0 && value <= 1.0) : "Hue value out of bounds";

                buffer[y][x] = (float) value;
            }
        return buffer;
    }

    void drawPlasma(Graphics2D g) {
        int h = plasma.length;
        int w = plasma[0].length;
        for (int y = 0; y < h; y++)
            for (int x = 0; x < w; x++) {
                float hue = hueShift + plasma[y][x] % 1;
                img.setRGB(x, y, Color.HSBtoRGB(hue, 1, 1));
            }
        g.drawImage(img, 0, 0, null);
    }

    @Override
    public void paintComponent(Graphics gg) {
        super.paintComponent(gg);
        Graphics2D g = (Graphics2D) gg;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        drawPlasma(g);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setTitle("Plasma Effect");
            f.setResizable(false);
            f.add(new PlasmaEffect(), BorderLayout.CENTER);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        });
    }
}


-- demo\rosetta\Polynomial_long_division.exw
with javascript_semantics

function degree(sequence p)
    for i=length(p) to 1 by -1 do
        if p[i]!=0 then return i end if
    end for
    return -1
end function

function poly_div(sequence n, d)
    d = deep_copy(d)
    while length(d)<length(n) do d &=0 end while
    integer dn = degree(n),
            dd = degree(d)
    if dd<0 then throw("divide by zero") end if
    sequence quo = repeat(0,dn),
             rem = deep_copy(n)
    while dn>=dd do
        integer k = dn-dd, qk = rem[dn]/d[dd]
        sequence d2 = d[1..length(d)-k]
        quo[k+1] = qk
        for i=1 to length(d2) do
            integer mi = -i
            rem[mi] -= d2[mi]*qk
        end for
        dn = degree(rem)
    end while
    return {quo,rem}
end function

function poly(sequence si)
    -- display helper
    string r = ""
    for t=length(si) to 1 by -1 do
        integer sit = si[t]
        if sit!=0 then
            if sit=1 and t>1 then
                r &= iff(r=""? "":" + ")
            elsif sit=-1 and t>1 then
                r &= iff(r=""?"-":" - ")
            else
                if r!="" then
                    r &= iff(sit<0?" - ":" + ")
                    sit = abs(sit)
                end if
                r &= sprintf("%d",sit)
            end if
            r &= iff(t>1?"x"&iff(t>2?sprintf("^%d",t-1):""):"")
        end if
    end for
    if r="" then r="0" end if
    return r
end function

constant tests = {{{-42,0,-12,1},{-3,1}},
                  {{-3,1},{-42,0,-12,1}},
                  {{-42,0,-12,1},{-3,1,1}},
                  {{2,3,1},{1,1}},
                  {{3,5,6,-4,1},{1,2,1}},
                  {{3,0,7,0,0,0,0,0,3,0,0,1},{1,0,0,5,0,0,0,1}},
                  {{-56,87,-94,-55,22,-7},{2,0,1}},
                 }

constant fmt = "%40s / %-16s = %25s rem %s\n"

for i=1 to length(tests) do
    sequence {num,den} = tests[i],
             {quo,rem} = poly_div(num,den)
    printf(1,fmt,apply({num,den,quo,rem},poly))
end for


import "graphics" for Canvas, ImageData, Color
import "dome" for Window
import "math" for Point

class PlotCoordinates {
    construct new(width, height) {
        Window.title = "Plot coordinates"
        Window.resize(width, height)
        Canvas.resize(width, height)
        _width = width
        _height = height
    }

    init() {
        var x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        var y = [2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0]
        plotCoordinates(x, y)
    }

    plotCoordinates(x, y) {
        var n = x.count
        // draw axes
        Canvas.line(40, _height - 40, _width - 40, _height - 40, Color.blue, 2)
        Canvas.line(40, _height - 40, 40, 40, Color.blue, 2)
        var length = 40 * n
        var div = length / 10
        var j = 0
        for (i in 0..9) {
            var p = Point.new(40 + j, _height - 40)
            Canvas.print(i.toString, p.x - 4, p.y + 4, Color.white)
            j = j + div
        }
        j = div
        for (i in 1..9) {
            var p = Point.new(10, _height - 40 - j)
            var s = (i * 20).toString
            if (s.count == 2) s = " " + s
            Canvas.print(s, p.x, p.y, Color.white)
            j = j + div
        }
        Canvas.print("X", _width - 44, _height - 36, Color.green)
        Canvas.print("Y", 20, 40, Color.green)

        // plot points
        var xStart = 40
        var xScale = 40
        var yStart = 40
        var yScale = 2
        var points = List.filled(n, null)
        for (i in 0...n) {
            points[i] = Point.new(xStart + x[i]*xScale, _height - yStart - y[i]*yScale)
        }
        Canvas.circlefill(points[0].x, points[0].y, 3, Color.red)
        for (i in 1...n) {
            Canvas.line(points[i-1].x, points[i-1].y, points[i].x, points[i].y, Color.red)
            Canvas.circlefill(points[i].x, points[i].y, 3, Color.red)
        }
    }

    update() {}

    draw(alpha) {}
}

var Game = PlotCoordinates.new(500, 500)


<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset='UTF-8'>
    <style>
        canvas {
            position: absolute;
            top: 50%;
            left: 50%;
            width: 700px;
            height: 500px;
            margin: -250px 0 0 -350px;
        }
        body {
            background-color: navy;
        }
    </style>
</head>
<body>
    <canvas></canvas>
    <script>
        'use strict';
        var canvas = document.querySelector('canvas');
        canvas.width = 700;
        canvas.height = 500;

        var g = canvas.getContext('2d');

        var plasma = createPlasma(canvas.width, canvas.height);
        var hueShift = 0;

        function createPlasma(w, h) {
            var buffer = new Array(h);

            for (var y = 0; y < h; y++) {
                buffer[y] = new Array(w);

                for (var x = 0; x < w; x++) {

                    var value = Math.sin(x / 16.0);
                    value += Math.sin(y / 8.0);
                    value += Math.sin((x + y) / 16.0);
                    value += Math.sin(Math.sqrt(x * x + y * y) / 8.0);
                    value += 4; // shift range from -4 .. 4 to 0 .. 8
                    value /= 8; // bring range down to 0 .. 1

                    buffer[y][x] = value;
                }
            }
            return buffer;
        }

        function drawPlasma(w, h) {
            var img = g.getImageData(0, 0, w, h);

            for (var y = 0; y < h; y++) {

                for (var x = 0; x < w; x++) {

                    var hue = hueShift + plasma[y][x] % 1;
                    var rgb = HSVtoRGB(hue, 1, 1);
                    var pos = (y * w + x) * 4;
                    img.data[pos] = rgb.r;
                    img.data[pos + 1] = rgb.g;
                    img.data[pos + 2] = rgb.b;
                }
            }
            g.putImageData(img, 0, 0);
        }

        /* copied from stackoverflow */
        function HSVtoRGB(h, s, v) {
            var r, g, b, i, f, p, q, t;

            i = Math.floor(h * 6);
            f = h * 6 - i;
            p = v * (1 - s);
            q = v * (1 - f * s);
            t = v * (1 - (1 - f) * s);
            switch (i % 6) {
                case 0: r = v, g = t, b = p; break;
                case 1: r = q, g = v, b = p; break;
                case 2: r = p, g = v, b = t; break;
                case 3: r = p, g = q, b = v; break;
                case 4: r = t, g = p, b = v; break;
                case 5: r = v, g = p, b = q; break;
            }
            return {
                r: Math.round(r * 255),
                g: Math.round(g * 255),
                b: Math.round(b * 255)
            };
        }

        function drawBorder() {
            g.strokeStyle = "white";
            g.lineWidth = 10;
            g.strokeRect(0, 0, canvas.width, canvas.height);
        }

        function animate(lastFrameTime) {
            var time = new Date().getTime();
            var delay = 42;

            if (lastFrameTime + delay < time) {
                hueShift = (hueShift + 0.02) % 1;
                drawPlasma(canvas.width, canvas.height);
                drawBorder();
                lastFrameTime = time;
            }

            requestAnimationFrame(function () {
                animate(lastFrameTime);
            });
        }

        g.fillRect(0, 0, canvas.width, canvas.height);
        animate(0);
    </script>

</body>
</html>


(de degree (P)
   (let I NIL
      (for (N . C) P
         (or (=0 C) (setq I N)) )
      (dec I) ) )

(de divPoly (N D)
   (if (lt0 (degree D))
      (quit "Div/0" D)
      (let (Q NIL Diff)
         (while (ge0 (setq Diff (- (degree N) (degree D))))
            (setq Q (need (- -1 Diff) Q 0))
            (let E D
               (do Diff (push 'E 0))
               (let F (/ (get N (inc (degree N))) (get E (inc (degree E))))
                  (set (nth Q (inc Diff)) F)
                  (setq N (mapcar '((N E) (- N (* E F))) N E)) ) ) )
         (list Q N) ) ) )


# -*- coding: utf-8 -*-

from itertools import izip

def degree(poly):
    while poly and poly[-1] == 0:
        poly.pop()   # normalize
    return len(poly)-1

def poly_div(N, D):
    dD = degree(D)
    dN = degree(N)
    if dD < 0: raise ZeroDivisionError
    if dN >= dD:
        q = [0] * dN
        while dN >= dD:
            d = [0]*(dN - dD) + D
            mult = q[dN - dD] = N[-1] / float(d[-1])
            d = [coeff*mult for coeff in d]
            N = [coeffN - coeffd for coeffN, coeffd in izip(N, d)]
            dN = degree(N)
        r = N
    else:
        q = [0]
        r = N
    return q, r

if __name__ == '__main__':
    print "POLYNOMIAL LONG DIVISION"
    N = [-42, 0, -12, 1]
    D = [-3, 1, 0, 0]
    print "  %s / %s =" % (N,D),
    print " %s remainder %s" % poly_div(N, D)


include c:\cxpl\codes;          \intrinsic 'code' declarations

def     ScrW=640, ScrH=480, VidMode=$101;
def     Sx = ScrW/10,           \pixels per horz grid line
        Sy = ScrH/10,           \pixels per vert grid line
        Ox = (3+1+1)*8+2,       \offset for horz grid: allow room for "180.0"
        Oy = ScrH-20;           \offset for vert grid: allow room for labels
int     X, DataX;
real    Y, DataY, Gain;
def     Brown=6, LCyan=11;

[DataX:= [0,   1,    2,    3,    4,    5,     6,     7,     8,     9];
 DataY:= [2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0];

SetVid(VidMode);
for X:= 0 to 9 do                                               \draw grid
        [Move(X*Sx+Ox, Oy);  Line(X*Sx+Ox, Oy-9*Sy, Brown);     \vert lines
         Move(Ox, Oy-X*Sy);  Line(9*Sx+Ox, Oy-X*Sy, Brown);     \horz lines
        ];
Format(3,1);  Attrib(LCyan);                                    \label grid
Y:= 0.0;
for X:= 0 to 9 do
        [Move(X*Sx+Ox-3, Oy+6); IntOut(6, X);                   \X axis
         Move(0, Oy-X*Sy-7);     RlOut(6, Y);                   \Y axis
        Y:= Y + 20.0;
        ];
Gain:= float(Sy)/20.0;
Move(DataX(0)*Sx+Ox, Oy-Fix(DataY(0)*Gain));                    \plot points
for X:= 1 to 9 do
        Line(DataX(X)*Sx+Ox, Oy-Fix(DataY(X)*Gain), LCyan);

if ChIn(1) then [];                                             \wait for key
SetVid(3);                                                      \restore text
]


#<<<
cmd:=0'|
#set term wxt  # X11
unset key  # Only one data set, so the key is uninformative

plot '-'   # '-' can be replaced with a filename, to read data from that file.
  0   2.7
  1   2.8
  2  31.4
  3  38.1
  4  68.0
  5  76.2
  6 100.5
  7 130.0
  8 149.3
  9 180.0
e
|;
#<<<

gnuplot:=System.popen("gnuplot","w");
gnuplot.write(cmd); gnuplot.flush();
ask("Hit return to finish"); gnuplot.close();


using Luxor, Colors

Drawing(800, 800)

function plasma(wid, hei)
    for x in 1:wid, y in 1:hei
        sethue(parse(Colorant, HSV(180 + 45sin(x/19) + 45sin(y/9) +
            45sin((x+y)/25) + 45sin(sqrt(x^2 + y^2)/8), 1, 1)))
        circle(Point(x, y), 1, :fill)
    end
end

@png plasma(800, 800)


// version 1.1.2

import java.awt.*
import java.awt.image.BufferedImage
import javax.swing.*

class PlasmaEffect : JPanel() {
    private val plasma: Array<FloatArray>
    private var hueShift = 0.0f
    private val img: BufferedImage

    init {
        val dim = Dimension(640, 640)
        preferredSize = dim
        background = Color.white
        img = BufferedImage(dim.width, dim.height, BufferedImage.TYPE_INT_RGB)
        plasma = createPlasma(dim.height, dim.width)
        // animate about 24 fps and shift hue value with every frame
        Timer(42) {
            hueShift = (hueShift + 0.02f) % 1
            repaint()
        }.start()
    }

    private fun createPlasma(w: Int, h: Int): Array<FloatArray> {
        val buffer = Array(h) { FloatArray(w) }
        for (y in 0 until h)
            for (x in 0 until w) {
                var value = Math.sin(x / 16.0)
                value += Math.sin(y / 8.0)
                value += Math.sin((x + y) / 16.0)
                value += Math.sin(Math.sqrt((x * x + y * y).toDouble()) / 8.0)
                value += 4.0  // shift range from -4 .. 4 to 0 .. 8
                value /= 8.0  // bring range down to 0 .. 1
                if (value < 0.0 || value > 1.0) throw RuntimeException("Hue value out of bounds")
                buffer[y][x] = value.toFloat()
            }
        return buffer
    }

    private fun drawPlasma(g: Graphics2D) {
        val h = plasma.size
        val w = plasma[0].size
        for (y in 0 until h)
            for (x in 0 until w) {
                val hue = hueShift + plasma[y][x] % 1
                img.setRGB(x, y, Color.HSBtoRGB(hue, 1.0f, 1.0f))
            }
        g.drawImage(img, 0, 0, null)
    }

    override fun paintComponent(gg: Graphics) {
        super.paintComponent(gg)
        val g = gg as Graphics2D
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
        drawPlasma(g);
    }
}

fun main(args: Array<String>) {
    SwingUtilities.invokeLater {
        val f = JFrame()
        f.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
        f.title = "Plasma Effect"
        f.isResizable = false
        f.add(PlasmaEffect(), BorderLayout.CENTER)
        f.pack()
        f.setLocationRelativeTo(null)
        f.isVisible = true
    }
}


polylongdiv <- function(n,d) {
  gd <- length(d)
  pv <- vector("numeric", length(n))
  pv[1:gd] <- d
  if ( length(n) >= gd ) {
    q <- c()
    while ( length(n) >= gd ) {
      q <- c(q, n[1]/pv[1])
      n <- n - pv * (n[1]/pv[1])
      n <- n[2:length(n)]
      pv <- pv[1:(length(pv)-1)]
    }
    list(q=q, r=n)
  } else {
    list(q=c(0), r=n)
  }
}

# an utility function to print polynomial
print.polynomial <- function(p) {
  i <- length(p)-1
  for(a in p) {
    if ( i == 0 ) {
      cat(a, "\n")
    } else {
      cat(a, "x^", i, " + ", sep="")
    }
    i <- i - 1
  }
}

r <- polylongdiv(c(1,-12,0,-42), c(1,-3))
print.polynomial(r$q)
print.polynomial(r$r)


#lang racket
(define (deg p)
  (for/fold ([d -inf.0]) ([(pi i) (in-indexed p)])
    (if (zero? pi) d i)))
(define (lead p) (vector-ref p (deg p)))
(define (mono c d) (build-vector (+ d 1) (λ(i) (if (= i d) c 0))))
(define (poly*cx^n c n p) (vector-append (make-vector n 0) (for/vector ([pi p]) (* c pi))))
(define (poly+ p q) (poly/lin 1 p  1 q))
(define (poly- p q) (poly/lin 1 p -1 q))
(define (poly/lin a p b q)
  (cond [(< (deg p) 0) q]
        [(< (deg q) 0) p]
        [(< (deg p) (deg q)) (poly/lin b q a p)]
        [else (define ap+bq (for/vector #:length (+ (deg p) 1) #:fill 0
                              ([pi p] [qi q]) (+ (* a pi) (* b qi))))
              (for ([i (in-range (+ (deg q) 1) (+ (deg p) 1))])
                (vector-set! ap+bq i (* a (vector-ref p i))))
              ap+bq]))

(define (poly/ n d)
  (define N (deg n))
  (define D (deg d))
  (cond
    [(< N 0) (error 'poly/ "can't divide by zero")]
    [(< N D) (values 0 n)]
    [else    (define c (/ (lead n) (lead d)))
             (define q (mono c (- N D)))
             (define r (poly- n (poly*cx^n c (- N D) d)))
             (define-values (q1 r1) (poly/ r d))
             (values (poly+ q q1) r1)]))
; Example:
(poly/ #(-42 0 -12 1) #(-3 1))
; Output:
'#(-27 -9 1)
'#(-123 0)


with Ada.Text_IO;

with PDF_Out;

procedure Pinstripe_Printer
is
   use PDF_Out;

   package Point_IO
   is new Ada.Text_Io.Float_IO (Real);

   procedure Pinstripe (Doc          : in out Pdf_Out_File;
                        Line_Width   : Real;
                        Line_Height  : Real;
                        Screen_Width : Real;
                        Y            : Real)
   is
      Count  : constant Natural
        := Natural (Real'Floor (Screen_Width / (2.0 * Line_Width)));
      Corner      : constant Point := (Doc.Left_Margin, Doc.Bottom_Margin);
      Corner_Box  : constant Point := Corner     + (10.0, 10.0);
      Corner_Text : constant Point := Corner_Box + (10.0, 10.0);
      Light_Gray  : constant Color_Type := (0.9, 0.9, 0.9);
      Image : String (1 .. 4);
   begin
      --  Pinstripes
      Doc.Color (Black);
      for A in 0 .. Count loop
         Doc.Draw (What => Corner +
                     Rectangle'(X_Min  => 2.0 * Real (A) * Line_Width,
                                Y_Min  => Y,
                                Width  => Line_Width,
                                Height => Line_Height),
                   Rendering => Fill);
      end loop;

      --  Box
      Doc.Stroking_Color (Black);
      Doc.Color (Light_Gray);
      Doc.Line_Width (3.0);
      Doc.Draw (What => Corner_Box + (0.0, Y, 120.0, 26.0),
                Rendering => Fill_Then_Stroke);
      --  Text
      Doc.Color (Black);
      Doc.Text_Rendering_Mode (Fill);
      Point_Io.Put (Image, Line_Width, Aft => 1, Exp => 0);
      Doc.Put_XY (Corner_Text.X, Corner_Text.Y + Y,
                  Image & " point pinstripe");
   end Pinstripe;

   Doc : PDF_Out_File;
begin
   Doc.Create ("pinstripe.pdf");
   Doc.Page_Setup (A4_Portrait);
   Doc.Margins (Margins_Type'(Left   => Cm_2_5,
                              others => One_cm));
   declare
      Width  : constant Real
        := A4_Portrait.Width - Doc.Left_Margin - Doc.Right_Margin;
      Height : constant Real
        := A4_Portrait.Height - Doc.Top_Margin - Doc.Bottom_Margin;
   begin
      Pinstripe (Doc, 1.0, One_Inch, Width, Height - 1.0 * One_Inch);
      Pinstripe (Doc, 2.0, One_Inch, Width, Height - 2.0 * One_Inch);
      Pinstripe (Doc, 3.0, One_Inch, Width, Height - 3.0 * One_Inch);
      Pinstripe (Doc, 4.0, One_inch, Width, Height - 4.0 * One_Inch);
      Pinstripe (Doc, 5.0, One_Inch, Width, Height - 5.0 * One_Inch);
      Pinstripe (Doc, 6.0, One_Inch, Width, Height - 6.0 * One_Inch);
      Pinstripe (Doc, 7.0, One_Inch, Width, Height - 7.0 * One_Inch);
      Pinstripe (Doc, 8.0, One_Inch, Width, Height - 8.0 * One_Inch);
      Pinstripe (Doc, 9.0, One_Inch, Width, Height - 9.0 * One_Inch);
      Pinstripe (Doc, 10.0, One_Inch, Width, Height - 10.0 * One_Inch);
      Pinstripe (Doc, 11.0, One_Inch, Width, Height - 11.0 * One_Inch);
   end;
   Doc.Close;
end Pinstripe_Printer;


_ = love.graphics
p1, p2, points = {}, {}, {}

function hypotenuse( a, b )
    return a * a + b * b
end
function love.load()
    size = _.getWidth()
    currentTime, doub, half = 0, size * 2, size / 2
    local b1, b2

    for j = 0, size * 2 do
        for i = 0, size * 2 do
            b1 = math.floor( 128 + 127 * ( math.cos( math.sqrt( hypotenuse( size - j , size - i ) ) / 64 ) ) )
            b2 = math.floor( ( math.sin( ( math.sqrt( 128.0 + hypotenuse( size - i, size - j ) ) - 4.0 ) / 32.0 ) + 1 ) * 90 )
            table.insert( p1, b1 ); table.insert( p2, b2 )
        end
    end
end
function love.draw()
    local a, c1, c2, c3, s1, s2, s3
    currentTime = currentTime + math.random( 2 ) * 3
    local x1 = math.floor( half + ( half -  2 ) * math.sin(  currentTime /  47 ) )
    local x2 = math.floor( half + ( half /  7 ) * math.sin( -currentTime / 149 ) )
    local x3 = math.floor( half + ( half -  3 ) * math.sin( -currentTime / 157 ) )
    local y1 = math.floor( half + ( half / 11 ) * math.cos(  currentTime /  71 ) )
    local y2 = math.floor( half + ( half -  5 ) * math.cos( -currentTime / 181 ) )
    local y3 = math.floor( half + ( half / 23 ) * math.cos( -currentTime / 137 ) )
    s1 = y1 * doub + x1; s2 = y2 * doub + x2; s3 = y3 * doub + x3
    for j = 0, size do
        for i = 0, size do
            a = p2[s1] + p1[s2] + p2[s3]
            c1 = a * 2; c2 = a * 4; c3 = a * 8
            table.insert( points, { i, j, c1, c2, c3, 255 } )
            s1 = s1 + 1; s2 = s2 + 1; s3 = s3 + 1;
        end
        s1 = s1 + size; s2 = s2 + size; s3 = s3 + size
    end
    _.points( points )
end


/* REXX needed by some... */
z='1 -12 0 -42'  /* Numerator   */
n='1 -3'         /* Denominator */
zx=z
nx=n copies('0 ',words(z)-words(n))
qx=''            /* Quotient    */
Do Until words(zx)<words(n)
  Parse Value div(zx,nx) With q zx
  qx=qx q
  nx=subword(nx,1,words(nx)-1)
  End
Say '('show(z)')/('show(n)')=('show(qx)')'
Say 'Remainder:' show(zx)
Exit
div: Procedure
Parse Arg z,n
q=word(z,1)/word(n,1)
zz=''
Do i=1 To words(z)
  zz=zz word(z,i)-q*word(n,i)
  End
Return q subword(zz,2)

show: Procedure
Parse Arg poly
d=words(poly)-1
res=''
Do i=1 To words(poly)
  Select
    When d>1 Then fact='*x**'d
    When d=1 Then fact='*x'
    Otherwise     fact=''
    End
  Select
    When word(poly,i)=0  Then p=''
    When word(poly,i)=1  Then p='+'substr(fact,2)
    When word(poly,i)=-1 Then p='-'substr(fact,2)
    When word(poly,i)<0  Then p=word(poly,i)||fact
    Otherwise                 p='+'word(poly,i)||fact
    End
  res=res p
  d=d-1
  End
Return strip(space(res,0),'L','+')


      PD_RETURNDC = 256
      _LOGPIXELSY = 90

      DIM pd{lStructSize%, hwndOwner%, hDevMode%, hDevNames%, \
      \      hdc%, flags%, nFromPage{l&,h&}, nToPage{l&,h&}, \
      \      nMinPage{l&,h&}, nMaxPage{l&,h&}, nCopies{l&,h&}, \
      \      hInstance%, lCustData%, lpfnPrintHook%, lpfnSetupHook%, \
      \      lpPrintTemplateName%, lpSetupTemplateName%, \
      \      hPrintTemplate%, hSetupTemplate%}
      pd.lStructSize% = DIM(pd{})
      pd.hwndOwner% = @hwnd%
      pd.flags% = PD_RETURNDC

      SYS "PrintDlg", pd{} TO ok%
      IF ok%=0 THEN QUIT
      SYS "DeleteDC", @prthdc%
      @prthdc% = pd.hdc%
      *MARGINS 0,0,0,0

      dx% = @vdu%[email protected]%!232
      dy% = @vdu%[email protected]%!240
      SYS "GetDeviceCaps", @prthdc%, _LOGPIXELSY TO dpi%

      DIM rc{l%,t%,r%,b%}
      SYS "CreateSolidBrush", 0 TO brush%

      VDU 2,1,32,3
      pitch% = 2
      FOR y% = 0 TO dy% STEP dpi%
        FOR x% = 0 TO dx%-pitch% STEP pitch%
          rc.l% = x% : rc.r% = x% + pitch%/2
          rc.t% = y% : rc.b% = y% + dpi%
          SYS "FillRect", @prthdc%, rc{}, brush%
        NEXT
        pitch% += 2
      NEXT y%
      VDU 2,1,12,3


package main

import (
    "github.com/fogleman/gg"
    "log"
    "os/exec"
    "runtime"
)

var palette = [2]string{
    "FFFFFF", // white
    "000000", // black
}

func pinstripe(dc *gg.Context) {
    w := dc.Width()
    h := dc.Height() / 7
    for b := 1; b <= 11; b++ {
        for x, ci := 0, 0; x < w; x, ci = x+b, ci+1 {
            dc.SetHexColor(palette[ci%2])
            y := h * (b - 1)
            dc.DrawRectangle(float64(x), float64(y), float64(b), float64(h))
            dc.Fill()
        }
    }
}

func main() {
    dc := gg.NewContext(842, 595)
    pinstripe(dc)
    fileName := "w_pinstripe.png"
    dc.SavePNG(fileName)
    var cmd *exec.Cmd
    if runtime.GOOS == "windows" {
        cmd = exec.Command("mspaint", "/pt", fileName)
    } else {
        cmd = exec.Command("lp", fileName)
    }
    if err := cmd.Run(); err != nil {
        log.Fatal(err)
    }
}


using FileIO, ImageIO

function getnumberwithprompt(prompt, t::Type)
    s = ""
    while (x = tryparse(t, s)) == nothing
        print("\n", prompt, ": -> ")
        s = strip(readline())
    end
    return x
end

dpi = getnumberwithprompt("Printer DPI (dots per inch)", Int)
pwidth = getnumberwithprompt("Printer width (inches)", Float64)
plength = 10.0

imgwidth, imgheight = Int(round(pwidth * dpi)), Int(round(plength * dpi))

img = zeros(UInt8, Int(round(imgheight)), Int(round(imgwidth)))

for row in 1:imgheight, col in 1:imgwidth
    stripewidth = div(row, dpi) + 1
    img[row, col] = rem(col, stripewidth * 2) < stripewidth ? 0 : 255
end

save("temp.png", img)
run(`print temp.png`)  # the run statement may need to be set up for the installed device


nomainwin

'paperW =  8.5  ' for US letter paper
'paperH = 11

paperW =  8.2677165   '   for A4 paper
paperH = 11.6929134

dpi= 300

prompt "Enter your printer DPI" +chr$( 13) + "(300 is OK for laser one, 360 likely for inkjet)"; dpi

w = paperW *dpi    'pixel size of paper
h = paperH *dpi

graphicbox #main.gr, 0, 0, 300, 300 'picture could be bigger

open "Pinstripe/Printer" for window as #main

#main    "trapclose [quit]"
#main.gr "autoresize"   'now we can maximize window with picture
#main.gr "down"
#main.gr "horizscrollbar on 0 "; w -300  'so we can scroll it
#main.gr "vertscrollbar  on 0 "; h -300
#main.gr "place 0 0"
#main.gr "color white"
#main.gr "boxfilled "; w; " ";h
#main.gr "color black"
#main.gr "backcolor black"

for i = 0 to int( paperH)
    ww = i + 1
    yy =( i + 1) * dpi
    if yy > h then yy = h
    for x = ww to w step ww * 2   'start with white strip
        x1 = x + ww
        if x1 >= w then x1 = w
        #main.gr "place "; x; " "; i * dpi
        #main.gr "boxfilled "; x1; " "; yy
    next
next

#main.gr "flush"
#main.gr "print "; w

wait
[quit]
close #main
end


import math
import imageman

const
  Width = 400
  Height = 400

var img = initImage[ColorRGBF](Width, Height)
for x in 0..<Width:
  for y in 0..<Height:
    let fx = float32(x)
    let fy = float32(y)
    var hue = sin(fx / 16) + sin(fy / 8) + sin((fx + fy) / 16) + sin(sqrt((fx^2 + fy^2)) / 8)
    hue = (hue + 4) / 8   # Between 0 and 1.
    let rgb = to(ColorHSL([hue * 360, 1, 0.5]), ColorRGBF)
    img[x, y] = rgb
  img.savePNG("plasma.png")


; creating the "plasma" image buffer
(import (scheme inexact))
(define plasma
   (fold append #null
      (map (lambda (y)
            (map (lambda (x)
                  (let ((value (/
                           (+ (sin (/ y 4))
                              (sin (/ (+ x y) 8))
                              (sin (/ (sqrt (+ (* x x) (* y y))) 8))
                              4) 8)))
                     value))
               (iota 256)))
         (iota 256))))


use Imager;

sub plasma {
    my ($w, $h) = @_;

    my $img = Imager->new(xsize => $w, ysize => $h);

    for my $x (0 .. $w-1) {
        for my $y (0 .. $h-1) {
            my $hue = 4 + sin($x/19) + sin($y/9) + sin(($x+$y)/25) + sin(sqrt($x**2 + $y**2)/8);
            $img->setpixel(x => $x, y => $y, color => {hsv => [360 * $hue / 8, 1, 1]});
        }
    }

    return $img;
}

my $img = plasma(400, 400);
$img->write(file => 'plasma-perl.png');


def polynomial_long_division(numerator, denominator)
  dd = degree(denominator)
  raise ArgumentError, "denominator is zero" if dd < 0
  if dd == 0
    return [multiply(numerator, 1.0/denominator[0]), [0]*numerator.length]
  end

  q = [0] * numerator.length

  while (dn = degree(numerator)) >= dd
    d = shift_right(denominator, dn - dd)
    q[dn-dd] = numerator[dn] / d[degree(d)]
    d = multiply(d, q[dn-dd])
    numerator = subtract(numerator, d)
  end

  [q, numerator]
end

def degree(ary)
  idx = ary.rindex(&:nonzero?)
  idx ? idx : -1
end

def shift_right(ary, n)
  [0]*n + ary[0, ary.length - n]
end

def subtract(a1, a2)
  a1.zip(a2).collect {|v1,v2| v1 - v2}
end

def multiply(ary, num)
  ary.collect {|x| x * num}
end

f = [-42, 0, -12, 1]
g = [-3, 1, 0, 0]
q, r = polynomial_long_division(f, g)
puts "#{f} / #{g} => #{q} remainder #{r}"
# => [-42, 0, -12, 1] / [-3, 1, 0, 0] => [-27, -9, 1, 0] remainder [-123, 0, 0, 0]

g = [-3, 1, 1, 0]
q, r = polynomial_long_division(f, g)
puts "#{f} / #{g} => #{q} remainder #{r}"
# => [-42, 0, -12, 1] / [-3, 1, 1, 0] => [-13, 1, 0, 0] remainder [-81, 16, 0, 0]


func poly_long_div(rn, rd) {

    var n = rn.map{_}
    var gd = rd.len

    if (n.len >= gd) {
        return(gather {
            while (n.len >= gd) {
                var piv = n[0]/rd[0]
                take(piv)
                { |i|
                    n[i] -= (rd[i] * piv)
                } << ^(n.len `min` gd)
                n.shift
            }
        }, n)
    }

    return([0], rn)
}


import gintro/[glib, gobject, gtk, gio, cairo]

const Colors = [[255.0, 255.0, 255.0], [0.0, 0.0, 0.0]]

#---------------------------------------------------------------------------------------------------

proc beginPrint(op: PrintOperation; printContext: PrintContext; data: pointer) =
  ## Process signal "begin_print", that is set the number of pages to print.
  op.setNPages(1)

#---------------------------------------------------------------------------------------------------

proc drawPage(op: PrintOperation; printContext: PrintContext; pageNum: int; data: pointer) =
  ## Draw a page.

  let context = printContext.getCairoContext()
  let lineHeight = printContext.height / 4

  var y = 0.0
  for lineWidth in [1.0, 2.0, 3.0, 4.0]:
    context.setLineWidth(lineWidth)
    var x = 0.0
    var colorIndex = 0
    while x < printContext.width:
      context.setSource(Colors[colorIndex])
      context.moveTo(x, y)
      context.lineTo(x, y + lineHeight)
      context.stroke()
      colorIndex = 1 - colorIndex
      x += lineWidth
    y += lineHeight

#---------------------------------------------------------------------------------------------------

proc activate(app: Application) =
  ## Activate the application.

  # Launch a print operation.
  let op = newPrintOperation()
  op.connect("begin_print", beginPrint, pointer(nil))
  op.connect("draw_page", drawPage, pointer(nil))

  # Run the print dialog.
  discard op.run(printDialog)

#———————————————————————————————————————————————————————————————————————————————————————————————————

let app = newApplication(Application, "Rosetta.Pinstripe")
discard app.connect("activate", activate)
discard app.run()


(load "@lib/ps.l")

(call 'lpr
   (pdf "pinstripes"
      (a4)  # 595 x 842 dots
      (for X 595
         (gray (if (bit? 1 X) 0 100)
            (vline X 0 842) ) )
      (page) ) )


#lang racket/gui

(define parts 4)

(define dc (new printer-dc%))
(send* dc (start-doc "Pinstripe") (start-page))

(define-values [W H] (send dc get-size))
(send dc set-pen "black" 0 'solid)
(send dc set-brush "black" 'solid)
(define H* (round (/ H parts)))
(for ([row parts])
  (define Y (* row H*))
  (for ([X (in-range 0 W (* (add1 row) 2))])
    (send dc draw-rectangle X Y (add1 row) H*)))

(send* dc (end-page) (end-doc))


unit sub MAIN ($dpi = 300, $size = 'letter');

my $filename = './Pinstripe-printer-perl6.png';

my %paper = (
    'letter' => { :width(8.5),    :height(11.0) }
    'A4'     => { :width(8.2677), :height(11.6929)}
);

my ($w, $h) = %paper{$size}<width height> »*» $dpi;

# Black. It's all black
my @color = (0,0,0),;

my $gap = floor $w % ($dpi * 8) / 2;

my $rows = (1, * * 2 … * > 8 * $dpi).elems;

my $height = $dpi * .8;

use Cairo;

my @colors = @color.map: { Cairo::Pattern::Solid.new.create(|$_) };

given Cairo::Image.create(Cairo::FORMAT_ARGB32, $w, $h) -> $image {
    given Cairo::Context.new($image) {
        my Cairo::Pattern::Solid $bg .= create(1,1,1);
        .rectangle(0, 0, $w, $h);
        .pattern($bg);
        .fill;
        $bg.destroy;
        my $y = $gap;
        for ^$rows -> $row {
            my $x = $gap;
            my $width = 8 * $dpi / (2 ** $row);
            for @colors -> $this {
                my $v = 0;
                while $x < ($dpi * 8) {
                    given Cairo::Context.new($image) -> $block {
                        $block.rectangle($x, $y, $width, $height);
                        $block.pattern($this);
                        $block.fill;
                        $block.destroy;
                    }
                    $x += $width * 2;
                }
            }
            $y += $height;
        }
    }
    $image.write_png($filename);
}

# Uncomment next line if you actually want to print it
#run('lp', $filename)


-- demo\rosetta\plasma.exw
include pGUI.e

Ihandle dlg, canvas
cdCanvas cddbuffer, cdcanvas

sequence plasma
integer pw = 0, ph = 0

procedure createPlasma(integer w, h)
    plasma = repeat(repeat(0,w),h)
    for y=1 to h do
        for x=1 to w do
            atom v = sin(x/16)
            v += sin(y/8)
            v += sin((x+y)/16)
            v += sin(sqrt(x*x + y*y)/8)
            v += 4 -- shift range from -4 .. 4 to 0 .. 8
            v /= 8 -- bring range down to 0 .. 1
            plasma[y][x] = v
        end for
    end for
    pw = w
    ph = h
end procedure

atom hueShift = 0

procedure drawPlasma(integer w, h)
    hueShift = remainder(hueShift + 0.02,1)
    sequence rgb3 = repeat(repeat(0,w*h),3)
    integer cx = 1
    for y=1 to h do
        for x=1 to w do
            atom hue = hueShift + remainder(plasma[y][x],1)
            integer i = floor(hue * 6)
            atom t = 255,
                 f = (hue * 6 - i)*t,
                 q = t - f,
                 r, g, b
            switch mod(i,6) do
                case 0: r = t; g = f; b = 0
                case 1: r = q; g = t; b = 0
                case 2: r = 0; g = t; b = f
                case 3: r = 0; g = q; b = t
                case 4: r = f; g = 0; b = t
                case 5: r = t; g = 0; b = q
            end switch
            rgb3[1][cx] = r
            rgb3[2][cx] = g
            rgb3[3][cx] = b
            cx += 1
        end for
    end for
    cdCanvasPutImageRectRGB(cddbuffer, w, h, rgb3, 0, 0, 0, 0, 0, 0, 0, 0)
end procedure

function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/)
    atom {w,h} = IupGetIntInt(canvas, "DRAWSIZE")
    if pw!=w or ph!=h then
        createPlasma(w,h)
    end if
    cdCanvasActivate(cddbuffer)
    drawPlasma(w,h)
    cdCanvasFlush(cddbuffer)
    return IUP_DEFAULT
end function

function timer_cb(Ihandle /*ih*/)
    IupUpdate(canvas)
    return IUP_IGNORE
end function

function map_cb(Ihandle ih)
    cdcanvas = cdCreateCanvas(CD_IUP, ih)
    cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas)
    cdCanvasSetBackground(cddbuffer, CD_WHITE)
    cdCanvasSetForeground(cddbuffer, CD_GRAY)
    return IUP_DEFAULT
end function

procedure main()
    IupOpen()

    canvas = IupCanvas(NULL)
    IupSetAttribute(canvas, "RASTERSIZE", "450x300")
    IupSetCallback(canvas, "MAP_CB", Icallback("map_cb"))
    IupSetCallback(canvas, "ACTION", Icallback("redraw_cb"))

    dlg = IupDialog(canvas)
    IupSetAttribute(dlg, "TITLE", "Plasma")

    IupShow(dlg)
    IupSetAttribute(canvas, "RASTERSIZE", NULL)
    Ihandle timer = IupTimer(Icallback("timer_cb"), 50)
    IupMainLoop()
    IupClose()
end procedure

main()


/**
 Plasmas with Palette Looping
 https://lodev.org/cgtutor/plasma.html#Plasmas_with_Palette_Looping_
 */

int pal[] = new int[128];
int[] buffer;
float r = 42, g = 84, b = 126;
boolean rd, gd, bd;

void setup() {
  size(600, 600);
  frameRate(25);
  buffer = new int[width*height];
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      buffer[x+y*width] = int(((128+(128*sin(x/32.0)))
        +(128+(128*cos(y/32.0)))
        +(128+(128*sin(sqrt((x*x+y*y))/32.0))))/4);
    }
  }
}

void draw() {
  if (r > 128) rd = true;
  if (!rd) r++;
  else r--;
  if (r < 0) rd = false;
  if (g > 128) gd = true;
  if (!gd) g++;
  else g--;
  if (r < 0) gd = false;
  if (b > 128) bd = true;
  if (!bd) b++;
  else b--;
  if (b < 0){ bd = false;}
  float s_1, s_2;
  for (int i = 0; i < 128; i++) {
    s_1 = sin(i*PI/25);
    s_2 = sin(i*PI/50+PI/4);
    pal[i] = color(r+s_1*128, g+s_2*128, b+s_1*128);
  }
  loadPixels();
  for (int i = 0; i < buffer.length; i++) {
    pixels[i] =  pal[(buffer[i]+frameCount)&127];
  }
  updatePixels();
}


define: #Polynomial &parents: {Comparable} &slots: {#coefficients -> ExtensibleArray new}.

[email protected](Polynomial traits) new &capacity: n
[
  p cloneSettingSlots: #(coefficients) to: {p coefficients new &capacity: n}
].

[email protected](Polynomial traits) newFrom: [email protected](Sequence traits)
[
  p clone `>> [coefficients: (seq as: p coefficients). normalize. ]
].

[email protected](Polynomial traits) copy
[
  p cloneSettingSlots: #(coefficients) to: {p coefficients copy}
].

[email protected](Polynomial traits) >= [email protected](Polynomial traits)
[p1 degree >= p2 degree].

[email protected](Polynomial traits) degree
[p coefficients indexOfLastSatisfying: [| :n | n isZero not]].

[email protected](Polynomial traits) normalize
[
  [p degree isPositive /\ [p coefficients last isZero]]
    whileTrue: [p coefficients removeLast]
].

[email protected](Polynomial traits) * [email protected](Number traits)
[
  p newFrom: (p coefficients collect: [| :x | x * n])
].

[email protected](Polynomial traits) / [email protected](Number traits)
[
  p newFrom: (p coefficients collect: [| :x | x / n])
].

[email protected](Polynomial traits) minusCoefficients: [email protected](Polynomial traits)
[
  p1 newFrom: (p1 coefficients with: p2 coefficients collect: #- `er)
].

[email protected](Polynomial traits) / [email protected](Polynomial traits)
[
  p >= denom
    ifTrue:
      [| n q |
       n: p copy.
       q: p new.
       [n >= denom]
          whileTrue:
            [| piv |
	     piv: p coefficients last / denom coefficients last.
	     q coefficients add: piv.
	     n: (n minusCoefficients: denom * piv).
	     n normalize].
       n coefficients isEmpty ifTrue: [n coefficients add: 0].
       {q. n}]
    ifFalse: [{p newFrom: #(0). p copy}]
].


Object subclass: Polynomial [
  |coeffs|
  Polynomial class >> new [ ^ super basicNew init ]
  init [ coeffs := OrderedCollection new. ^ self ]
  Polynomial class >> newWithCoefficients: coefficients [
    |r|
    r := super basicNew.
    ^ r initWithCoefficients: coefficients
  ]
  initWithCoefficients: coefficients [
    coeffs := coefficients asOrderedCollection.
    ^ self
  ]
  / denominator [ |n q|
    n := self deepCopy.
    self >= denominator
      ifTrue: [
        q := Polynomial new.
        [ n >= denominator ]
          whileTrue: [ |piv|
 	    piv := (n coeff: 0) / (denominator coeff: 0).
	    q addCoefficient: piv.
	    n := n - (denominator * piv).
	    n clean
          ].
        ^ { q . (n degree) > 0 ifTrue: [ n ] ifFalse: [ n addCoefficient: 0. n ] }
      ]
      ifFalse: [
        ^ { Polynomial newWithCoefficients: #( 0 ) . self deepCopy }
      ]
  ]
  * constant [ |r| r := self deepCopy.
    1 to: (coeffs size) do: [ :i |
      r at: i put: ((r at: i) * constant)
    ].
    ^ r
  ]
  at: index [ ^ coeffs at: index ]
  at: index put: obj [ ^ coeffs at: index put: obj ]
  >= anotherPoly [
    ^ (self degree) >= (anotherPoly degree)
  ]
  degree [ ^ coeffs size ]
  - anotherPoly [ "This is not a real subtraction between Polynomial: it is an
                   internal method ..."
    |a|
    a := self deepCopy.
    1 to: ( (coeffs size) min: (anotherPoly degree) ) do: [ :i |
      a at: i put: ( (a at: i) - (anotherPoly at: i) )
    ].
    ^ a
  ]
  coeff: index [ ^ coeffs at: (index + 1) ]
  addCoefficient: coeff [ coeffs add: coeff ]
  clean [
    [ (coeffs size) > 0
        ifTrue: [ (coeffs at: 1) = 0 ] ifFalse: [ false ] ]
      whileTrue: [ coeffs removeFirst ].
  ]
  display [
    1 to: (coeffs size) do: [ :i |
      (coeffs at: i) display.
      i < (coeffs size)
        ifTrue: [ ('x^%1 + ' % {(coeffs size) - i} ) display ]
    ]
  ]
  displayNl [ self display. Character nl display ]
].


package require Tk
# Allocate a temporary drawing surface
canvas .c
# Draw the output we want
for {set y 0;set dx 1} {$y < 11*72} {incr y 72;incr dx} {
    for {set x 0;set c 0} {$x < 8.5*72} {incr x $dx;set c [expr {!$c}]} {
	.c create rectangle $x $y [expr {$x+$dx+1}] [expr {$y+73}] \
	    -fill [lindex {black white} $c] -outline {}
    }
}
# Send postscript to default printer, scaled 1 pixel -> 1 point
exec lp - << [.c postscript -height $y -width $x -pageheight $y -pagewidth $x]
# Explicit exit; no GUI desired
exit


/* gcc -O3 -std=c11 -shared -o printer.so -fPIC  -I./include printer.c */

#include <stdlib.h>
#include <string.h>
#include "dome.h"

static DOME_API_v0* core;
static WREN_API_v0* wren;

static const char* source =  ""
"class Printer {\n"
  "foreign static printFile(name) \n"
"} \n";

void C_printFile(WrenVM* vm) {
    const char *arg = wren->getSlotString(vm, 1);
    char command[strlen(arg) + 4];
    strcpy(command, "lp ");
    strcat(command, arg);
    int res = system(command);
}

DOME_EXPORT DOME_Result PLUGIN_onInit(DOME_getAPIFunction DOME_getAPI, DOME_Context ctx) {
    core = DOME_getAPI(API_DOME, DOME_API_VERSION);
    wren = DOME_getAPI(API_WREN, WREN_API_VERSION);
    core->registerModule(ctx, "printer", source);
    core->registerClass(ctx, "printer", "Printer", NULL, NULL);
    core->registerFn(ctx, "printer", "static Printer.printFile(_)", C_printFile);
    return DOME_RESULT_SUCCESS;
}

DOME_EXPORT DOME_Result PLUGIN_preUpdate(DOME_Context ctx) {
    return DOME_RESULT_SUCCESS;
}

DOME_EXPORT DOME_Result PLUGIN_postUpdate(DOME_Context ctx) {
    return DOME_RESULT_SUCCESS;
}

DOME_EXPORT DOME_Result PLUGIN_preDraw(DOME_Context ctx) {
    return DOME_RESULT_SUCCESS;
}

DOME_EXPORT DOME_Result PLUGIN_postDraw(DOME_Context ctx) {
    return DOME_RESULT_SUCCESS;
}

DOME_EXPORT DOME_Result PLUGIN_onShutdown(DOME_Context ctx) {
    return DOME_RESULT_SUCCESS;
}


import math
import colorsys
from PIL import Image

def plasma (w, h):
	out = Image.new("RGB", (w, h))
	pix = out.load()
	for x in range (w):
		for y in range(h):
			hue = 4.0 + math.sin(x / 19.0) + math.sin(y / 9.0) \
				+ math.sin((x + y) / 25.0) + math.sin(math.sqrt(x**2.0 + y**2.0) / 8.0)
			hsv = colorsys.hsv_to_rgb(hue/8.0, 1, 1)
			pix[x, y] = tuple([int(round(c * 255.0)) for c in hsv])
	return out

if __name__=="__main__":
	im = plasma(400, 400)
	im.show()


#lang racket
;;  from lisp (cos I could just lift the code)
(require images/flomap
         2htdp/universe
         racket/flonum)

;; copied from pythagoras-triangle#racket
(define (real-remainder x q) (- x (* (floor (/ x q)) q)))

(define (HSV->RGB H S V)
  (define C (* V S)) ; chroma
  (define H′ (/ H 60))
  (define X (* C (- 1 (abs (- (real-remainder H′ 2) 1)))))
  (define-values (R1 G1 B1)
    (cond
      [(< H′ 1) (values C X 0.)]
      [(< H′ 2) (values X C 0.)]
      [(< H′ 3) (values 0. C X)]
      [(< H′ 4) (values 0. X C)]
      [(< H′ 5) (values X 0. C)]
      [(< H′ 6) (values C 0. X)]
      [else (values 0. 0. 0.)]))
  (define m (- V C))
  (values (+ R1 m) (+ G1 m) (+ B1 m)))

(define ((colour-component-by-pos ϕ) k x y)
  (let ((rv
         (/ (+ (+ 1/2 (* 1/2 (sin (+ ϕ (/ x 16.0)))))
               (+ 1/2 (* 1/2 (sin (+ ϕ (/ y 8.0)))))
               (+ 1/2 (* 1/2 (sin (+ ϕ (/ (+ x y) 16.0)))))
               (+ 1/2 (* 1/2 (sin (+ ϕ (/ (sqrt (+ (sqr x) (sqr y))) 8.0))))))
            4.0)))
    rv))

(define ((plasma-flomap (ϕ 0)) w h)
  (build-flomap 1 w h (colour-component-by-pos ϕ)))

(define ((plasma-image (ϕ 0)) w h)
  (flomap->bitmap ((plasma-flomap ϕ) w h)))

(define ((colour-plasma plsm) t)
  (let ((w (flomap-width plsm))
        (h (flomap-height plsm)))
    (flomap->bitmap
     (build-flomap* 3 w h
                    (λ (x y)
                      (define-values (r g b)
                        (HSV->RGB (real-remainder
                                   (+ (* t 5.)
                                      (* 360 (flomap-ref plsm 0 x y)))
                                   360.) 1. 1.))
                      (flvector r g b))))))

;((plasma-image) 200 200)

;((plasma-image (/ pi 32)) 200 200)

(define plsm ((plasma-flomap) 300 300))
  (animate (λ (t)
             ((colour-plasma plsm) t)))


(1) -> monicDivide(x^3-12*x^2-42,x-3,'x)

                     2
   (1)  [quotient = x  - 9x - 27,remainder = - 123]

   Type: Record(quotient: Polynomial(Integer),remainder: Polynomial(Integer))


protocol Dividable {
  static func / (lhs: Self, rhs: Self) -> Self
}

extension Int: Dividable { }

struct Solution<T> {
  var quotient: [T]
  var remainder: [T]
}

func polyDegree<T: SignedNumeric>(_ p: [T]) -> Int {
  for i in stride(from: p.count - 1, through: 0, by: -1) where p[i] != 0 {
    return i
  }

  return Int.min
}

func polyShiftRight<T: SignedNumeric>(p: [T], places: Int) -> [T] {
  guard places > 0 else {
    return p
  }

  let deg = polyDegree(p)

  assert(deg + places < p.count, "Number of places to shift too large")

  var res = p

  for i in stride(from: deg, through: 0, by: -1) {
    res[i + places] = res[i]
    res[i] = 0
  }

  return res
}

func polyMul<T: SignedNumeric>(_ p: inout [T], by: T) {
  for i in 0..<p.count {
    p[i] *= by
  }
}

func polySub<T: SignedNumeric>(_ p: inout [T], by: [T]) {
  for i in 0..<p.count {
    p[i] -= by[i]
  }
}

func polyLongDiv<T: SignedNumeric & Dividable>(numerator n: [T], denominator d: [T]) -> Solution<T>? {
  guard n.count == d.count else {
    return nil
  }

  var nDeg = polyDegree(n)
  let dDeg = polyDegree(d)

  guard dDeg >= 0, nDeg >= dDeg else {
    return nil
  }

  var n2 = n
  var quo = [T](repeating: 0, count: n.count)

  while nDeg >= dDeg {
    let i = nDeg - dDeg
    var d2 = polyShiftRight(p: d, places: i)

    quo[i] = n2[nDeg] / d2[nDeg]

    polyMul(&d2, by: quo[i])
    polySub(&n2, by: d2)

    nDeg = polyDegree(n2)
  }

  return Solution(quotient: quo, remainder: n2)
}

func polyPrint<T: SignedNumeric & Comparable>(_ p: [T]) {
  let deg = polyDegree(p)

  for i in stride(from: deg, through: 0, by: -1) where p[i] != 0 {
    let coeff = p[i]

    switch coeff {
    case 1 where i < deg:
      print(" + ", terminator: "")
    case 1:
      print("", terminator: "")
    case -1 where i < deg:
      print(" - ", terminator: "")
    case -1:
      print("-", terminator: "")
    case _ where coeff < 0 && i < deg:
      print(" - \(-coeff)", terminator: "")
    case _ where i < deg:
      print(" + \(coeff)", terminator: "")
    case _:
      print("\(coeff)", terminator: "")
    }

    if i > 1 {
      print("x^\(i)", terminator: "")
    } else if i == 1 {
      print("x", terminator: "")
    }
  }

  print()
}

let n = [-42, 0, -12, 1]
let d = [-3, 1, 0, 0]

print("Numerator: ", terminator: "")
polyPrint(n)
print("Denominator: ", terminator: "")
polyPrint(d)

guard let sol = polyLongDiv(numerator: n, denominator: d) else {
  fatalError()
}

print("----------")
print("Quotient: ", terminator: "")
polyPrint(sol.quotient)
print("Remainder: ", terminator: "")
polyPrint(sol.remainder)


# poldiv - Divide two polynomials n and d.
#          Result is a list of two polynomials, q and r, where n = qd + r
#          and the degree of r is less than the degree of b.
#          Polynomials are represented as lists, where element 0 is the
#          x**0 coefficient, element 1 is the x**1 coefficient, and so on.

proc poldiv {a b} {
    # Toss out leading zero coefficients efficiently
    while {[lindex $a end] == 0} {set a [lrange $a[set a {}] 0 end-1]}
    while {[lindex $b end] == 0} {set b [lrange $b[set b {}] 0 end-1]}
    if {[llength $a] < [llength $b]} {
        return [list 0 $a]
    }

    # Rearrange the terms to put highest powers first
    set n [lreverse $a]
    set d [lreverse $b]

    # Carry out classical long division, accumulating quotient coefficients
    # in q, and replacing n with the remainder.
    set q {}
    while {[llength $n] >= [llength $d]} {
        set qd [expr {[lindex $n 0] / [lindex $d 0]}]
        set i 0
        foreach nd [lrange $n 0 [expr {[llength $d] - 1}]] dd $d {
            lset n $i [expr {$nd - $qd * $dd}]
            incr i
        }
        lappend q $qd
        set n [lrange $n 1 end]
    }

    # Return quotient and remainder, constant term first
    return [list [lreverse $q] [lreverse $n]]
}

# Demonstration
lassign [poldiv {-42. 0. -12. 1.} {-3. 1. 0. 0.}] Q R
puts [list Q = $Q]
puts [list R = $R]


# Project : Plasma effect

load "guilib.ring"

paint = null

new qapp
       {
        win1 = new qwidget()
       {
                   setwindowtitle("Plasma effect")
                   setgeometry(100,100,500,600)

                   label1 = new qlabel(win1)
                   {
                   setgeometry(10,10,400,400)
                   settext("")
                    }

                   new qpushbutton(win1)
                   {
                   setgeometry(150,500,100,30)
                   settext("Draw")
                   setclickevent("Draw()")
                  }
                  show()
       }
       exec()
       }

func draw

        p1    = new qpicture()
        color = new qcolor() { setrgb(0,0,255,255) }   ### <<< BLUE
        pen   = new qpen() { setcolor(color) setwidth(1) }

        paint = new qpainter()
        {
                   begin(p1)
                   setpen(pen)

                   w = 256
                   h = 256
                   time = 0

                   for x = 0 to w -1
                         for y = 0 to h -1
                               time = time + 0.99
                               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 = floor(value * 32)
                               r = c
                               g = (c*2)%255
                               b = 255-c
                               color2 = new qcolor()
                               color2.setrgb(r,g,b,255)
                               pen.setcolor(color2)
                               setpen(pen)
                               drawpoint(x,y)
                        next
                   next
        endpaint()
        }
        label1 { setpicture(p1) show() }
        return

func dist(a, b, c, d)
        d = sqrt(((a - c) * (a - c) + (b - d) * (b - d)))
        return d


attr_reader :buffer, :palette, :r, :g, :b, :rd, :gd, :bd, :dim

def settings
  size(600, 600)
end

def setup
  sketch_title 'Plasma Effect'
  frame_rate 25
  @r = 42
  @g = 84
  @b = 126
  @rd = true
  @gd = true
  @bd = true
  @dim = width * height
  @buffer = Array.new(dim)
  grid(width, height) do |x, y|
    buffer[x + y * width] = (
      (
        (128 + (128 * sin(x / 32.0))) +
        (128 + (128 * cos(y / 32.0))) +
        (128 + (128 * sin(Math.hypot(x, y) / 32.0)))
      ) / 4
    ).to_i
  end
  load_pixels
end

def draw
  if rd
    @r -= 1
    @rd = false if r.negative?
  else
    @r += 1
    @rd = true if r > 128
  end
  if gd
    @g -= 1
    @gd = false if g.negative?
  else
    @g += 1
    @gd = true if g > 128
  end
  if bd
    @b -= 1
    @bd = false if b.negative?
  else
    @b += 1
    @bd = true if b > 128
  end
  @palette = (0..127).map do |col|
    s1 = sin(col * Math::PI / 25)
    s2 = sin(col * Math::PI / 50 + Math::PI / 4)
    color(r + s1 * 128, g + s2 * 128, b + s1 * 128)
  end
  dim.times do |idx|
    pixels[idx] = palette[(buffer[idx] + frame_count) & 127]
  end
  update_pixels
end


#import std
#import flo

polydiv =

zeroid~-l~~; leql?rlX\~&NlX ^H\(@rNrNSPXlHDlS |\ :/0.) @NlX //=> ?(
   @lrrPX ==!| zipp0.; @x not zeroid+ [email protected]>hr ~&t,
   (^lryPX/~&lrrl2C minus^*p/~&rrr times*lrlPD)^/[email protected] ~&,
   @r ^|\~& ~&i&& :/0.)


Option Base 1
Function degree(p As Variant)
    For i = UBound(p) To 1 Step -1
        If p(i) <> 0 Then
            degree = i
            Exit Function
        End If
    Next i
    degree = -1
End Function

Function poly_div(ByVal n As Variant, ByVal d As Variant) As Variant
    If UBound(d) < UBound(n) Then
        ReDim Preserve d(UBound(n))
    End If
    Dim dn As Integer: dn = degree(n)
    Dim dd As Integer: dd = degree(d)
    If dd < 0 Then
        poly_div = CVErr(xlErrDiv0)
        Exit Function
    End If
    Dim quot() As Integer
    ReDim quot(dn)
    Do While dn >= dd
        Dim k As Integer: k = dn - dd
        Dim qk As Integer: qk = n(dn) / d(dd)
        quot(k + 1) = qk
        Dim d2() As Variant
        d2 = d
        ReDim Preserve d2(UBound(d) - k)
        For i = 1 To UBound(d2)
            n(UBound(n) + 1 - i) = n(UBound(n) + 1 - i) - d2(UBound(d2) + 1 - i) * qk
        Next i
        dn = degree(n)
    Loop
    poly_div = Array(quot, n) '-- (n is now the remainder)
End Function

Function poly(si As Variant) As String
'-- display helper
    Dim r As String
    For t = UBound(si) To 1 Step -1
        Dim sit As Integer: sit = si(t)
        If sit <> 0 Then
            If sit = 1 And t > 1 Then
                r = r & IIf(r = "", "", " + ")
            Else
                If sit = -1 And t > 1 Then
                    r = r & IIf(r = "", "-", " - ")
                Else
                    If r <> "" Then
                        r = r & IIf(sit < 0, " - ", " + ")
                        sit = Abs(sit)
                    End If
                    r = r & CStr(sit)
                End If
            End If
            r = r & IIf(t > 1, "x" & IIf(t > 2, t - 1, ""), "")
        End If
    Next t
    If r = "" Then r = "0"
    poly = r
End Function

Function polyn(s As Variant) As String
    Dim t() As String
    ReDim t(2 * UBound(s))
    For i = 1 To 2 * UBound(s) Step 2
        t(i) = poly(s((i + 1) / 2))
    Next i
    t(1) = String$(45 - Len(t(1)) - Len(t(3)), " ") & t(1)
    t(2) = "/"
    t(4) = "="
    t(6) = "rem"
    polyn = Join(t, " ")
End Function

Public Sub main()
    Dim tests(7) As Variant
    tests(1) = Array(Array(-42, 0, -12, 1), Array(-3, 1))
    tests(2) = Array(Array(-3, 1), Array(-42, 0, -12, 1))
    tests(3) = Array(Array(-42, 0, -12, 1), Array(-3, 1, 1))
    tests(4) = Array(Array(2, 3, 1), Array(1, 1))
    tests(5) = Array(Array(3, 5, 6, -4, 1), Array(1, 2, 1))
    tests(6) = Array(Array(3, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 1), Array(1, 0, 0, 5, 0, 0, 0, 1))
    tests(7) = Array(Array(-56, 87, -94, -55, 22, -7), Array(2, 0, 1))
    Dim num As Variant, denom As Variant, quot As Variant, rmdr As Variant
    For i = 1 To 7
        num = tests(i)(1)
        denom = tests(i)(2)
        tmp = poly_div(num, denom)
        quot = tmp(1)
        rmdr = tmp(2)
        Debug.Print polyn(Array(num, denom, quot, rmdr))
    Next i
End Sub


extern crate image;

use image::ColorType;
use std::path::Path;

// Framebuffer dimensions
const WIDTH: usize = 640;
const HEIGHT: usize = 480;

/// Formula for plasma at any particular address
fn plasma_pixel(x: f64, y: f64) -> f64 {
    ((x / 16.0).sin()
        + (y / 8.0).sin()
        + ((x + y) / 16.0).sin()
        + ((x * x + y * y).sqrt() / 8.0).sin()
        + 4.0)
        / 8.0
}

/// Precalculate plasma field lookup-table for performance
fn create_plasma_lut() -> Vec<f64> {
    let mut plasma: Vec<f64> = vec![0.0; WIDTH * HEIGHT];
    for y in 0..HEIGHT {
        for x in 0..WIDTH {
            plasma[(y * WIDTH) + x] = plasma_pixel(x as f64, y as f64);
        }
    }
    plasma
}

/// Convert from HSV float(1.0,1.0,1.0) to RGB u8 tuple (255,255,255).
/// From https://crates.io/crates/palette 0.5.0 rgb.rs, simplified for example
fn hsv_to_rgb(hue: f64, saturation: f64, value: f64) -> (u8, u8, u8) {
    let c = value * saturation;
    let h = hue * 6.0;
    let x = c * (1.0 - (h % 2.0 - 1.0).abs());
    let m = value - c;
    let (red, green, blue) = match (h % 6.0).floor() as u32 {
        0 => (c, x, 0.0),
        1 => (x, c, 0.0),
        2 => (0.0, c, x),
        3 => (0.0, x, c),
        4 => (x, 0.0, c),
        _ => (c, 0.0, x),
    };
    // Convert back to RGB (where components are integers from 0 to 255)
    (
        ((red + m) * 255.0).round() as u8,
        ((green + m) * 255.0).round() as u8,
        ((blue + m) * 255.0).round() as u8,
    )
}
fn main() {
    // The bitmap/framebuffer for our application. 3 u8 elements per output pixel
    let mut framebuffer: Vec<u8> = vec![0; WIDTH * HEIGHT * 3];
    // Generate a lookup table so we don't do too much math for every pixel.
    // Do it in a function so that the local one can be immutable.
    let plasma_lookup_table = create_plasma_lut();
    // For each (r,g,b) pixel in our output buffer
    for (index, rgb) in framebuffer.chunks_mut(3).enumerate() {
        // Lookup the precalculated plasma value
        let hue_lookup = plasma_lookup_table[index] % 1.0;
        let (red, green, blue) = hsv_to_rgb(hue_lookup, 1.0, 1.0);
        rgb[0] = red;
        rgb[1] = green;
        rgb[2] = blue;
    }
    // Save our plasma image to out.png
    let output_path = Path::new("out.png");
    match image::save_buffer(
        output_path,
        framebuffer.as_slice(),
        WIDTH as u32,
        HEIGHT as u32,
        ColorType::RGB(8),
    ) {
        Err(e) => println!("Error writing output image:\n{}", e),
        Ok(_) => println!("Output written to:\n{}", output_path.to_str().unwrap()),
    }
}


import java.awt._
import java.awt.event.ActionEvent
import java.awt.image.BufferedImage

import javax.swing._

import scala.math.{sin, sqrt}

object PlasmaEffect extends App {

  SwingUtilities.invokeLater(() =>
    new JFrame("Plasma Effect") {

      class PlasmaEffect extends JPanel {
        private val (w, h) = (640, 640)
        private var hueShift = 0.0f

        override def paintComponent(gg: Graphics): Unit = {
          val g = gg.asInstanceOf[Graphics2D]

          def drawPlasma(g: Graphics2D) = {
            val img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB)

            for (y <- 0 until h;
                 x <- 0 until w) {

              def design =
                (sin(x / 16f) + sin(y / 8f) + sin((x + y) / 16f) + sin(sqrt(x * x + y * y) / 8f) + 4).toFloat / 8

              img.setRGB(x, y, Color.HSBtoRGB(hueShift + design % 1, 1, 1))
            }
            g.drawImage(img, 0, 0, null)
          }

          super.paintComponent(gg)
          g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
          drawPlasma(g)
        }

        // animate about 24 fps and shift hue value with every frame
        new Timer(42, (_: ActionEvent) => {
          hueShift = (hueShift + 0.02f) % 1
          repaint()
        }).start()

        setBackground(Color.white)
        setPreferredSize(new Dimension(h, w))
      }

      add(new PlasmaEffect, BorderLayout.CENTER)
      pack()
      setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
      setLocationRelativeTo(null)
      setResizable(false)
      setVisible(true)
    })

}


import "/dynamic" for Tuple

var Solution = Tuple.create("Solution", ["quotient", "remainder"])

var polyDegree = Fn.new { |p|
    for (i in p.count-1..0) if (p[i] != 0) return i
    return -2.pow(31)
}

var polyShiftRight = Fn.new { |p, places|
    if (places <= 0) return p
    var pd = polyDegree.call(p)
    if (pd + places >= p.count) {
        Fiber.abort("The number of places to be shifted is too large.")
    }
    var d = p.toList
    for (i in pd..0) {
        d[i + places] = d[i]
        d[i] = 0
    }
    return d
}

var polyMultiply = Fn.new { |p, m|
    for (i in 0...p.count) p[i] = p[i] * m
}

var polySubtract = Fn.new { |p, s|
    for (i in 0...p.count) p[i] = p[i] - s[i]
}

var polyLongDiv = Fn.new { |n, d|
    if (n.count != d.count) {
        Fiber.abort("Numerator and denominator vectors must have the same size")
    }
    var nd = polyDegree.call(n)
    var dd = polyDegree.call(d)
    if (dd < 0) {
        Fiber.abort("Divisor must have at least one one-zero coefficient")
    }
    if (nd < dd) {
        Fiber.abort("The degree of the divisor cannot exceed that of the numerator")
    }
    var n2 = n.toList
    var q = List.filled(n.count, 0)
    while (nd >= dd) {
        var d2 = polyShiftRight.call(d, nd - dd)
        q[nd - dd] = n2[nd] / d2[nd]
        polyMultiply.call(d2, q[nd - dd])
        polySubtract.call(n2, d2)
        nd = polyDegree.call(n2)
    }
    return Solution.new(q, n2)
}

var polyShow = Fn.new { |p|
    var pd = polyDegree.call(p)
    for (i in pd..0) {
        var coeff = p[i]
        if (coeff != 0) {
            System.write(
                (coeff ==  1) ? ((i < pd) ? " + " :  "") :
                (coeff == -1) ? ((i < pd) ? " - " : "-") :
                (coeff <   0) ? ((i < pd) ? " - %(-coeff)" : "%(coeff)") :
                                ((i < pd) ? " + %( coeff)" : "%(coeff)")
            )
            if (i > 1) {
                System.write("x^%(i)")
            } else if (i == 1) {
                System.write("x")
            }
        }
    }
    System.print()
}

var n = [-42, 0, -12, 1]
var d = [ -3, 1,   0, 0]
System.write("Numerator   : ")
polyShow.call(n)
System.write("Denominator : ")
polyShow.call(d)
System.print("-------------------------------------")
var sol = polyLongDiv.call(n, d)
System.write("Quotient    : ")
polyShow.call(sol.quotient)
System.write("Remainder   : ")
polyShow.call(sol.remainder)


require('Imager')

class Plasma(width=400, height=400) {

    has img = nil

    method init {
        img = %O|Imager|.new(xsize => width, ysize => height)
    }

    method generate {
        for y=(^height), x=(^width) {
            var hue = (4 + sin(x/19) + sin(y/9) + sin((x+y)/25) + sin(hypot(x, y)/8))
            img.setpixel(x => x, y => y, color => Hash(hsv => [360 * hue / 8, 1, 1]))
        }
    }

    method save_as(filename) {
        img.write(file => filename)
    }
}

var plasma = Plasma(256, 256)
plasma.generate
plasma.save_as('plasma.png')


import "graphics" for Canvas, Color, ImageData
import "dome" for Window
import "math" for Math

class PlasmaEffect {
    construct new(width, height) {
        Window.title = "Plasma Effect"
        Window.resize(width, height)
        Canvas.resize(width, height)
        _w = width
        _h = height
        _bmp = ImageData.create("plasma_effect", _w, _h)
        _plasma = createPlasma() // stores the hues for the colors
    }

    init() {
        _frame = 0
        _hueShift = 0
        Canvas.cls(Color.white)
    }

    createPlasma() {
        var buffer = List.filled(_w, null)
        for (x in 0..._w) {
            buffer[x] = List.filled(_h, 0)
            for (y in 0..._h) {
                var value = Math.sin(x / 16)
                value = value + Math.sin(y / 8)
                value = value + Math.sin((x + y) / 16)
                value = value + Math.sin((x * x + y * y).sqrt / 8)
                value = value + 4  // shift range from -4 .. 4 to 0 .. 8
                value = value / 8  // bring range down to 0 .. 1
                if (value < 0 || value > 1) Fiber.abort("Hue value out of bounds")
                buffer[x][y] = value
                pset(x, y, Color.hsv(value * 360, 1, 1))
            }
        }
        return buffer
    }

    pset(x, y, col) { _bmp.pset(x, y, col) }

    pget(x, y) { _bmp.pget(x, y) }

    update() {
        _frame = _frame + 1
        if (_frame % 3 == 0) {  // update every 3 frames or 1/20th second
            _hueShift = (_hueShift + 0.02) % 1
        }
    }

    draw(alpha) {
        for (x in 0..._w) {
            for (y in 0..._h) {
                var hue = (_hueShift + _plasma[x][y]) % 1
                var col = Color.hsv(hue * 360, 1, 1)
                pset(x, y, col)
            }
        }
        _bmp.draw(0, 0)
    }
}

var Game = PlasmaEffect.new(640, 640)


fcn polyLongDivision(a,b){  // (a0 + a1x + a2x^2 + a3x^3 ...)
   _assert_(degree(b)>=0,"degree(%s) < 0".fmt(b));
   q:=List.createLong(a.len(),0.0);
   while((ad:=degree(a)) >= (bd:=degree(b))){
      z,d,m := ad-bd, List.createLong(z,0.0).extend(b), a[ad]/b[bd];;
      q[z]=m;
      d,a = d.apply('*(m)), a.zipWith('-,d);
   }
   return(q,a);		// may have trailing zero elements
}
fcn degree(v){  // -1,0,..len(v)-1, -1 if v==0
   v.len() - v.copy().reverse().filter1n('!=(0)) - 1;
}
fcn polyString(terms){ // (a0,a1,a2...)-->"a0 + a1x + a2x^2 ..."
   str:=[0..].zipWith('wrap(n,a){ if(a) "+ %sx^%s ".fmt(a,n) else "" },terms)
   .pump(String)
   .replace("x^0 "," ").replace(" 1x"," x").replace("x^1 ","x ")
   .replace("+ -", "- ");
   if(not str)     return(" ");  // all zeros
   if(str[0]=="+") str[1,*];     // leave leading space
   else            String("-",str[2,*]);
}


F lcm(m, n)
   R m I/ gcd(m, n) * n

F get_primes(=n)
   [Int] r
   L(d) 2 .. n
      V q = n I/ d
      V m = n % d
      L m == 0
         r.append(d)
         n = q
         q = n I/ d
         m = n % d
   R r

F is_prime(a)
   I a == 2
      R 1B
   I a < 2 | a % 2 == 0
      R 0B
   L(i) (3 .. Int(sqrt(a))).step(2)
      I a % i == 0
         R 0B
   R 1B

F pisano_period(m)
   V p = 0
   V c = 1
   L(i) 0 .< m * m
      p = (p + c) % m
      swap(&p, &c)
      I p == 0 & c == 1
         R i + 1
   R 1

F pisano_prime(p, k)
   R I is_prime(p) {p ^ (k - 1) * pisano_period(p)} E 0

F pisano(m)
   V primes = get_primes(m)
   DefaultDict[Int, Int] prime_powers
   L(p) primes
      prime_powers[p]++
   [Int] pps
   L(k, v) prime_powers
      pps.append(pisano_prime(k, v))
   I pps.empty
      R 1
   V result = pps[0]
   L(i) 1 .< pps.len
      result = lcm(result, pps[i])
   R result

L(p) 2..14
   V pp = pisano_prime(p, 2)
   I pp > 0
      print(‘pisano_prime(#2, 2) = #.’.format(p, pp))

print()
L(p) 2..179
   V pp = pisano_prime(p, 1)
   I pp > 0
      print(‘pisano_prime(#3, 1) = #.’.format(p, pp))

print()
print(‘pisano(n) for integers 'n' from 1 to 180 are:’)
L(n) 1..180
   print(‘#3’.format(pisano(n)), end' I n % 15 == 0 {"\n"} E ‘ ’)


USING: formatting fry grouping io kernel math math.functions
math.primes math.primes.factors math.ranges sequences ;

: pisano-period ( m -- n )
    [ 0 1 ] dip [ sq <iota> ] [ ] bi
    '[ drop tuck + _ mod 2dup [ zero? ] [ 1 = ] bi* and ]
    find 3nip [ 1 + ] [ 1 ] if* ;

: pisano-prime ( p k -- n )
    over prime? [ "p must be prime." throw ] unless
    ^ pisano-period ;

: pisano ( m -- n )
    group-factors [ first2 pisano-prime ] [ lcm ] map-reduce ;

: show-pisano ( upto m -- )
    [ primes-upto ] dip
    [ 2dup pisano-prime "%d %d pisano-prime = %d\n" printf ]
    curry each nl ;

15  2 show-pisano
180 1 show-pisano

"n pisano for integers 'n' from 2 to 180:" print
2 180 [a,b] [ pisano ] map 15 group
[ [ "%3d " printf ] each nl ] each


package main

import "fmt"

func gcd(a, b uint) uint {
    if b == 0 {
        return a
    }
    return gcd(b, a%b)
}

func lcm(a, b uint) uint {
    return a / gcd(a, b) * b
}

func ipow(x, p uint) uint {
    prod := uint(1)
    for p > 0 {
        if p&1 != 0 {
            prod *= x
        }
        p >>= 1
        x *= x
    }
    return prod
}

// Gets the prime decomposition of n.
func getPrimes(n uint) []uint {
    var primes []uint
    for i := uint(2); i <= n; i++ {
        div := n / i
        mod := n % i
        for mod == 0 {
            primes = append(primes, i)
            n = div
            div = n / i
            mod = n % i
        }
    }
    return primes
}

// OK for 'small' numbers.
func isPrime(n uint) bool {
    switch {
    case n < 2:
        return false
    case n%2 == 0:
        return n == 2
    case n%3 == 0:
        return n == 3
    default:
        d := uint(5)
        for d*d <= n {
            if n%d == 0 {
                return false
            }
            d += 2
            if n%d == 0 {
                return false
            }
            d += 4
        }
        return true
    }
}

// Calculates the Pisano period of 'm' from first principles.
func pisanoPeriod(m uint) uint {
    var p, c uint = 0, 1
    for i := uint(0); i < m*m; i++ {
        p, c = c, (p+c)%m
        if p == 0 && c == 1 {
            return i + 1
        }
    }
    return 1
}

// Calculates the Pisano period of p^k where 'p' is prime and 'k' is a positive integer.
func pisanoPrime(p uint, k uint) uint {
    if !isPrime(p) || k == 0 {
        return 0 // can't do this one
    }
    return ipow(p, k-1) * pisanoPeriod(p)
}

// Calculates the Pisano period of 'm' using pisanoPrime.
func pisano(m uint) uint {
    primes := getPrimes(m)
    primePowers := make(map[uint]uint)
    for _, p := range primes {
        primePowers[p]++
    }
    var pps []uint
    for k, v := range primePowers {
        pps = append(pps, pisanoPrime(k, v))
    }
    if len(pps) == 0 {
        return 1
    }
    if len(pps) == 1 {
        return pps[0]
    }
    f := pps[0]
    for i := 1; i < len(pps); i++ {
        f = lcm(f, pps[i])
    }
    return f
}

func main() {
    for p := uint(2); p < 15; p++ {
        pp := pisanoPrime(p, 2)
        if pp > 0 {
            fmt.Printf("pisanoPrime(%2d: 2) = %d\n", p, pp)
        }
    }
    fmt.Println()
    for p := uint(2); p < 180; p++ {
        pp := pisanoPrime(p, 1)
        if pp > 0 {
            fmt.Printf("pisanoPrime(%3d: 1) = %d\n", p, pp)
        }
    }
    fmt.Println()
    fmt.Println("pisano(n) for integers 'n' from 1 to 180 are:")
    for n := uint(1); n <= 180; n++ {
        fmt.Printf("%3d ", pisano(n))
        if n != 1 && n%15 == 0 {
            fmt.Println()
        }
    }
    fmt.Println()
}


import qualified Data.Text as T

main = do
  putStrLn "PisanoPrime(p,2) for prime p lower than 15"
  putStrLn . see 15 . map (`pisanoPrime` 2) . filter isPrime $ [1 .. 15]
  putStrLn "PisanoPrime(p,1) for prime p lower than 180"
  putStrLn . see 15 . map (`pisanoPrime` 1) . filter isPrime $ [1 .. 180]
  let ns = [1 .. 180] :: [Int]
  let xs = map pisanoPeriod ns
  let ys = map pisano ns
  let zs = map pisanoConjecture ns
  putStrLn "Pisano(m) for m from 1 to 180"
  putStrLn . see 15 $ map pisano [1 .. 180]
  putStrLn $
    "map pisanoPeriod [1..180] == map pisano [1..180] = " ++ show (xs == ys)
  putStrLn $
    "map pisanoPeriod [1..180] == map pisanoConjecture [1..180] = " ++
    show (ys == zs)

bagOf :: Int -> [a] -> [[a]]
bagOf _ [] = []
bagOf n xs =
  let (us, vs) = splitAt n xs
  in us : bagOf n vs

see
  :: Show a
  => Int -> [a] -> String
see n =
  unlines .
  map unwords . bagOf n . map (T.unpack . T.justifyRight 3 ' ' . T.pack . show)

fibMod
  :: Integral a
  => a -> [a]
fibMod 1 = repeat 0
fibMod n = fib
  where
    fib = 0 : 1 : zipWith (\x y -> rem (x + y) n) fib (tail fib)

pisanoPeriod
  :: Integral a
  => a -> a
pisanoPeriod m
  | m <= 0 = 0
pisanoPeriod 1 = 1
pisanoPeriod m = go 1 (tail $ fibMod m)
  where
    go t (0:1:_) = t
    go t (_:xs) = go (succ t) xs

powMod
  :: Integral a
  => a -> a -> a -> a
powMod _ _ k
  | k < 0 = error "negative power"
powMod m _ _
  | 1 == abs m = 0
powMod m p k
  | 1 == abs p = mod v m
  where
    v
      | 1 == p || even k = 1
      | otherwise = p
powMod m p k = go p k
  where
    to x y = mod (x * y) m
    go _ 0 = 1
    go u 1 = mod u m
    go u i
      | even i = to w w
      | otherwise = to u (to w w)
      where
        w = go u (quot i 2)

-- Fermat primality test
probablyPrime
  :: Integral a
  => a -> Bool
probablyPrime p
  | p < 2 || even p = 2 == p
  | otherwise = 1 == powMod p 2 (p - 1)

primes
  :: Integral a
  => [a]
primes =
  2 :
  3 :
  5 :
  7 :
  [ p
  | p <- [11,13 ..]
  , isPrime p ]

limitDivisor
  :: Integral a
  => a -> a
limitDivisor = floor . (+ 0.05) . sqrt . fromIntegral

isPrime
  :: Integral a
  => a -> Bool
isPrime p
  | not $ probablyPrime p = False
isPrime p = go primes
  where
    stop = limitDivisor p
    go (n:_)
      | stop < n = True
    go (n:ns) = (0 /= rem p n) && go ns
    go [] = True

factor
  :: Integral a
  => a -> [(a, a)]
factor n
  | n <= 1 = []
factor n = go n primes
  where
    fun x d c
      | 0 /= rem x d = (x, c)
      | otherwise = fun (quot x d) d (succ c)
    go 1 _ = []
    go _ [] = []
    go x (d:ds)
      | 0 /= rem x d = go x $ dropWhile ((0 /=) . rem x) ds
    go x (d:ds) =
      let (u, c) = fun (quot x d) d 1
      in (d, c) : go u ds

pisanoPrime
  :: Integral a
  => a -> a -> a
pisanoPrime p k
  | p <= 0 || k < 0 = 0
pisanoPrime p k = pisanoPeriod $ p ^ k

pisano
  :: Integral a
  => a -> a
pisano m
  | m < 1 = 0
pisano 1 = 1
pisano m = foldl1 lcm . map (uncurry pisanoPrime) $ factor m

pisanoConjecture
  :: Integral a
  => a -> a
pisanoConjecture m
  | m < 1 = 0
pisanoConjecture 1 = 1
pisanoConjecture m = foldl1 lcm . map (uncurry pisanoPrime') $ factor m
  where
    pisanoPrime' p k = (p ^ (k - 1)) * pisanoPeriod p


import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class PisanoPeriod {

    public static void main(String[] args) {
        System.out.printf("Print pisano(p^2) for every prime p lower than 15%n");
        for ( long i = 2 ; i < 15 ; i++ ) {
            if ( isPrime(i) ) {
                long n = i*i;
                System.out.printf("pisano(%d) = %d%n", n, pisano(n));
            }
        }

        System.out.printf("%nPrint pisano(p) for every prime p lower than 180%n");
        for ( long n = 2 ; n < 180 ; n++ ) {
            if ( isPrime(n) ) {
                System.out.printf("pisano(%d) = %d%n", n, pisano(n));
            }
        }

        System.out.printf("%nPrint pisano(n) for every integer from 1 to 180%n");
        for ( long n = 1 ; n <= 180 ; n++ ) {
            System.out.printf("%3d  ", pisano(n));
            if ( n % 10 == 0 ) {
                System.out.printf("%n");
            }
        }

    }

    private static final boolean isPrime(long test) {
        if ( test == 2 ) {
            return true;
        }
        if ( test % 2 == 0 ) {
            return false;
        }
        for ( long i = 3 ; i <= Math.sqrt(test) ; i += 2 ) {
            if ( test % i == 0 ) {
                return false;
            }
        }
        return true;
    }

    private static Map<Long,Long> PERIOD_MEMO = new HashMap<>();
    static {
        PERIOD_MEMO.put(2L, 3L);
        PERIOD_MEMO.put(3L, 8L);
        PERIOD_MEMO.put(5L, 20L);
    }

    //  See http://webspace.ship.edu/msrenault/fibonacci/fib.htm
    private static long pisano(long n) {
        if ( PERIOD_MEMO.containsKey(n) ) {
            return PERIOD_MEMO.get(n);
        }
        if ( n == 1 ) {
            return 1;
        }
        Map<Long,Long> factors = getFactors(n);

        //  Special cases
        //  pisano(2^k) = 3*n/2
        if ( factors.size() == 1 & factors.get(2L) != null && factors.get(2L) > 0 ) {
            long result = 3 * n / 2;
            PERIOD_MEMO.put(n, result);
            return result;
        }
        //  pisano(5^k) = 4*n
        if ( factors.size() == 1 & factors.get(5L) != null && factors.get(5L) > 0 ) {
            long result = 4*n;
            PERIOD_MEMO.put(n, result);
            return result;
        }
        //  pisano(2*5^k) = 6*n
        if ( factors.size() == 2 & factors.get(2L) != null && factors.get(2L) == 1 && factors.get(5L) != null && factors.get(5L) > 0 ) {
            long result = 6*n;
            PERIOD_MEMO.put(n, result);
            return result;
        }

        List<Long> primes = new ArrayList<>(factors.keySet());
        long prime = primes.get(0);
        if ( factors.size() == 1 && factors.get(prime) == 1 ) {
            List<Long> divisors = new ArrayList<>();
            if ( n % 10 == 1 || n % 10 == 9 ) {
                for ( long divisor : getDivisors(prime-1) ) {
                    if ( divisor % 2 == 0 ) {
                        divisors.add(divisor);
                    }
                }
            }
            else {
                List<Long> pPlus1Divisors = getDivisors(prime+1);
                for ( long divisor : getDivisors(2*prime+2) ) {
                    if ( !  pPlus1Divisors.contains(divisor) ) {
                        divisors.add(divisor);
                    }
                }
            }
            Collections.sort(divisors);
            for ( long divisor : divisors ) {
                if ( fibModIdentity(divisor, prime) ) {
                    PERIOD_MEMO.put(prime, divisor);
                    return divisor;
                }
            }
            throw new RuntimeException("ERROR 144: Divisor not found.");
        }
        long period = (long) Math.pow(prime, factors.get(prime)-1) * pisano(prime);
        for ( int i = 1 ; i < primes.size() ; i++ ) {
            prime = primes.get(i);
            period = lcm(period, (long) Math.pow(prime, factors.get(prime)-1) * pisano(prime));
        }
        PERIOD_MEMO.put(n, period);
        return period;
    }

    //  Use Matrix multiplication to compute Fibonacci numbers.
    private static boolean fibModIdentity(long n, long mod) {
        long aRes = 0;
        long bRes = 1;
        long cRes = 1;
        long aBase = 0;
        long bBase = 1;
        long cBase = 1;
        while ( n > 0 ) {
            if ( n % 2 == 1 ) {
                long temp1 = 0, temp2 = 0, temp3 = 0;
                if ( aRes > SQRT || aBase > SQRT || bRes > SQRT || bBase > SQRT || cBase > SQRT || cRes > SQRT ) {
                    temp1 = (multiply(aRes, aBase, mod) + multiply(bRes, bBase, mod)) % mod;
                    temp2 = (multiply(aBase, bRes, mod) + multiply(bBase, cRes, mod)) % mod;
                    temp3 = (multiply(bBase, bRes, mod) + multiply(cBase, cRes, mod)) % mod;
                }
                else {
                    temp1 = ((aRes*aBase % mod) + (bRes*bBase % mod)) % mod;
                    temp2 = ((aBase*bRes % mod) + (bBase*cRes % mod)) % mod;
                    temp3 = ((bBase*bRes % mod) + (cBase*cRes % mod)) % mod;
                }
                aRes = temp1;
                bRes = temp2;
                cRes = temp3;
            }
            n >>= 1L;
            long temp1 = 0, temp2 = 0, temp3 = 0;
            if ( aBase > SQRT || bBase > SQRT || cBase > SQRT ) {
                temp1 = (multiply(aBase, aBase, mod) + multiply(bBase, bBase, mod)) % mod;
                temp2 = (multiply(aBase, bBase, mod) + multiply(bBase, cBase, mod)) % mod;
                temp3 = (multiply(bBase, bBase, mod) + multiply(cBase, cBase, mod)) % mod;
            }
            else {
                temp1 = ((aBase*aBase % mod) + (bBase*bBase % mod)) % mod;
                temp2 = ((aBase*bBase % mod) + (bBase*cBase % mod)) % mod;
                temp3 = ((bBase*bBase % mod) + (cBase*cBase % mod)) % mod;
            }
            aBase = temp1;
            bBase = temp2;
            cBase = temp3;
        }
        return aRes % mod == 0 && bRes % mod == 1 && cRes % mod == 1;
    }

    private static final long SQRT = (long) Math.sqrt(Long.MAX_VALUE);

    //  Result is a*b % mod, without overflow.
    public static final long multiply(long a, long b, long modulus) {
        //System.out.println("    multiply : a = " + a + ", b = " + b + ", mod = " + modulus);
        long x = 0;
        long y = a % modulus;
        long t;
        while ( b > 0 ) {
            if ( b % 2 == 1 ) {
                t = x + y;
                x = (t > modulus ? t-modulus : t);
            }
            t = y << 1;
            y = (t > modulus ? t-modulus : t);
            b >>= 1;
        }
        //System.out.println("    multiply : answer = " + (x % modulus));
        return x % modulus;
    }

    private static final List<Long> getDivisors(long number) {
        List<Long> divisors = new ArrayList<>();
        long sqrt = (long) Math.sqrt(number);
        for ( long i = 1 ; i <= sqrt ; i++ ) {
            if ( number % i == 0 ) {
                divisors.add(i);
                long div = number / i;
                if ( div != i ) {
                    divisors.add(div);
                }
            }
        }
        return divisors;
    }

    public static long lcm(long a, long b) {
        return a*b/gcd(a,b);
    }

    public static long gcd(long a, long b) {
        if ( b == 0 ) {
            return a;
        }
        return gcd(b, a%b);
    }

    private static final Map<Long,Map<Long,Long>> allFactors = new TreeMap<Long,Map<Long,Long>>();
    static {
        Map<Long,Long> factors = new TreeMap<Long,Long>();
        factors.put(2L, 1L);
        allFactors.put(2L, factors);
    }

    public static Long MAX_ALL_FACTORS = 100000L;

    public static final Map<Long,Long> getFactors(Long number) {
        if ( allFactors.containsKey(number) ) {
            return allFactors.get(number);
        }
        Map<Long,Long> factors = new TreeMap<Long,Long>();
        if ( number % 2 == 0 ) {
            Map<Long,Long> factorsdDivTwo = getFactors(number/2);
            factors.putAll(factorsdDivTwo);
            factors.merge(2L, 1L, (v1, v2) -> v1 + v2);
            if ( number < MAX_ALL_FACTORS ) {
                allFactors.put(number, factors);
            }
            return factors;
        }
        boolean prime = true;
        long sqrt = (long) Math.sqrt(number);
        for ( long i = 3 ; i <= sqrt ; i += 2 ) {
            if ( number % i == 0 ) {
                prime = false;
                factors.putAll(getFactors(number/i));
                factors.merge(i, 1L, (v1, v2) -> v1 + v2);
                if ( number < MAX_ALL_FACTORS ) {
                    allFactors.put(number, factors);
                }
                return factors;
            }
        }
        if ( prime ) {
            factors.put(number, 1L);
            if ( number < MAX_ALL_FACTORS ) {
                allFactors.put(number, factors);
            }
        }
        return factors;
    }

}


using Primes

const pisanos = Dict{Int, Int}()
function pisano(p)
    p < 2 && return 1
    (i = get(pisanos, p, 0)) > 0 && return i
    lastn, n = 0, 1
    for i in 1:p^2
        lastn, n = n, (lastn + n) % p
        if lastn == 0 && n == 1
            pisanos[p] = i
            return i
        end
    end
    return 1
end

pisanoprime(p, k) = (@assert(isprime(p)); p^(k-1) * pisano(p))
pisanotask(n) = mapreduce(p -> pisanoprime(p[1], p[2]), lcm, collect(factor(n)), init=1)

for i in 1:15
    if isprime(i)
        println("pisanoPrime($i, 2) = ", pisanoprime(i, 2))
    end
end

for i in 1:180
    if isprime(i)
        println("pisanoPrime($i, 1) = ", pisanoprime(i, 1))
    end
end

println("\nPisano(n) for n from 2 to 180:\n", [pisano(i) for i in 2:180])
println("\nPisano(n) using pisanoPrime for n from 2 to 180:\n", [pisanotask(i) for i in 2:180])


import math, strformat, tables

func primes(n: Positive): seq[int] =
  ## Return the list of prime divisors of "n".
  var n = n.int
  for d in 2..n:
    var q = n div d
    var m = n mod d
    while m == 0:
      result.add d
      n = q
      q = n div d
      m = n mod d

func isPrime(n: Positive): bool =
  ## Return true if "n" is prime.
  if n < 2: return false
  if n mod 2 == 0: return n == 2
  if n mod 3 == 0: return n == 3
  var d = 5
  while d <= sqrt(n.toFloat).int:
    if n mod d == 0: return false
    inc d, 2
    if n mod d == 0: return false
    inc d, 4
  result = true

func pisanoPeriod(m: Positive): int =
  ## Calculate the Pisano period of 'm' from first principles.
  var p = 0
  var c = 1
  for i in 0..<m*m:
    p = (p + c) mod m
    swap p, c
    if p == 0 and c == 1: return i + 1
  result = 1

func pisanoPrime(p, k: Positive): int =
  ## Calculate the Pisano period of p^k where 'p' is prime and 'k' is a positive integer.
  if p.isPrime: p^(k-1) * p.pisanoPeriod() else: 0

func pisano(m: Positive): int =
  ## Calculate the Pisano period of 'm' using pisanoPrime.
  let primes = m.primes
  var primePowers = primes.toCountTable
  var pps: seq[int]
  for k, v in primePowers.pairs:
    pps.add pisanoPrime(k, v)
  if pps.len == 0: return 1
  result = pps[0]
  for i in 1..pps.high:
    result = lcm(result, pps[i])

when isMainModule:

  for p in 2..14:
    let pp = pisanoPrime(p, 2)
    if pp > 0:
      echo &"pisanoPrime({p:2}, 2) = {pp}"

  echo()
  for p in 2..179:
    let pp = pisanoPrime(p, 1)
    if pp > 0:
      echo &"pisanoPrime({p:3}, 1) = {pp}"

  echo()
  echo "pisano(n) for integers 'n' from 1 to 180 are:"
  for n in 1..180:
    stdout.write &"{pisano(n):3}", if n mod 15 == 0: '\n' else: ' '


use strict;
use warnings;
use feature 'say';
use ntheory qw(primes factor_exp lcm);

sub pisano_period_pp {
    my($a, $b, $n, $k) = (0, 1, $_[0]**$_[1]);
    while (++$k) {
        ($a, $b) = ($b, ($a+$b) % $n);
        return $k if $a == 0 and $b == 1;
    }
}

sub pisano_period {
    (lcm map { pisano_period_pp($$_[0],$$_[1]) } factor_exp($_[0])) or 1;
}

sub display { (sprintf "@{['%5d' x @_]}", @_) =~ s/(.{75})/$1\n/gr }

say "Pisano periods for squares of primes p <= 50:\n", display( map { pisano_period_pp($_, 2) } @{primes(1,  50)} ),
  "\nPisano periods for primes p <= 180:\n",           display( map { pisano_period_pp($_, 1) } @{primes(1, 180)} ),
"\n\nPisano periods for integers n from 1 to 180:\n",  display( map { pisano_period   ($_   ) }          1..180   );


with javascript_semantics
function pisano_period(integer m)
-- Calculates the Pisano period of 'm' from first principles. (copied from Go)
    integer p = 0, c = 1
    for i=0 to m*m-1 do
        {p, c} = {c, mod(p+c,m)}
        if p == 0 and c == 1 then
            return i + 1
        end if
    end for
    return 1
end function

function pisanoPrime(integer p, k)
    if not is_prime(p) or k=0 then ?9/0 end if
    return power(p,k-1)*pisano_period(p)
end function

function pisano(integer m)
-- Calculates the Pisano period of 'm' using pisanoPrime.
    if m=1 then return 1 end if
    sequence s = prime_factors(m, true, get_maxprime(m))&0,
             pps = {}
    integer k = 1, p = s[1]
    for i=2 to length(s) do
        integer n = s[i]
        if n!=p then
            pps = append(pps,pisanoPrime(p,k))
            {k,p} = {1,n}
        else
            k += 1
        end if
    end for
    return lcm(pps)
end function

procedure p(integer k, lim)
-- test harness
    printf(1,"pisanoPrimes")
    integer pdx = 1, c = 0
    while true do
        integer p = get_prime(pdx)
        if p>=lim then exit end if
        c += 1
        if c=7 then puts(1,"\n            ") c = 1
        elsif pdx>1 then puts(1,", ") end if
        printf(1,"(%3d,%d)=%3d",{p,k,pisanoPrime(p,k)})
        pdx += 1
    end while
    printf(1,"\n")
end procedure
p(2,15)
p(1,180)

sequence p180 = {}
for n=1 to 180 do p180 &= pisano(n) end for
printf(1,"pisano(1..180):\n")
pp(p180,{pp_IntFmt,"%4d",pp_IntCh,false})


from sympy import isprime, lcm, factorint, primerange
from functools import reduce

def pisano1(m):
    "Simple definition"
    if m < 2:
        return 1
    lastn, n = 0, 1
    for i in range(m ** 2):
        lastn, n = n, (lastn + n) % m
        if lastn == 0 and n == 1:
            return i + 1
    return 1

def pisanoprime(p, k):
    "Use conjecture π(p ** k) == p ** (k − 1) * π(p) for prime p and int k > 1"
    assert isprime(p) and k > 0
    return p ** (k - 1) * pisano1(p)

def pisano_mult(m, n):
    "pisano(m*n) where m and n assumed coprime integers"
    return lcm(pisano1(m), pisano1(n))

def pisano2(m):
    "Uses prime factorization of m"
    return reduce(lcm, (pisanoprime(prime, mult)
                        for prime, mult in factorint(m).items()), 1)

if __name__ == '__main__':
    for n in range(1, 181):
        assert pisano1(n) == pisano2(n), "Wall-Sun-Sun prime exists??!!"
    print("\nPisano period (p, 2) for primes less than 50\n ",
          [pisanoprime(prime, 2) for prime in primerange(1, 50)])
    print("\nPisano period (p, 1) for primes less than 180\n ",
          [pisanoprime(prime, 1) for prime in primerange(1, 180)])
    print("\nPisano period (p) for integers 1 to 180")
    for i in range(1, 181):
        print(" %3d" % pisano2(i), end="" if i % 10 else "\n")


use Prime::Factor;

constant @fib := 1,1,*+*…*;

my %cache;

multi pisano-period (Int $p where *.is-prime, Int $k where * > 0 = 1) {
    return %cache{"$p|$k"} if %cache{"$p|$k"};
    my $fibmod = @fib.map: * % $p**$k;
    %cache{"$p|$k"} = (1..*).first: { !$fibmod[$_-1] and ($fibmod[$_] == 1) }
}

multi pisano-period (Int $p where * > 0 ) {
    [lcm] prime-factors($p).Bag.map: { samewith .key, .value }
}

put "Pisano period (p, 2) for primes less than 50";
put (map { pisano-period($_, 2) }, ^50 .grep: *.is-prime )».fmt('%4d');

put "\nPisano period (p, 1) for primes less than 180";
.put for (map { pisano-period($_, 1) }, ^180 .grep: *.is-prime )».fmt('%4d').batch(15);

put "\nPisano period (p, 1) for integers 1 to 180";
.put for (1..180).map( { pisano-period($_) } )».fmt('%4d').batch(15);


/*REXX pgm calculates pisano period for a range of N, and pisanoPrime(N,m)  [for primes]*/
numeric digits 500                               /*ensure enough decimal digits for Fib.*/
parse arg lim.1 lim.2 lim.3 .                    /*obtain optional arguments from the CL*/
if lim.1=='' | lim.1==","  then lim.1=  15 - 1   /*Not specified?  Then use the default.*/
if lim.2=='' | lim.2==","  then lim.2= 180 - 1   /* "      "         "   "   "     "    */
if lim.3=='' | lim.3==","  then lim.3= 180       /* "      "         "   "   "     "    */
call Fib                                         /*    "      "   Fibonacci numbers.    */
         do i=1  for max(lim.1, lim.2, lim.3);  call pisano(i)    /*find pisano periods.*/
         end   /*i*/;    w= length(i)

    do j=1  for 2;  #= word(2 1, j)
       do p=1  for lim.j;  if \isPrime(p)  then iterate  /*Not prime?  Skip this number.*/
       say '   pisanoPrime('right(p, w)", "#') = 'right( pisanoPrime(p, #), 5)
       end   /*p*/;        say
    end      /*j*/

say center(' pisano numbers for 1──►'lim.3" ",  20*4 - 1,  "═")       /*display a title.*/
$=
    do j=1  for lim.3;     $= $  right(@.j, w)   /*append pisano number to the  $  list.*/
    if j//20==0  then do;  say substr($, 2);  $=;  end    /*display 20 numbers to a line*/
    end   /*j*/
                           say substr($, 2)      /*possible display any residuals──►term*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
fib: procedure expose fib.; parse arg x; fib.=.;     if x==''      then x= 1000
     fib.0= 0;  fib.1= 1;                            if fib.x\==.  then return fib.x
                  do k=2  for x-1;    a= k-1;        b= k-2;       fib.k=  fib.a + fib.b
                  end   /*k*/;    return fib.k
/*──────────────────────────────────────────────────────────────────────────────────────*/
isPrime: parse arg n; if n<11  then return pos(n, '2 3 5 7')>0;  if n//2==0  then return 0
            do k=3  by 2  while k*k<=n; if n//k==0  then return 0; end /*k*/;     return 1
/*──────────────────────────────────────────────────────────────────────────────────────*/
pisano: procedure expose @. fib.; parse arg m;   if m==1  then do;  @.m=1;  return 1;  end
                do k=1;  _= k+1;                 if fib.k//m==0 & fib._//m==1  then leave
                end   /*k*/;      @.m= k;                 return k
/*──────────────────────────────────────────────────────────────────────────────────────*/
pisanoPrime: procedure expose @. fib.; parse arg m,n;     return m**(n-1)  *  pisano(m)


func pisano_period_pp(p,k) is cached {

    assert(k.is_pos,   "k = #{k} must be positive")
    assert(p.is_prime, "p = #{p} must be prime")

    var (a, b, n) = (0, 1, p**k)

    1..Inf -> first_by {
        (a, b) = (b, (a+b) % n)
        (a == 0) && (b == 1)
    }
}

func pisano_period(n) {
    n.factor_map {|p,k| pisano_period_pp(p, k) }.lcm
}

say "Pisano periods for squares of primes p <= 15:"
say  15.primes.map {|p| pisano_period_pp(p, 2) }

say "\nPisano periods for primes p <= 180:"
say 180.primes.map {|p| pisano_period_pp(p, 1) }

say "\nPisano periods for integers n from 1 to 180:"
say pisano_period.map(1..180)