'use strict';
/*
 * Imported from http://rosettacode.org/wiki/Maze_generation#JavaScript
 * Added asynchronous behaviour to the maze generation.
 *
 * Port by sigmasoldier
 */

/**
 * Generates the maze asynchronously.
 * @param {Number} x Width of the maze.
 * @param {Number} y Height of the maze.
 * @returns {Promise} finished when resolved.
 */
function maze(x,y) {
	return new Promise((resolve, reject) => {
		let n=x*y-1;
		if (n<0) {
			reject(new Error(`illegal maze dimensions (${x} x ${y} < 1)`));
		} else {
			let horiz =[]; for (let j= 0; j<x+1; j++) horiz[j]= [];
			let verti =[]; for (let j= 0; j<x+1; j++) verti[j]= [];
			let here = [Math.floor(Math.random()*x), Math.floor(Math.random()*y)];
			let path = [here];
			let unvisited = [];
			for (let j = 0; j<x+2; j++) {
				unvisited[j] = [];
				for (let k= 0; k<y+1; k++)
					unvisited[j].push(j>0 && j<x+1 && k>0 && (j != here[0]+1 || k != here[1]+1));
			}
			while (0<n) {
				let potential = [[here[0]+1, here[1]], [here[0],here[1]+1],
						[here[0]-1, here[1]], [here[0],here[1]-1]];
				let neighbors = [];
				for (let j = 0; j < 4; j++)
					if (unvisited[potential[j][0]+1][potential[j][1]+1])
						neighbors.push(potential[j]);
				if (neighbors.length) {
					n = n-1;
					let next= neighbors[Math.floor(Math.random()*neighbors.length)];
					unvisited[next[0]+1][next[1]+1]= false;
					if (next[0] == here[0])
						horiz[next[0]][(next[1]+here[1]-1)/2]= true;
					else
						verti[(next[0]+here[0]-1)/2][next[1]]= true;
					path.push(here = next);
				} else
					here = path.pop();
			}
			resolve({x: x, y: y, horiz: horiz, verti: verti});
		}
	});
}

/**
 * A mere way of generating text.
 * The text (Since it can be large) is generated in a non-blocking way.
 * @param {Object} m Maze object.
 * @param {Stream} writeTo Optinally, include here a function to write to.
 * @returns {Promise} finished when the text is generated.
 */
function display(m, writeTo) {
	return new Promise((resolve, reject) => {
		let text = [];
		for (let j= 0; j<m.x*2+1; j++) {
			let line = [];
			if (0 == j%2)
				for (let k=0; k<m.y*4+1; k++)
					if (0 == k%4)
						line[k] = '+';
					else
						if (j>0 && m.verti[j/2-1][Math.floor(k/4)])
							line[k] = ' ';
						else
							line[k] = '-';
			else
				for (let k=0; k<m.y*4+1; k++)
					if (0 == k%4)
						if (k>0 && m.horiz[(j-1)/2][k/4-1])
							line[k] = ' ';
						else
							line[k] = '|';
					else
						line[k] = ' ';
			if (0 == j) line[1] = line[2] = line[3] = ' ';
			if (m.x*2-1 == j) line[4*m.y]= ' ';
			text.push(line.join('')+'\r\n');
		}
		const OUTPUT = text.join('');
		if (typeof writeTo === 'function')
			writeTo(OUTPUT);
		resolve(OUTPUT);
	});
}

module.exports = {
  maze: maze,
  display: display
}


Map:=proc(a1,a2,b1,b2,s);
	return (b1+((s-a1)*(b2-b1)/(a2-a1)));
end proc;

for i from 0 to 10 do
	printf("%a  maps to ",i);
	printf("%a\n",Map(0,10,-1,0,i));
end do;


maprange(a, b, c, d) := buildq([e: ratsimp(('x - a)*(d - c)/(b - a) + c)],
   lambda([x], e))$

f: maprange(0, 10, -1, 0);


using System;
using System.Console;

module Maprange
{
    Maprange(a : double * double, b : double * double, s : double) : double
    {
        def (a1, a2) = a; def (b1, b2) = b;

        b1 + (((s - a1) * (b2 - b1))/(a2 - a1))
    }

    Main() : void
    {
        foreach (i in [0 .. 10])
            WriteLine("{0, 2:f0} maps to {1:f1}", i, Maprange((0.0, 10.0), (-1.0, 0.0), i));
    }
}


let seen = Hashtbl.create 7
let mark t = Hashtbl.add seen t true
let marked t = Hashtbl.mem seen t

let walls = Hashtbl.create 7
let ord a b = if a <= b then (a,b) else (b,a)
let join a b = Hashtbl.add walls (ord a b) true
let joined a b = Hashtbl.mem walls (ord a b)

let () =
  let nx = int_of_string Sys.argv.(1) in
  let ny = int_of_string Sys.argv.(2) in

  let shuffle lst =
     let nl = List.map (fun c -> (Random.bits (), c)) lst in
     List.map snd (List.sort compare nl) in

  let get_neighbours (x,y) =
    let lim n k = (0 <= k) && (k < n) in
    let bounds (x,y) = lim nx x && lim ny y in
    List.filter bounds [(x-1,y);(x+1,y);(x,y-1);(x,y+1)] in

  let rec visit cell =
    mark cell;
    let check k =
      if not (marked k) then (join cell k; visit k) in
    List.iter check (shuffle (get_neighbours cell)) in

  let print_maze () =
    begin
    for i = 1 to nx do print_string "+---";done; print_endline "+";
    let line n j k l s t u =
      for i = 0 to n do print_string (if joined (i,j) (i+k,j+l) then s else t) done;
      print_endline u in
    for j = 0 to ny-2 do
      print_string "|   ";
      line (nx-2) j 1 0 "    " "|   " "|";
      line (nx-1) j 0 1 "+   " "+---" "+";
    done;
    print_string "|   ";
    line (nx-2) (ny-1) 1 0 "    " "|   " "|";
    for i = 1 to nx do print_string "+---";done; print_endline "+";
   end in

  Random.self_init();
  visit (Random.int nx, Random.int ny);
  print_maze ();


#include <stdio.h>

#define MAT_ELEM(rows,cols,r,c) (r*cols+c)

//Improve performance by assuming output matrices do not overlap with
//input matrices. If this is C++, use the __restrict extension instead
#ifdef __cplusplus
    typedef double * const __restrict MAT_OUT_t;
#else
    typedef double * const restrict MAT_OUT_t;
#endif
typedef const double * const MAT_IN_t;

static inline void mat_mult(
    const int m,
    const int n,
    const int p,
    MAT_IN_t a,
    MAT_IN_t b,
    MAT_OUT_t c)
{
    for (int row=0; row<m; row++) {
        for (int col=0; col<p; col++) {
            c[MAT_ELEM(m,p,row,col)] = 0;
            for (int i=0; i<n; i++) {
                c[MAT_ELEM(m,p,row,col)] += a[MAT_ELEM(m,n,row,i)]*b[MAT_ELEM(n,p,i,col)];
            }
        }
    }
}

static inline void mat_show(
    const int m,
    const int p,
    MAT_IN_t a)
{
    for (int row=0; row<m;row++) {
        for (int col=0; col<p;col++) {
            printf("\t%7.3f", a[MAT_ELEM(m,p,row,col)]);
        }
        putchar('\n');
    }
}

int main(void)
{
    double a[4*4] = {1, 1,   1,   1,
                     2, 4,   8,  16,
                     3, 9,  27,  81,
                     4, 16, 64, 256};

    double b[4*3] = {    4.0,   -3.0,  4.0/3,
                     -13.0/3, 19.0/4, -7.0/3,
                       3.0/2,   -2.0,  7.0/6,
                      -1.0/6,  1.0/4, -1.0/6};

    double c[4*3] = {0};

    mat_mult(4,4,3,a,b,c);
    mat_show(4,3,c);
    return 0;
}


/* NetRexx */
options replace format comments java crossref savelog symbols nobinary

A    = [  0.0, 10.0 ]
B    = [ -1.0,  0.0 ]
incr = 1.0

say 'Mapping ['A[0]',' A[1]'] to ['B[0]',' B[1]'] in increments of' incr':'
loop sVal = A[0] to A[1] by incr
  say '  f('sVal.format(3, 3)') ='  mapRange(A, B, sVal).format(4, 3)
  end sVal

return

method mapRange(a = Rexx[], b = Rexx[], s_) public static
  return mapRange(a[0], a[1], b[0], b[1], s_)

method mapRange(a1, a2, b1, b2, s_) public static
  t_ = b1 + ((s_ - a1) * (b2 - b1) / (a2 - a1))
  return t_


import strformat

type FloatRange = tuple[s, e: float]

proc mapRange(a, b: FloatRange; s: float): float =
  b.s + (s - a.s) * (b.e - b.s) / (a.e - a.s)

for i in 0..10:
  let m = mapRange((0.0,10.0), (-1.0, 0.0), float(i))
  echo &"{i:>2} maps to {m:4.1f}"


bundle Default {
  class Range {
    function : MapRange(a1:Float, a2:Float, b1:Float, b2:Float, s:Float) ~ Float {
      return b1 + (s-a1)*(b2-b1)/(a2-a1);
    }

    function : Main(args : String[]) ~ Nil {
      "Mapping [0,10] to [-1,0] at intervals of 1:"->PrintLine();
      for(i := 0.0; i <= 10.0; i += 1;) {
        IO.Console->Print("f(")->Print(i->As(Int))->Print(") = ")->PrintLine(MapRange(0.0, 10.0, -1.0, 0.0, i));
      };
    }
  }
}


; maze generation
(import (otus random!))
(define WIDTH 30)
(define HEIGHT 8)

(define maze
   (map (lambda (?)
         (repeat #b01111 WIDTH)) ; 0 - unvisited, 1111 - all walls exists
      (iota HEIGHT)))
(define (at x y)
   (list-ref (list-ref maze y) x))

(define (unvisited? x y)
   (if (and (< -1 x WIDTH) (< -1 y HEIGHT))
      (zero? (band (at x y) #b10000))))
(define neighbors '((-1 . 0) (0 . -1) (+1 . 0) (0 . +1)))
(define walls     '( #b10111  #b11011  #b11101  #b11110))
(define antiwalls '( #b11101  #b11110  #b10111  #b11011))

(let loop ((x (rand! WIDTH)) (y (rand! HEIGHT)))
   (list-set! (list-ref maze y) x (bor (at x y) #b10000))
   (let try ()
      (if (or
            (unvisited? (- x 1) y) ; left
            (unvisited? x (- y 1)) ; top
            (unvisited? (+ x 1) y) ; right
            (unvisited? x (+ y 1))) ; bottom
         (let*((p (rand! 4))
               (neighbor (list-ref neighbors p)))
            (let ((nx (+ x (car neighbor)))
                  (ny (+ y (cdr neighbor))))
            (if (unvisited? nx ny)
               (let ((ncell (at nx ny)))
                  (list-set! (list-ref maze y) x (band (at x y) (list-ref walls p)))
                  (list-set! (list-ref maze ny) nx (band ncell (list-ref antiwalls p)))
                  (loop nx ny)))
            (try))))))


public class Matrix
{
	int n;
	int m;
	double[,] a;

	public Matrix(int n, int m)
	{
		if (n <= 0 || m <= 0)
			throw new ArgumentException("Matrix dimensions must be positive");
		this.n = n;
		this.m = m;
		a = new double[n, m];
	}

	//indices start from one
	public double this[int i, int j]
	{
		get { return a[i - 1, j - 1]; }
		set { a[i - 1, j - 1] = value; }
	}

	public int N { get { return n; } }
	public int M { get { return m; } }

	public static Matrix operator*(Matrix _a, Matrix b)
	{
		int n = _a.N;
		int m = b.M;
		int l = _a.M;
		if (l != b.N)
			throw new ArgumentException("Illegal matrix dimensions for multiplication. _a.M must be equal b.N");
		Matrix result = new Matrix(_a.N, b.M);
		for(int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
			{
				double sum = 0.0;
				for (int k = 0; k < l; k++)
					sum += _a.a[i, k]*b.a[k, j];
				result.a[i, j] = sum;
			}
		return result;
	}
}


let map_range (a1, a2) (b1, b2) s =
  b1 +. ((s -. a1) *. (b2 -. b1) /. (a2 -. a1))

let () =
  print_endline "Mapping [0,10] to [-1,0] at intervals of 1:";
  for i = 0 to 10 do
    Printf.printf "f(%d) = %g\n" i (map_range (0.0, 10.0) (-1.0, 0.0) (float i))
  done


: mapRange(p1, p2, s)
   s p1 first - p2 second p2 first - * p1 second p1 first - asFloat /
   p2 first + ;


#include <iostream>
#include <blitz/tinymat.h>

int main()
{
  using namespace blitz;

  TinyMatrix<double,3,3> A, B, C;

  A = 1, 2, 3,
      4, 5, 6,
      7, 8, 9;

  B = 1, 0, 0,
      0, 1, 0,
      0, 0, 1;

  C = product(A, B);

  std::cout << C << std::endl;
}


alias Matrix => Integer[][];

void printMatrix(Matrix m) {
	value strings = m.collect((row) => row.collect(Integer.string));
	value maxLength = max(expand(strings).map(String.size)) else 0;
	value padded = strings.collect((row) => row.collect((s) => s.padLeading(maxLength)));
	for (row in padded) {
		print("[``", ".join(row)``]");
	}
}

Matrix? multiplyMatrices(Matrix a, Matrix b) {

	function rectangular(Matrix m) =>
			if (exists firstRow = m.first)
			then m.every((row) => row.size == firstRow.size)
			else false;

	function rowCount(Matrix m) => m.size;
	function columnCount(Matrix m) => m[0]?.size else 0;

	if (!rectangular(a) || !rectangular(b) || columnCount(a) != rowCount(b)) {
		return null;
	}

	function getNumber(Matrix m, Integer x, Integer y) {
		assert (exists number = m[y]?.get(x));
		return number;
	}

	function getRow(Matrix m, Integer rowIndex) {
		assert (exists row = m[rowIndex]);
		return row;
	}

	function getColumn(Matrix m, Integer columnIndex) => {
		for (y in 0:rowCount(m))
		getNumber(m, columnIndex, y)
	};

	return [
		for (y in 0:rowCount(a)) [
			for (x in 0:columnCount(b))
			sum { 0, for ([a1, b1] in zipPairs(getRow(a, y), getColumn(b, x))) a1 * b1 }
		]
	];
}

shared void run() {
    value m = [[1, 2, 3], [4, 5, 6]];
    printMatrix(m);
    print("---------");
    print("multiplied by");
    value m2 = [[7, 8], [9, 10], [11, 12]];
    printMatrix(m2);
    print("---------");
    print("equals:");
    value result = multiplyMatrices(m, m2);
    if (exists result) {
        printMatrix(result);
    }
    else {
        print("something went wrong!");
    }
}


Program Map(output);

function MapRange(fromRange, toRange: array of real; value: real): real;
  begin
    MapRange := (value-fromRange[0]) * (toRange[1]-toRange[0]) / (fromRange[1]-fromRange[0]) + toRange[0];
  end;

var
  i: integer;
begin
  for i := 0 to 10 do
    writeln (i, ' maps to: ', MapRange([0.0, 10.0], [-1.0, 0.0], i):4:2);
end.


#!/usr/bin/perl -w
use strict ;

sub mapValue {
   my ( $range1 , $range2 , $number ) = @_ ;
   return ( $range2->[ 0 ] +
      (( $number - $range1->[ 0 ] ) * ( $range2->[ 1 ] - $range2->[ 0 ] ) ) / ( $range1->[ -1 ]
      - $range1->[ 0 ] ) ) ;
}
my @numbers = 0..10 ;
my @interval = ( -1 , 0 ) ;
print "The mapped value for $_ is " . mapValue( \@numbers , \@interval , $_ ) . " !\n" foreach @numbers ;


with javascript_semantics
--
-- grid is eg for w=3,h=2: {"+---+---+---+",    -- ("wall")
--                          "| ? | ? | ? |",    -- ("cell")
--                          "+---+---+---+",    -- ("wall")
--                          "| ? | ? | ? |",    -- ("cell")
--                          "+---+---+---+",    -- ("wall")
--                          ""} -- (for a trailing \n)
--
-- note those ?(x,y) are at [y*2][x*4-1], and we navigate
-- using y=2..2*h (+/-2), x=3..w*4-1 (+/-4) directly.
--
constant w = 11, h = 8

sequence wall = join(repeat("+",w+1),"---")&"\n",
         cell = join(repeat("|",w+1)," ? ")&"\n",
         grid = split(join(repeat(wall,h+1),cell),'\n')

procedure amaze(integer x, integer y)
    grid[y][x] = ' '                        -- mark cell visited
    sequence p = shuffle({{x-4,y},{x,y+2},{x+4,y},{x,y-2}})
    for i=1 to length(p) do
        integer {nx,ny} = p[i]
        if nx>1 and nx<w*4 and ny>1 and ny<=2*h and grid[ny][nx]='?' then
            integer mx = (x+nx)/2
            grid[(y+ny)/2][mx-1..mx+1] = ' ' -- knock down wall
            amaze(nx,ny)
        end if
    end for
end procedure

function heads()
    return rand(2)=1 -- 50:50 true(1)/false(0)
end function

integer {x,y} = {(rand(w)*4)-1,rand(h)*2}
amaze(x,y)
-- mark start pos
grid[y][x] = '*'
-- add a random door (heads=rhs/lhs, tails=top/btm)
if heads() then
    grid[rand(h)*2][heads()*w*4-1] = ' '
else
    x = rand(w)*4-1
    grid[heads()*h*2+1][x-1..x+1] = ' '
end if
printf(1,"%s\n",join(grid,'\n'))


proc *(a:[], b:[]) {

    if (a.eltType != b.eltType) then
        writeln("type mismatch: ", a.eltType, " ", b.eltType);

    var ad = a.domain.dims();
    var bd = b.domain.dims();
    var (arows, acols) = ad;
    var (brows, bcols) = bd;
    if (arows != bcols) then
        writeln("dimension mismatch: ", ad, " ", bd);

    var c:[{arows, bcols}] a.eltType = 0;

    for i in arows do
        for j in bcols do
            for k in acols do
                c(i,j) += a(i,k) * b(k,j);

    return c;
}


with javascript_semantics
function map_range(atom s, a1, a2, b1, b2)
    return b1+(s-a1)*(b2-b1)/(a2-a1)
end function

for i=0 to 10 by 2 do
    printf(1,"%2d : %g\n",{i,map_range(i,0,10,-1,0)})
end for


(scl 1)

(de mapRange (Val A1 A2 B1 B2)
   (+ B1 (*/ (- Val A1) (- B2 B1) (- A2 A1))) )

(for Val (range 0 10.0 1.0)
   (prinl
      (format (mapRange Val 0 10.0 -1.0 0) *Scl) ) )


map: procedure options (main); /* 24/11/2011 */
   declare (a1, a2, b1, b2) float;
   declare d fixed decimal (3,1);

   do d = 0 to 10 by 0.9, 10;
      put skip edit ( d, ' maps to ', map(0, 10, -1, 0, d) ) (f(5,1), a, f(10,6));
   end;

map: procedure (a1, a2, b1, b2, s) returns (float);
   declare (a1, a2, b1, b2, s) float;
   return (b1 + (s - a1)*(b2 - b1) / (a2 - a1) );
end map;
end map;


<?php
class Maze
{
    protected $width;
    protected $height;
    protected $grid;
    protected $path;
    protected $horWalls;
    protected $vertWalls;
    protected $dirs;
    protected $isDebug;

    public function __construct($x, $y, $debug = false)
    {
        $this->width = $x;
        $this->height = $y;
        $this->path = [];
        $this->dirs = [ [0, -1], [0, 1], [-1, 0], [1, 0]]; // array of coordinates of N,S,W,E
        $this->horWalls = []; // list of removed horizontal walls (---+)
        $this->vertWalls = [];// list of removed vertical walls (|)
        $this->isDebug = $debug; // debug flag

        // generate the maze:
        $this->generate();
    }

    protected function generate()
    {
        $this->initMaze(); // init the stack and an unvisited grid
        // start from a random cell and then proceed recursively
        $this->walk(mt_rand(0, $this->width-1), mt_rand(0, $this->height-1));
    }

    /**
    * Actually prints the Maze, on stdOut. Put in a separate method to allow extensibility
    * For simplicity sake doors are positioned on the north wall and east wall
    */
    public function printOut()
    {
        $this->log("Horizontal walls: %s", json_encode($this->horWalls));
        $this->log("Vertical walls: %s", json_encode($this->vertWalls));

        $northDoor = mt_rand(0,$this->width-1);
        $eastDoor = mt_rand(0, $this->height-1);

        $str = '+';
        for ($i=0;$i<$this->width;$i++) {
            $str .= ($northDoor == $i) ? '   +' : '---+';
        }
        $str .= PHP_EOL;
        for ($i=0; $i<$this->height; $i++) {

            for ($j=0; $j<$this->width; $j++) {
                $str .= (!empty($this->vertWalls[$j][$i]) ? $this->vertWalls[$j][$i] : '|   ');
            }
            $str .= ($i == $eastDoor ? '  ' : '|').PHP_EOL.'+';
            for ($j=0; $j<$this->width; $j++) {
                $str .= (!empty($this->horWalls[$j][$i]) ? $this->horWalls[$j][$i] : '---+');
            }
            $str .= PHP_EOL;
        }
        echo $str;
    }

    /**
    * Logs to stdOut if debug flag is enabled
    */
    protected function log(...$params)
    {
        if ($this->isDebug) {
            echo vsprintf(array_shift($params), $params).PHP_EOL;
        }
    }

    private function walk($x, $y)
    {
        $this->log('Entering cell %d,%d', $x, $y);
        // mark current cell as visited
        $this->grid[$x][$y] = true;
        // add cell to path
        $this->path[] = [$x, $y];
        // get list of all neighbors
        $neighbors = $this->getNeighbors($x, $y);
        $this->log("Valid neighbors: %s", json_encode($neighbors));

        if(empty($neighbors)) {
            // Dead end, we need now to backtrack, if there's still any cell left to be visited
            $this->log("Start backtracking along path: %s", json_encode($this->path));
            array_pop($this->path);
            if (!empty($this->path)) {
                $next = array_pop($this->path);
                return $this->walk($next[0], $next[1]);
            }
        } else {
            // randomize neighbors, as per request
            shuffle($neighbors);

            foreach ($neighbors as $n) {
                $nextX = $n[0];
                $nextY = $n[1];
                if ($nextX == $x) {
                    $wallY = max($nextY, $y);
                    $this->log("New cell is on the same column (%d,%d), removing %d, (%d-1) horizontal wall", $nextX, $nextY, $x, $wallY);
                    $this->horWalls[$x][min($nextY, $y)] = "   +";
                }
                if ($nextY == $y) {
                    $wallX = max($nextX, $x);
                    $this->log("New cell is on the same row (%d,%d), removing %d,%d vertical wall", $nextX, $nextY, $wallX, $y);
                    $this->vertWalls[$wallX][$y] = "    ";
                }
                return $this->walk($nextX, $nextY);
            }
        }
    }

    /**
    * Initialize an empty grid of $width * $height dimensions
    */
    private function initMaze()
    {
        for ($i=0;$i<$this->width;$i++) {
            for ($j = 0;$j<$this->height;$j++) {
                $this->grid[$i][$j] = false;
            }
        }
    }

    /**
    * @param int $x
    * @param int $y
    * @return array
    */
    private function getNeighbors($x, $y)
    {
        $neighbors = [];
        foreach ($this->dirs as $dir) {
            $nextX = $dir[0] + $x;
            $nextY = $dir[1] + $y;
            if (($nextX >= 0 && $nextX < $this->width && $nextY >= 0 && $nextY < $this->height) && !$this->grid[$nextX][$nextY]) {
                $neighbors[] = [$nextX, $nextY];
            }
        }
        return $neighbors;
    }
}

$maze = new Maze(10,10);
$maze->printOut();


(defun matrix-multiply (a b)
  (flet ((col (mat i) (mapcar #'(lambda (row) (elt row i)) mat))
         (row (mat i) (elt mat i)))
    (loop for row from 0 below (length a)
          collect (loop for col from 0 below (length (row b 0))
                        collect (apply #'+ (mapcar #'* (row a row) (col b col)))))))

;; example use:
(matrix-multiply '((1 2) (3 4)) '((-3 -8 3) (-2 1 4)))


import std.stdio, std.string, std.conv, std.numeric,
       std.array, std.algorithm;

bool isRectangular(T)(in T[][] M) pure nothrow {
    return M.all!(row => row.length == M[0].length);
}

T[][] matrixMul(T)(in T[][] A, in T[][] B) pure nothrow
in {
    assert(A.isRectangular && B.isRectangular &&
           !A.empty && !B.empty && A[0].length == B.length);
} body {
    auto result = new T[][](A.length, B[0].length);
    auto aux = new T[B.length];

    foreach (immutable j; 0 .. B[0].length) {
        foreach (immutable k, const row; B)
            aux[k] = row[j];
        foreach (immutable i, const ai; A)
            result[i][j] = dotProduct(ai, aux);
    }

    return result;
}

void main() {
    immutable a = [[1, 2], [3, 4], [3, 6]];
    immutable b = [[-3, -8, 3,], [-2, 1, 4]];

    immutable form = "[%([%(%d, %)],\n %)]]";
    writefln("A = \n" ~ form ~ "\n", a);
    writefln("B = \n" ~ form ~ "\n", b);
    writefln("A * B = \n" ~ form, matrixMul(a, b));
}


function Group-Range
{
    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    Param
    (
        [Parameter(Mandatory=$true,
                   Position=0)]
        [ValidateCount(2,2)]
        [double[]]
        $Range1,

        [Parameter(Mandatory=$true,
                   Position=1)]
        [ValidateCount(2,2)]
        [double[]]
        $Range2,

        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$true,
                   Position=2)]
        [double]
        $Map
    )

    Process
    {
        foreach ($number in $Map)
        {
            [PSCustomObject]@{
                Index   = $number
                Mapping = $Range2[0] + ($number - $Range1[0]) * ($Range2[0] - $Range2[1]) / ($Range1[0] - $Range1[1])
            }
        }
    }
}


Structure RR
  a.f
  b.f
EndStructure

Procedure.f MapRange(*a.RR, *b.RR, s)
  Protected.f a1, a2, b1, b2
  a1=*a\a:  a2=*a\b
  b1=*b\a:  b2=*b\b
  ProcedureReturn b1 + ((s - a1) * (b2 - b1) / (a2 - a1))
EndProcedure

;- Test the function
If OpenConsole()
  Define.RR Range1, Range2
  Range1\a=0: Range1\b=10
  Range2\a=-1:Range2\b=0
  ;
  For i=0 To 10
    PrintN(RSet(Str(i),2)+" maps to "+StrF(MapRange(@Range1, @Range2, i),1))
  Next
EndIf


main =>
    gen_maze(8,8).

main([RStr,CStr]) =>
    MaxR = to_int(RStr),
    MaxC = to_int(CStr),
    gen_maze(MaxR,MaxC).

gen_maze(MaxR,MaxC) =>
    Maze = new_array(MaxR,MaxC),
    foreach (R in 1..MaxR, C in 1..MaxC)
        Maze[R,C] = 0
    end,
    gen_maze(Maze,MaxR,MaxC,1,1),
    display_maze(Maze,MaxR,MaxC).

gen_maze(Maze,MaxR,MaxC,R,C) =>
    Dirs = shuffle([left, right, up, down]),
    foreach (Dir in Dirs)
        dir(Dir,Dr,Dc,B,OB),
        R1 := R+Dr,
        C1 := C+Dc,
        if (R1 >= 1 && R1 =< MaxR && C1 >= 1 && C1 =< MaxC && Maze[R1,C1] == 0) then
            Maze[R,C] := Maze[R,C] \/ B,
            Maze[R1,C1] := Maze[R1,C1] \/ OB,
            gen_maze(Maze,MaxR,MaxC,R1,C1)
        end
    end.

% dir(direction, Dr, Dc, Bit, OppBit)
dir(left,  0, -1, 1, 2).
dir(right, 0,  1, 2, 1).
dir(up,    -1, 0, 4, 8).
dir(down,  1,  0, 8, 4).

shuffle(Arr) = Res =>
    foreach (_ in 1..10)
        I1 = random() mod 4 + 1,
        I2 = random() mod 4 + 1,
        T := Arr[I1],
        Arr[I1] := Arr[I2],
        Arr[I2] := T
    end,
    Res = Arr.

display_maze(Maze,MaxR,MaxC) =>
    foreach (R in 1..MaxR)
        foreach (C in 1..MaxC)
            printf("%s", cond(Maze[R,C] /\ 4 == 0, "+---", "+   "))
        end,
        println("+"),
        foreach (C in 1..MaxC)
            printf("%s", cond(Maze[R,C] /\ 1 == 0, "|   ", "    ")),
        end,
        println("|")
    end,
    foreach (C in 1..MaxC)
        print("+---")
    end,
    println("+").


(load "@lib/simul.l")

(de maze (DX DY)
   (let Maze (grid DX DY)
      (let Fld (get Maze (rand 1 DX) (rand 1 DY))
         (recur (Fld)
            (for Dir (shuffle '((west . east) (east . west) (south . north) (north . south)))
               (with ((car Dir) Fld)
                  (unless (or (: west) (: east) (: south) (: north))
                     (put Fld (car Dir) This)
                     (put This (cdr Dir) Fld)
                     (recurse This) ) ) ) ) )
      (for (X . Col) Maze
         (for (Y . This) Col
            (set This
               (cons
                  (cons
                     (: west)
                     (or
                        (: east)
                        (and (= Y 1) (= X DX)) ) )
                  (cons
                     (: south)
                     (or
                        (: north)
                        (and (= X 1) (= Y DY)) ) ) ) ) ) )
      Maze ) )

(de display (Maze)
   (disp Maze 0 '((This) "   ")) )


program Matrix_multiplication;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

type
  TMatrix = record
    values: array of array of Double;
    Rows, Cols: Integer;
    constructor Create(Rows, Cols: Integer);
    class operator Multiply(a: TMatrix; b: TMatrix): TMatrix;
    function ToString: string;
  end;

{ TMatrix }

constructor TMatrix.Create(Rows, Cols: Integer);
var
  i: Integer;
begin
  Self.Rows := Rows;
  self.Cols := Cols;
  SetLength(values, Rows);
  for i := 0 to High(values) do
    SetLength(values[i], Cols);
end;

class operator TMatrix.Multiply(a, b: TMatrix): TMatrix;
var
  rows, cols, l: Integer;
  i, j: Integer;
  sum: Double;
  k: Integer;
begin
  rows := a.Rows;
  cols := b.Cols;
  l := a.Cols;
  if l <> b.Rows then
    raise Exception.Create('Illegal matrix dimensions for multiplication');
  result := TMatrix.create(a.rows, b.Cols);
  for i := 0 to rows - 1 do
    for j := 0 to cols - 1 do
    begin
      sum := 0.0;
      for k := 0 to l - 1 do
        sum := sum + (a.values[i, k] * b.values[k, j]);
      result.values[i, j] := sum;
    end;
end;

function TMatrix.ToString: string;
var
  i, j: Integer;
begin
  Result := '[';
  for i := 0 to 2 do
  begin
    if i > 0 then
      Result := Result + #10;
    Result := Result + '[';
    for j := 0 to 2 do
    begin
      if j > 0 then
        Result := Result + ', ';
      Result := Result + format('%5.2f', [values[i, j]]);
    end;
    Result := Result + ']';
  end;
  Result := Result + ']';
end;

var
  a, b, r: TMatrix;
  i, j: Integer;

begin
  a := TMatrix.Create(3, 3);
  b := TMatrix.Create(3, 3);
  a.values := [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
  b.values := [[2, 2, 2], [5, 5, 5], [7, 7, 7]];
  r := a * b;

  Writeln('a: ');
  Writeln(a.ToString, #10);
  Writeln('b: ');
  Writeln(b.ToString, #10);
  Writeln('a * b:');
  Writeln(r.ToString);
  readln;

end.


>>> def maprange( a, b, s):
	(a1, a2), (b1, b2) = a, b
	return  b1 + ((s - a1) * (b2 - b1) / (a2 - a1))

>>> for s in range(11):
	print("%2g maps to %g" % (s, maprange( (0, 10), (-1, 0), s)))

 0 maps to -1
 1 maps to -0.9
 2 maps to -0.8
 3 maps to -0.7
 4 maps to -0.6
 5 maps to -0.5
 6 maps to -0.4
 7 maps to -0.3
 8 maps to -0.2
 9 maps to -0.1
10 maps to 0


tRange <- function(aRange, bRange, s)
{
  #Guard clauses. We could write some proper error messages, but this is all we really need.
  stopifnot(length(aRange) == 2, length(bRange) == 2,
            is.numeric(aRange), is.numeric(bRange), is.numeric(s),
            s >= aRange[1], s <= aRange[2])
  bRange[1] + ((s - aRange[1]) * (bRange[2] - bRange[1])) / (aRange[2] - aRange[1])
}
data.frame(s = 0:10, t = sapply(0:10, tRange, aRange = c(0, 10), bRange = c(-1, 0)))


*process source attributes xref or(!);
 mgg: Proc Options(main);
 /* REXX ***************************************************************
 * 04.09.2013 Walter Pachl translated from REXX version 3
 **********************************************************************/
 Dcl (MIN,MOD,RANDOM,REPEAT,SUBSTR) Builtin;
 Dcl SYSIN    STREAM INPUT;
 Dcl print Print;
 Dcl imax Bin Fixed(31) init(10);
 Dcl jmax Bin Fixed(31) init(15);
 Dcl seed Bin Fixed(31) init(4711);
 Get File(sysin) Data(imax,jmax,seed);
 Dcl ii   Bin Fixed(31);
 Dcl jj   Bin Fixed(31);
 Dcl id   Bin Fixed(31);
 Dcl jd   Bin Fixed(31);
 id=2*imax+1;                        /* vertical dimension of a.i.j   */
 jd=2*jmax+1;                        /* horizontal dimension of a.i.j */
 Dcl c Char(2000) Var;
 c=repeat('123456789'!!'abcdefghijklmnopqrstuvwxyz'!!
                       'ABCDEFGHIJKLMNOPQRSTUVWXYZ',20);
 Dcl x Bin Float(53);
 x=random(seed);
 Dcl ps Bin Fixed(31) Init(1);         /* first position             */
 Dcl na Bin Fixed(31) Init(1);         /* number of points used      */
 Dcl si Bin Fixed(31);                 /* loop to compute paths      */
 Begin;
 Dcl a(id,jd) Bin Fixed(15);
 Dcl p(imax,jmax) Char(1);
 Dcl 1 pl(imax*jmax),
      2 ic Bin Fixed(15),
      2 jc Bin Fixed(15);
 Dcl 1 np(imax*jmax),
      2 ic Bin Fixed(15),
      2 jc Bin Fixed(15);
 Dcl 1 pos(imax*jmax),
      2 ic Bin Fixed(15),
      2 jc Bin Fixed(15);
 Dcl npl Bin Fixed(31) Init(0);
 a=1;                                   /* mark all borders present   */
 p='.';                                 /* Initialize all grid points */
 ii=rnd(imax);                          /* find a start position      */
 jj=rnd(jmax);
 Do si=1 To 1000;                       /* Do Forever - see Leave     */
   Call path(ii,jj);              /* compute a path starting at ii/jj */
   If na=imax*jmax Then                 /* all points used            */
     Leave;                             /* we are done                */
   Call select_next(ii,jj);             /* get a new start from a path*/
   End;
 Call show;
 Return;

 path: Procedure(ii,jj);
 /**********************************************************************
 * compute a path starting from point (ii,jj)
 **********************************************************************/
 Dcl ii   Bin Fixed(31);
 Dcl jj   Bin Fixed(31);
 Dcl nb   Bin Fixed(31);
 Dcl ch   Bin Fixed(31);
 Dcl pp   Bin Fixed(31);
   p(ii,jj)='1';
   pos.ic(ps)=ii;
   pos.jc(ps)=jj;
   Do pp=1 to 50;               /* compute a path of maximum length 50*/
     nb=neighbors(ii,jj);               /* number of free neighbors   */
     Select;
       When(nb=1)                       /* just one                   */
         Call advance((1),ii,jj);       /* go for it                  */
       When(nb>0) Do;                   /* more Than 1                */
         ch=rnd(nb);                    /* choose one possibility     */
         Call advance(ch,ii,jj);        /* and go for that            */
         End;
       Otherwise                        /* none available             */
         Leave;
       End;
     End;
   End;

 neighbors: Procedure(i,j) Returns(Bin Fixed(31));
 /**********************************************************************
 * count the number of free neighbors of point (i,j)
 **********************************************************************/
 Dcl i    Bin Fixed(31);
 Dcl j    Bin Fixed(31);
 Dcl in   Bin Fixed(31);
 Dcl jn   Bin Fixed(31);
 Dcl nb   Bin Fixed(31) Init(0);
   in=i-1; If in>0     Then Call check(in,j,nb);
   in=i+1; If in<=imax Then Call check(in,j,nb);
   jn=j-1; If jn>0     Then Call check(i,jn,nb);
   jn=j+1; If jn<=jmax Then Call check(i,jn,nb);
   Return(nb);
 End;

 check: Procedure(i,j,n);
 /**********************************************************************
 * check if point (i,j) is free and note it as possible successor
 **********************************************************************/
 Dcl i    Bin Fixed(31);
 Dcl j    Bin Fixed(31);
 Dcl n    Bin Fixed(31);
   If p(i,j)='.' Then Do;               /* point is free              */
     n+=1;                              /* number of free neighbors   */
     np.ic(n)=i;                        /* note it as possible choice */
     np.jc(n)=j;
     End;
 End;

 advance: Procedure(ch,ii,jj);
 /**********************************************************************
 * move to the next point of the current path
 **********************************************************************/
 Dcl ch   Bin Fixed(31);
 Dcl ii   Bin Fixed(31);
 Dcl jj   Bin Fixed(31);
 Dcl ai   Bin Fixed(31);
 Dcl aj   Bin Fixed(31);
 Dcl pii  Bin Fixed(31) Init((ii));
 Dcl pjj  Bin Fixed(31) Init((jj));
 Dcl z    Bin Fixed(31);
   ii=np.ic(ch);
   jj=np.jc(ch);
   ps+=1;                               /* position number            */
   pos.ic(ps)=ii;                       /* note its coordinates       */
   pos.jc(ps)=jj;
   p(ii,jj)=substr(c,ps,1);             /* mark the point as used     */
   ai=pii+ii;                           /* vertical border position   */
   aj=pjj+jj;                           /* horizontal border position */
   a(ai,aj)=0;                          /* tear the border down       */
   na+=1;                               /* number of used positions   */
   z=npl+1;                             /* add the point to the list  */
   pl.ic(z)=ii;                         /* of follow-up start pos.    */
   pl.jc(z)=jj;
   npl=z;
   End;

 show: Procedure;
 /*********************************************************************
 * Show the resulting maze
 *********************************************************************/
 Dcl i Bin Fixed(31);
 Dcl j Bin Fixed(31);
 Dcl ol Char(300) Var;
   Put File(print) Edit('mgg',imax,jmax,seed)(Skip,a,3(f(4)));
   Put File(print) Skip Data(na);
   Do i=1 To id;
     ol='';
     Do j=1 To jd;
       If mod(i,2)=1 Then Do;            /* odd lines                 */
         If a(i,j)=1 Then Do;            /* border to be drawn        */
           If mod(j,2)=0 Then
             ol=ol!!'---';               /* draw the border           */
           Else
             ol=ol!!'+';
           End;
         Else Do;                        /* border was torn down      */
           If mod(j,2)=0 Then
             ol=ol!!'   ';               /* blanks instead of border  */
           Else
             ol=ol!!'+';
           End;
         End;
       Else Do;                          /* even line                 */
         If a(i,j)=1 Then Do;
           If mod(j,2)=0 Then            /* even column               */
             ol=ol!!'   ';               /* moving space              */
           Else                          /* odd column                */
             ol=ol!!'!';                 /* draw the border           */
           End;
         Else                            /* border was torn down      */
           ol=ol!!' ';                   /* blank instead of border   */
         End;
       End;
     Select;
       When(i=6) substr(ol,11,1)='A';
       When(i=8) substr(ol, 3,1)='B';
       Otherwise;
       End;
     Put File(print) Edit(ol,i)(Skip,a,f(3));
     End;
   End;

 select_next: Procedure(is,js);
 /**********************************************************************
 * look for a point to start the nnext path
 **********************************************************************/
 Dcl is Bin Fixed(31);
 Dcl js Bin Fixed(31);
 Dcl n  Bin Fixed(31);
 Dcl nb Bin Fixed(31);
 Dcl s  Bin Fixed(31);
   Do Until(nb>0);                       /* loop until one is found   */
     n=npl;                              /* number of points recorded */
     s=rnd(n);                           /* pick a random index       */
     is=pl.ic(s);                        /* its coordinates           */
     js=pl.jc(s);
     nb=neighbors(is,js);                /* count free neighbors      */
     If nb=0 Then Do;                    /* if there is none          */
       pl.ic(s)=pl.ic(n);                /* remove this point         */
       pl.jc(s)=pl.jc(n);
       npl-=1;
       End;
     End;
 End;

 rnd: Proc(n) Returns(Bin Fixed(31));
 /*********************************************************************
 * return a pseudo-random integer between 1 and n
 *********************************************************************/
 dcl (r,n) Bin Fixed(31);
 r=min(random()*n+1,n);
 Return(r);
 End;

 End;
 End;


program Matrix_multiplication type BasicProgram {}

	function main()
		a float[][] = [[1,2,3],[4,5,6]];
		b float[][] = [[1,2],[3,4],[5,6]];
		c float[][] = mult(a, b);
	end

	function mult(a float[][], b float[][]) returns(float[][])
		if(a.getSize() == 0)
			return (new float[0][0]);
		end
		if(a[1].getSize() != b.getSize())
			return (null); //invalid dims
		end

	   	n int = a[1].getSize();
	   	m int = a.getSize();
	   	p int = b[1].getSize();

		ans float[0][0];
		ans.resizeAll([m, p]);

		// Calculate dot product.
		for(i int from 1 to m)
			for(j int from 1 to p)
				for(k int from 1 to n)
	            	                ans[i][j] += a[i][k] * b[k][j];
				end
			end
		end
		return (ans);
	end
end


#lang racket

(define (make-range-map a1 a2 b1 b2)
  ;; returns a mapping function, doing computing the differences in
  ;; advance so it's fast
  (let ([a (- a2 a1)] [b (- b2 b1)])
    (λ(s) (exact->inexact (+ b1 (/ (* (- s a1) b) a))))))

(define map (make-range-map 0 10 -1 0))
(for ([i (in-range 0 11)]) (printf "~a --> ~a\n" i (map i)))


sub getmapper(Range $a, Range  $b) {
  my ($a1, $a2) = $a.bounds;
  my ($b1, $b2) = $b.bounds;
  return -> $s { $b1 + (($s-$a1) * ($b2-$b1) / ($a2-$a1)) }
}

my &mapper = getmapper(0 .. 10, -1 .. 0);
for ^11 -> $x {say "$x maps to &mapper($x)"}


int g_size = 10;
color background_color = color (80, 80, 220);
color runner = color (255, 50, 50);
color visited_color = color(220, 240, 240);
color done_color = color (100, 160, 250);
int c_size;

Cell[][] cell;
ArrayList<Cell> done = new ArrayList<Cell>();
ArrayList<Cell> visit = new ArrayList<Cell>();
Cell run_cell;

void setup() {
  size(600, 600);
  frameRate(20);
  smooth(4);
  strokeCap(ROUND);
  c_size = max(width/g_size, height/g_size);
  cell = new Cell[g_size][g_size];
  for (int i = 0; i < g_size; i++) {
    for (int j = 0; j < g_size; j++) {
      cell[i][j] = new Cell(i, j);
    }
  }
  for (int i = 0; i < g_size; i++) {
    for (int j = 0; j < g_size; j++) {
      cell[i][j].add_neighbor();
    }
  }
  run_cell = cell[0][0];
  visit.add(run_cell);
}

void draw() {
  background(background_color);
  for (int i = 0; i < g_size; i++) {
    for (int j = 0; j < g_size; j++) {
      cell[i][j].draw_cell();
      cell[i][j].draw_wall();
    }
  }
  if (visit.size() < g_size*g_size) {
    if (run_cell.check_sides()) {
      Cell chosen = run_cell.pick_neighbor();
      done.add(run_cell);
      run_cell.stacked = true;
      if (chosen.i - run_cell.i == 1) {
        run_cell.wall[1] = false;
        chosen.wall[3] = false;
      } else if (chosen.i - run_cell.i == -1) {
        run_cell.wall[3] = false;
        chosen.wall[1] = false;
      } else if (chosen.j - run_cell.j == 1) {
        run_cell.wall[2] = false;
        chosen.wall[0] = false;
      } else {
        run_cell.wall[0] = false;
        chosen.wall[2] = false;
      }
      run_cell.current = false;
      run_cell = chosen;
      run_cell.current = true;
      run_cell.visited = true;
    } else if (done.size()>0) {
      run_cell.current = false;
      run_cell = done.remove(done.size()-1);
      run_cell.stacked = false;
      run_cell.current = true;
    }
  }
}

class Cell {
  ArrayList<Cell> neighbor;
  boolean visited, stacked, current;
  boolean[] wall;
  int i, j;

  Cell(int _i, int _j) {
    i = _i;
    j = _j;
    wall = new boolean[]{true,true,true,true};
  }

  Cell pick_neighbor() {
    ArrayList<Cell> unvisited = new ArrayList<Cell>();
     for(int i = 0;  i < neighbor.size(); i++){
      Cell nb = neighbor.get(i);
     if(nb.visited == false) unvisited.add(nb);
    }
    return unvisited.get(floor(random(unvisited.size())));
  }

  void add_neighbor() {
    neighbor = new ArrayList<Cell>();
    if(i>0){neighbor.add(cell[i-1][j]);}
    if(i<g_size-1){neighbor.add(cell[i+1][j]);}
    if(j>0){neighbor.add(cell[i][j-1]);}
    if(j<g_size-1){neighbor.add(cell[i][j+1]);}
  }

    boolean check_sides() {
      for(int i = 0;  i < neighbor.size(); i++){
      Cell nb = neighbor.get(i);
     if(!nb.visited) return true;
    }
    return false;
  }

  void draw_cell() {
    noStroke();
    noFill();
    if(current) fill(runner);
    else if(stacked) fill(done_color);
    else if(visited) fill(visited_color);
    rect(j*c_size,i*c_size,c_size,c_size);
  }

  void draw_wall() {
    stroke(0);
    strokeWeight(5);
    if(wall[0]) line(j*c_size, i*c_size, j*c_size, (i+1)* c_size);
    if(wall[1]) line(j*c_size, (i+1)*c_size, (j+1)*c_size, (i+1)*c_size);
    if(wall[2]) line((j+1)*c_size, (i+1)*c_size, (j+1)*c_size, i*c_size);
    if(wall[3]) line((j+1)*c_size, i*c_size, j*c_size, i*c_size);
  }
}


  def mult(m1, m2) do
    Enum.map m1, fn (x) -> Enum.map t(m2), fn (y) -> Enum.zip(x, y)
        |> Enum.map(fn {x, y} -> x * y end)
        |> Enum.sum
      end
    end
  end

  def t(m) do # transpose
    List.zip(m) |> Enum.map(&Tuple.to_list(&1))
  end


MAC ZIP = ([INT n]TYPE t: vector1 vector2) -> [n][2]t:
  [INT k = 1..n](vector1[k], vector2[k]).

MAC TRANSPOSE = ([INT n][INT m]TYPE t: matrix) -> [m][n]t:
  [INT i = 1..m] [INT j = 1..n] matrix[j][i].

MAC INNER_PRODUCT{FN * = [2]TYPE t -> TYPE s, FN + = [2]s -> s}
                 = ([INT n][2]t: vector) -> s:
  IF n = 1 THEN *vector[1]
  ELSE *vector[1] + INNER_PRODUCT {*,+} vector[2..n]
  FI.

MAC MATRIX_MULT {FN * = [2]TYPE t->TYPE s, FN + = [2]s->s} =
([INT n][INT m]t: matrix1, [m][INT p]t: matrix2) -> [n][p]s:
BEGIN
  LET transposed_matrix2 = TRANSPOSE matrix2.
OUTPUT [INT i = 1..n][INT j = 1..p]
       INNER_PRODUCT{*,+}ZIP(matrix1[i],transposed_matrix2[j])
END.

TYPE element = NEW elt/(1..20),
     product = NEW prd/(1..1200).

FN PLUS = (product: integer1 integer2) -> product:
  ARITH integer1 + integer2.

FN MULT = (element: integer1 integer2) -> product:
  ARITH integer1 * integer2.

FN MULT_234 = ([2][3]element:matrix1, [3][4]element:matrix2) ->
             [2][4]product:
  MATRIX_MULT{MULT,PLUS}(matrix1, matrix2).

FN TEST = () -> [2][4]product:
( LET m1 = ((elt/2, elt/1, elt/1),
            (elt/3, elt/6, elt/9)),
      m2 = ((elt/6, elt/1, elt/3, elt/4),
            (elt/9, elt/2, elt/8, elt/3),
            (elt/6, elt/4, elt/1, elt/2)).
  OUTPUT
    MULT_234 (m1, m2)
).

COM test: just displaysignal MOC


/*REXX program maps and displays a  range of numbers from  one range  to  another range.*/
rangeA =   0   10                                      /*or:   rangeA =   '  0  10 '    */
rangeB =  -1    0                                      /*or:   rangeB =   " -1   0 "    */
parse  var   rangeA  L  H
inc= 1
          do j=L  to H  by inc * (1 - 2 * sign(H<L) )  /*BY:   either   +inc  or  -inc  */
          say right(j, 9)      ' maps to '      mapR(rangeA, rangeB, j)
          end   /*j*/
exit                                                   /*stick a fork in it, we're done.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
mapR: procedure; parse arg a1 a2,b1 b2,s;$=b1+(s-a1)*(b2-b1)/(a2-a1);return left('',$>=0)$


# Project : Map range

decimals(1)
al = 0
ah = 10
bl = -1
bh = 0
for n = 0 to 10
     see "" + n + " maps to " + maprange(al, bl, n) + nl
next

func maprange(al, bl, s)
       return bl + (s - al) * (bh - bl) / (ah - al)


def map_range(a, b, s)
  af, al, bf, bl = a.first, a.last, b.first, b.last
  bf + (s - af)*(bl - bf).quo(al - af)
end

(0..10).each{|s| puts "%s maps to %g" % [s, map_range(0..10, -1..0, s)]}


:- dynamic cell/2.

maze(Lig,Col) :-
	retractall(cell(_,_)),

	new(D, window('Maze')),

	% creation of the grid
	forall(between(0,Lig, I),
	       (XL is  50, YL is I * 30 + 50,
		XR is Col * 30 + 50,
		new(L, line(XL, YL, XR, YL)),
		send(D, display, L))),

	forall(between(0,Col, I),
	       (XT is  50 + I * 30, YT is 50,
		YB is Lig * 30 + 50,
		new(L, line(XT, YT, XT, YB)),
		send(D, display, L))),

	SX is Col * 30 + 100,
	SY is Lig * 30 + 100,
	send(D, size, new(_, size(SX, SY))),

	% choosing a first cell
	L0 is random(Lig),
	C0 is random(Col),
	assert(cell(L0, C0)),
	\+search(D, Lig, Col, L0, C0),
	send(D, open).

search(D, Lig, Col, L, C) :-
	Dir is random(4),
	nextcell(Dir, Lig, Col, L, C, L1, C1),
	assert(cell(L1,C1)),
	assert(cur(L1,C1)),
	erase_line(D, L, C, L1, C1),
	search(D, Lig, Col, L1, C1).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
erase_line(D, L, C, L, C1) :-
	(   C < C1 -> C2 = C1; C2 = C),
	XT is C2  * 30 + 50,
	YT is L * 30 + 51, YR is (L+1) * 30 + 50,
	new(Line, line(XT, YT, XT, YR)),
	send(Line, colour, white),
	send(D, display, Line).

erase_line(D, L, C, L1, C) :-
	XT is  51 + C * 30, XR is 50 + (C + 1) * 30,
	(   L < L1 -> L2 is L1; L2 is L),
	YT is L2 * 30 + 50,
	new(Line, line(XT, YT, XR, YT)),
	send(Line, colour, white),
	send(D, display, Line).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nextcell(Dir, Lig, Col, L, C, L1, C1) :-
	next(Dir, Lig, Col, L, C, L1, C1);
	(   Dir1 is (Dir+3) mod 4,
	    next(Dir1, Lig, Col, L, C, L1, C1));
	(   Dir2 is (Dir+1) mod 4,
	    next(Dir2, Lig, Col, L, C, L1, C1));
	(   Dir3 is (Dir+2) mod 4,
	    next(Dir3, Lig, Col, L, C, L1, C1)).

% 0 => northward
next(0, _Lig, _Col, L, C, L1, C) :-
	L > 0,
	L1 is L - 1,
	\+cell(L1, C).

% 1 => rightward
next(1, _Lig, Col, L, C, L, C1) :-
	C < Col - 1,
	C1 is C + 1,
	\+cell(L, C1).

% 2 => southward
next(2, Lig, _Col, L, C, L1, C) :-
	L < Lig - 1,
	L1 is L + 1,
	\+cell(L1, C).

% 3 => leftward
next(2, _Lig, _Col, L, C, L, C1) :-
	C > 0,
	C1 is C - 1,
	\+cell(L, C1).


%% Multiplies two matrices. Usage example:
%% $ matrix:multiply([[1,2,3],[4,5,6]], [[4,4],[0,0],[1,4]])
%% If the dimentions are incompatible, an error is thrown.
%%
%% The erl shell may encode the lists output as strings. In order to prevent such
%% behaviour, BEFORE running matrix:multiply, run shell:strings(false) to disable
%% auto-encoding. When finished, run shell:strings(true) to reset the defaults.

-module(matrix).
-export([multiply/2]).

transpose([[]|_]) ->
    [];
transpose(B) ->
  [lists:map(fun hd/1, B) | transpose(lists:map(fun tl/1, B))].

red(Pair, Sum) ->
    X = element(1, Pair),   %gets X
    Y = element(2, Pair),   %gets Y
    X * Y + Sum.

%% Mathematical dot product. A x B = d
%% A, B = 1-dimension vector
%% d    = scalar
dot_product(A, B) ->
    lists:foldl(fun red/2, 0, lists:zip(A, B)).

%% Exposed function. Expected result is C = A x B.
multiply(A, B) ->
    %% First transposes B, to facilitate the calculations (It's easier to fetch
    %% row than column wise).
    multiply_internal(A, transpose(B)).

%% This function does the actual multiplication, but expects the second matrix
%% to be transposed.
multiply_internal([Head | Rest], B) ->
    % multiply each row by Y
    Element = multiply_row_by_col(Head, B),

    % concatenate the result of this multiplication with the next ones
    [Element | multiply_internal(Rest, B)];

multiply_internal([], B) ->
    % concatenating and empty list to the end of a list, changes nothing.
    [].

multiply_row_by_col(Row, [Col_Head | Col_Rest]) ->
    Scalar = dot_product(Row, Col_Head),

    [Scalar | multiply_row_by_col(Row, Col_Rest)];

multiply_row_by_col(Row, []) ->
    [].


use std::ops::{Add, Sub, Mul, Div};

fn map_range<T: Copy>(from_range: (T, T), to_range: (T, T), s: T) -> T
    where T: Add<T, Output=T> +
             Sub<T, Output=T> +
             Mul<T, Output=T> +
             Div<T, Output=T>
{
    to_range.0 + (s - from_range.0) * (to_range.1 - to_range.0) / (from_range.1 - from_range.0)
}

fn main() {
    let input: Vec<f64> = vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0];
    let result = input.into_iter()
        .map(|x| map_range((0.0, 10.0), (-1.0, 0.0), x))
        .collect::<Vec<f64>>();
    print!("{:?}", result);
}


def mapRange(a1:Double, a2:Double, b1:Double, b2:Double, x:Double):Double=b1+(x-a1)*(b2-b1)/(a2-a1)

for(i <- 0 to 10)
  println("%2d in [0, 10] maps to %5.2f in [-1, 0]".format(i, mapRange(0,10, -1,0, i)))


$ include "seed7_05.s7i";
  include "float.s7i";

const func float: mapRange (in float: a1, in float: a2, in float: b1, in float: b2, ref float: s) is
    return b1 + (s-a1)*(b2-b1)/(a2-a1);

const proc: main is func
  local
    var integer: number is 0;
  begin
    writeln("Mapping [0,10] to [-1,0] at intervals of 1:");
    for number range 0 to 10 do
      writeln("f(" <& number <& ") = " <& mapRange(0.0, 10.0, -1.0, 0.0, flt(number)) digits 1);
    end for;
  end func;


func map_range(a, b, x) {
    var (a1, a2, b1, b2) = (a.bounds, b.bounds);
    x-a1 * b2-b1 / a2-a1 + b1;
}

var a = 0..10;
var b = -1..0;

for x in a {
    say "#{x} maps to #{map_range(a, b, x)}";
}


Enumeration
  ;indexes for types of offsets from maze coordinates (x,y)
  #visited ;used to index visited(x,y) in a given direction from current maze cell
  #maze    ;used to index maze() in a given direction from current maze cell
  #wall    ;used to index walls in maze() in a given direction from current maze cell
  #numOffsets = #wall
  ;direction indexes
  #dir_ID = 0 ;identity value, produces no changes
  #firstDir
  #dir_N = #firstDir
  #dir_E
  #dir_S
  #dir_W
  #numDirs = #dir_W
EndEnumeration

DataSection
  ;maze(x,y) offsets for visited, maze, & walls for each direction
  Data.i 1, 1,  0,  0, 0, 0 ;ID
  Data.i 1, 0,  0, -1, 0, 0 ;N
  Data.i 2, 1,  1,  0, 1, 0 ;E
  Data.i 1, 2,  0,  1, 0, 1 ;S
  Data.i 0, 1, -1,  0, 0, 0 ;W
  Data.i %00, %01, %10, %01, %10 ;wall values for ID, N, E, S, W
EndDataSection

#cellDWidth = 4

Structure mazeOutput
  vWall.s
  hWall.s
EndStructure

;setup reference values indexed by type and direction from current map cell
Global Dim offset.POINT(#numOffsets, #numDirs)
Define i, j
For i = 0 To #numDirs
  For j = 0 To #numOffsets
    Read.i offset(j, i)\x: Read.i offset(j, i)\y
  Next
Next

Global Dim wallvalue(#numDirs)
For i = 0 To #numDirs: Read.i wallvalue(i): Next

Procedure makeDisplayMazeRow(Array mazeRow.mazeOutput(1), Array maze(2), y)
  ;modify mazeRow() to produce output of 2 strings showing the vertical walls above and horizontal walls across a given maze row
  Protected x, vWall.s, hWall.s
  Protected mazeWidth = ArraySize(maze(), 1), mazeHeight = ArraySize(maze(), 2)

  vWall = "": hWall = ""
  For x = 0 To mazeWidth
    If maze(x, y) & wallvalue(#dir_N): vWall + "+   ": Else: vWall + "+---": EndIf
    If maze(x, y) & wallvalue(#dir_W): hWall + "    ": Else: hWall + "|   ": EndIf
  Next
  mazeRow(0)\vWall = Left(vWall, mazeWidth * #cellDWidth + 1)
  If y <> mazeHeight: mazeRow(0)\hWall = Left(hWall, mazeWidth * #cellDWidth + 1): Else: mazeRow(0)\hWall = "": EndIf
EndProcedure

Procedure displayMaze(Array maze(2))
  Protected x, y, vWall.s, hWall.s, mazeHeight = ArraySize(maze(), 2)
  Protected Dim mazeRow.mazeOutput(0)

  For y = 0 To mazeHeight
    makeDisplayMazeRow(mazeRow(), maze(), y)
    PrintN(mazeRow(0)\vWall): PrintN(mazeRow(0)\hWall)
  Next
EndProcedure

Procedure generateMaze(Array maze(2), mazeWidth, mazeHeight)
  Dim maze(mazeWidth, mazeHeight) ;Each cell specifies walls present above and to the left of it,
                                  ;array includes an extra row and column for the right and bottom walls
  Dim visited(mazeWidth + 1, mazeHeight + 1) ;Each cell represents a cell of the maze, an extra line of cells are included
                                             ;as padding around the representative cells for easy border detection

  Protected i
  ;mark outside border as already visited (off limits)
  For i = 0 To mazeWidth
    visited(i + offset(#visited, #dir_N)\x, 0 + offset(#visited, #dir_N)\y) = #True
    visited(i + offset(#visited, #dir_S)\x, mazeHeight - 1 + offset(#visited, #dir_S)\y) = #True
  Next
  For i = 0 To mazeHeight
    visited(0 + offset(#visited, #dir_W)\x, i + offset(#visited, #dir_W)\y) = #True
    visited(mazeWidth - 1 + offset(#visited, #dir_E)\x, i + offset(#visited, #dir_E)\y) = #True
  Next

  ;generate maze
  Protected x = Random(mazeWidth - 1), y = Random (mazeHeight - 1), cellCount, nextCell
  visited(x + offset(#visited, #dir_ID)\x, y + offset(#visited, #dir_ID)\y) = #True
  PrintN("Maze of size " + Str(mazeWidth) + " x " + Str(mazeHeight) + ", generation started at " + Str(x) + " x " + Str(y))

  NewList stack.POINT()
  Dim unvisited(#numDirs - #firstDir)
  Repeat
    cellCount = 0
    For i = #firstDir To #numDirs
      If Not visited(x + offset(#visited, i)\x, y + offset(#visited, i)\y)
        unvisited(cellCount) = i: cellCount + 1
      EndIf
    Next

    If cellCount
      nextCell = unvisited(Random(cellCount - 1))
      visited(x + offset(#visited, nextCell)\x, y + offset(#visited, nextCell)\y) = #True
      maze(x + offset(#wall, nextCell)\x, y + offset(#wall, nextCell)\y) | wallvalue(nextCell)

      If cellCount > 1
        AddElement(stack())
        stack()\x = x: stack()\y = y
      EndIf
      x + offset(#maze, nextCell)\x: y + offset(#maze, nextCell)\y
    ElseIf ListSize(stack()) > 0
      x = stack()\x: y = stack()\y
      DeleteElement(stack())
    Else
      Break  ;end maze generation
    EndIf
  ForEver

  ; ;mark random entry and exit point
  ; x = Random(mazeWidth - 1): y = Random(mazeHeight - 1)
  ; maze(x, 0) | wallvalue(#dir_N): maze(mazeWidth, y) | wallvalue(#dir_E)
  ProcedureReturn
EndProcedure

If OpenConsole()
  Dim maze(0, 0)
  Define mazeWidth = Random(5) + 7: mazeHeight = Random(5) + 3
  generateMaze(maze(), mazeWidth, mazeHeight)
  displayMaze(maze())

  Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
  CloseConsole()
EndIf


PROGRAM MAT_PROD

DIM A[3,1],B[1,2],ANS[3,2]

BEGIN

DATA(1,2,3,4,5,6,7,8)
DATA(1,2,3,4,5,6)

FOR I=0 TO 3 DO
   FOR J=0 TO 1 DO
      READ(A[I,J])
   END FOR
END FOR

FOR I=0 TO 1 DO
   FOR J=0 TO 2 DO
      READ(B[I,J])
   END FOR
END FOR

FOR I=0 TO UBOUND(ANS,1) DO
  FOR J=0 TO UBOUND(ANS,2) DO
     FOR K=0 TO UBOUND(A,2) DO
        ANS[I,J]=ANS[I,J]+(A[I,K]*B[K,J])
     END FOR
  END FOR
END FOR
! print answer
  FOR I=0 TO UBOUND(ANS,1) DO
     FOR J=0 TO UBOUND(ANS,2) DO
        PRINT(ANS[I,J],)
     END FOR
     PRINT
  END FOR

END PROGRAM


function matrix_mul(sequence a, sequence b)
    sequence c
    if length(a[1]) != length(b) then
        return 0
    else
        c = repeat(repeat(0,length(b[1])),length(a))
        for i = 1 to length(a) do
            for j = 1 to length(b[1]) do
                for k = 1 to length(a[1]) do
                    c[i][j] += a[i][k]*b[k][j]
                end for
            end for
        end for
        return c
    end if
end function


program define maprange
	version 15.1
	syntax varname(numeric) [if] [in], ///
		from(numlist min=2 max=2) to(numlist min=2 max=2) ///
		GENerate(name) [REPLACE]
	tempname a b c d h
	sca `a'=`:word 1 of `from''
	sca `b'=`:word 2 of `from''
	sca `c'=`:word 1 of `to''
	sca `d'=`:word 2 of `to''
	sca `h'=(`d'-`c')/(`b'-`a')
	cap confirm variable `generate'
	if "`replace'"=="replace" & !_rc {
		qui replace `generate'=(`varlist'-`a')*`h'+`c' `if' `in'
	}
	else {
		if "`replace'"=="replace" {
			di in gr `"(note: variable `generate' not found)"'
		}
		qui gen `generate'=(`varlist'-`a')*`h'+`c' `if' `in'
	}
end


import Foundation

func mapRanges(_ r1: ClosedRange<Double>, _ r2: ClosedRange<Double>, to: Double) -> Double {
  let num = (to - r1.lowerBound) * (r2.upperBound - r2.lowerBound)
  let denom = r1.upperBound - r1.lowerBound

  return r2.lowerBound + num / denom
}

for i in 0...10 {
  print(String(format: "%2d maps to %5.2f", i, mapRanges(0...10, -1...0, to: Double(i))))
}


package require Tcl 8.5
proc rangemap {rangeA rangeB value} {
    lassign $rangeA a1 a2
    lassign $rangeB b1 b2
    expr {$b1 + ($value - $a1)*double($b2 - $b1)/($a2 - $a1)}
}


from random import shuffle, randrange

def make_maze(w = 16, h = 8):
    vis = [[0] * w + [1] for _ in range(h)] + [[1] * (w + 1)]
    ver = [["|  "] * w + ['|'] for _ in range(h)] + [[]]
    hor = [["+--"] * w + ['+'] for _ in range(h + 1)]

    def walk(x, y):
        vis[y][x] = 1

        d = [(x - 1, y), (x, y + 1), (x + 1, y), (x, y - 1)]
        shuffle(d)
        for (xx, yy) in d:
            if vis[yy][xx]: continue
            if xx == x: hor[max(y, yy)][x] = "+  "
            if yy == y: ver[y][max(x, xx)] = "   "
            walk(xx, yy)

    walk(randrange(w), randrange(h))

    s = ""
    for (a, b) in zip(hor, ver):
        s += ''.join(a + ['\n'] + b + ['\n'])
    return s

if __name__ == '__main__':
    print(make_maze())


let MatrixMultiply (matrix1 : _[,] , matrix2 : _[,]) =
    let result_row = (matrix1.GetLength 0)
    let result_column = (matrix2.GetLength 1)
    let ret = Array2D.create result_row result_column 0
    for x in 0 .. result_row - 1 do
        for y in 0 .. result_column - 1 do
            let mutable acc = 0
            for z in 0 .. (matrix1.GetLength 1) - 1 do
                acc <- acc + matrix1.[x,z] * matrix2.[z,y]
            ret.[x,y] <- acc
    ret


double map_range(double s, int a1, int a2, int b1, int b2) {
  return b1+(s-a1)*(b2-b1)/(a2-a1);
}

void main() {
  for (int s = 0; s < 11; s++){
    print("%2d maps to %5.2f\n", s, map_range(s, 0, 10, -1, 0));
  }
}


let mapRange r1 r2 s =>
    +
        (at r2 0)
        (/
            (*
                (-
                    s
                    (at r1 0)
                )
                (-
                    (at r2 1)
                    (at r2 0)
                )
            )
            (-
                (at r1 1)
                (at r1 0)
            )
        )
    ;

let s => import 'stream';
let str => import 'strings';

s.range 10
-> s.map (@ enum v => [v; mapRange [0; 10] [-1; 0] v])
-> s.map (@ print v => str.format '{} -> {}' (at v 0) (at v 1) -- io.writeln io.stdout)
-> s.drain
;


import "/fmt" for Fmt

var mapRange = Fn.new { |a, b, s| b.from + (s - a.from) * (b.to - b.from) / (a.to - a.from) }

var a = 0..10
var b = -1..0
for (s in a) {
    var t = mapRange.call(a, b, s)
    var f = (t >= 0) ? " " : ""
    System.print("%(Fmt.d(2, s)) maps to %(f)%(t)")
}


#lang racket

;; the structure representing a maze of size NxM
(struct maze (N M tbl))

;; managing cell properties
(define (connections tbl c) (dict-ref tbl c '()))

(define (connect! tbl c n)
  (dict-set! tbl c (cons n (connections tbl c)))
  (dict-set! tbl n (cons c (connections tbl n))))

(define (connected? tbl a b) (member a (connections tbl b)))

;; Returns a maze of a given size
;; build-maze :: Index Index -> Maze
(define (build-maze N M)
  (define tbl (make-hash))
  (define (visited? tbl c) (dict-has-key? tbl c))
  (define (neigbours c)
    (filter
     (match-lambda [(list i j) (and (<= 0 i (- N 1)) (<= 0 j (- M 1)))])
     (for/list ([d '((0 1) (0 -1) (-1 0) (1 0))]) (map + c d))))
  ; generate the maze
  (let move-to-cell ([c (list (random N) (random M))])
    (for ([n (shuffle (neigbours c))] #:unless (visited? tbl n))
      (connect! tbl c n)
      (move-to-cell n)))
  ; return the result
  (maze N M tbl))


constant mapping = :OPEN(' '),
		      :N< ╵ >,
		      :E< ╶ >,
		     :NE< └ >,
		      :S< ╷ >,
		     :NS< │ >,
		     :ES< ┌ >,
		    :NES< ├ >,
		      :W< ╴ >,
		     :NW< ┘ >,
		     :EW< ─ >,
		    :NEW< ┴ >,
		     :SW< ┐ >,
		    :NSW< ┤ >,
		    :ESW< ┬ >,
		   :NESW< ┼ >,
		   :TODO< x >,
	          :TRIED< · >;

enum Sym (mapping.map: *.key);
my @ch = mapping.map: *.value;

enum Direction <DeadEnd Up Right Down Left>;

sub gen_maze ( $X,
               $Y,
               $start_x = (^$X).pick * 2 + 1,
               $start_y = (^$Y).pick * 2 + 1 )
{
    my @maze;
    push @maze, $[ flat ES, -N, (ESW, EW) xx $X - 1, SW ];
    push @maze, $[ flat (NS, TODO) xx $X, NS ];
    for 1 ..^ $Y {
	push @maze, $[ flat NES, EW, (NESW, EW) xx $X - 1, NSW ];
	push @maze, $[ flat (NS, TODO) xx $X, NS ];
    }
    push @maze, $[ flat NE, (EW, NEW) xx $X - 1, -NS, NW ];
    @maze[$start_y][$start_x] = OPEN;

    my @stack;
    my $current = [$start_x, $start_y];
    loop {
        if my $dir = pick_direction( $current ) {
            @stack.push: $current;
            $current = move( $dir, $current );
        }
        else {
            last unless @stack;
            $current = @stack.pop;
        }
    }
    return @maze;

    sub pick_direction([$x,$y]) {
	my @neighbors =
	    (Up    if @maze[$y - 2][$x]),
	    (Down  if @maze[$y + 2][$x]),
	    (Left  if @maze[$y][$x - 2]),
	    (Right if @maze[$y][$x + 2]);
	@neighbors.pick or DeadEnd;
    }

    sub move ($dir, @cur) {
	my ($x,$y) = @cur;
	given $dir {
	    when Up    { @maze[--$y][$x] = OPEN; @maze[$y][$x-1] -= E; @maze[$y--][$x+1] -= W; }
	    when Down  { @maze[++$y][$x] = OPEN; @maze[$y][$x-1] -= E; @maze[$y++][$x+1] -= W; }
	    when Left  { @maze[$y][--$x] = OPEN; @maze[$y-1][$x] -= S; @maze[$y+1][$x--] -= N; }
	    when Right { @maze[$y][++$x] = OPEN; @maze[$y-1][$x] -= S; @maze[$y+1][$x++] -= N; }
	}
	@maze[$y][$x] = 0;
	[$x,$y];
    }
}

sub display (@maze) {
    for @maze -> @y {
	for @y.rotor(2) -> ($w, $c) {
	    print @ch[abs $w];
	    if $c >= 0 { print @ch[$c] x 3 }
	    else { print ' ', @ch[abs $c], ' ' }
	}
	say @ch[@y[*-1]];
    }
}

display gen_maze( 29, 19 );


class Main
{
  // multiply two matrices (with no error checking)
  public static Int[][] multiply (Int[][] m1, Int[][] m2)
  {
    Int[][] result := [,]
    m1.each |Int[] row1|
    {
      Int[] row := [,]
      m2[0].size.times |Int colNumber|
      {
        Int value := 0
        m2.each |Int[] row2, Int index|
        {
          value += row1[index] * row2[colNumber]
        }
        row.add (value)
      }
     result.add (row)
    }
    return result
  }

  public static Void main ()
  {
    m1 := [[1,2,3],[4,5,6]]
    m2 := [[1,2],[3,4],[5,6]]

    echo ("${m1} times ${m2} = ${multiply(m1,m2)}")
  }
}


include c:\cxpl\codes;

func real Map(A1, A2, B1, B2, S);
real A1, A2, B1, B2, S;
return B1 + (S-A1)*(B2-B1)/(A2-A1);

int I;
[for I:= 0 to 10 do
    [if I<10 then ChOut(0, ^ );  IntOut(0, I);
    RlOut(0, Map(0., 10., -1., 0., float(I)));
    CrLf(0);
    ];
]


sub MapRange(s, a1, a2, b1, b2)
    return b1+(s-a1)*(b2-b1)/(a2-a1)
end sub

for i = 0 to 10 step 2
    print i, " : ", MapRange(i,0,10,-1,0)
next


Red ["Maze generation"]

size: as-pair to-integer ask "Maze width: " to-integer ask "Maze height: "
random/seed now/time
offsetof: function [pos] [pos/y * size/x + pos/x + 1]
visited?: function [pos] [find visited pos]

newneighbour: function [pos][
	nnbs: collect [
		if all [pos/x > 0 not visited? p: pos - 1x0] [keep p]
		if all [pos/x < (size/x - 1) not visited? p: pos + 1x0] [keep p]
		if all [pos/y > 0 not visited? p: pos - 0x1] [keep p]
		if all [pos/y < (size/y - 1) not visited? p: pos + 0x1] [keep p]
	]
	pick nnbs random length? nnbs
]
expand: function [pos][
	insert visited pos
	either npos: newneighbour pos [
		insert exploring npos
		do select [
			0x-1 [o: offsetof npos walls/:o/y: 0]
			1x0  [o: offsetof  pos walls/:o/x: 0]
			0x1  [o: offsetof  pos walls/:o/y: 0]
			-1x0 [o: offsetof npos walls/:o/x: 0]
		] npos - pos
	][
		remove exploring
	]
]
visited: []
walls: append/dup [] 1x1 size/x * size/y
exploring: reduce [random size - 1x1]

until [
	expand exploring/1
	empty? exploring
]

print append/dup "" " _" size/x
repeat j size/y [
	prin "|"
	repeat i size/x [
		p: pick walls (j - 1 * size/x + i)
		prin rejoin [pick " _" 1 + p/y pick " |" 1 + p/x]
	]
	print ""
]


S" fsl-util.fs" REQUIRED
S" fsl/dynmem.seq" REQUIRED
: F+! ( addr -- ) ( F: r -- )  DUP [email protected] F+ F! ;
: FSQR ( F: r1 -- r2 ) FDUP F* ;
S" fsl/gaussj.seq" REQUIRED

3 3 float matrix A{{
1e 2e 3e  4e 5e 6e  7e 8e 9e  3 3 A{{ }}fput
3 3 float matrix B{{
3e 3e 3e  2e 2e 2e  1e 1e 1e  3 3 B{{ }}fput
float dmatrix C{{    \ result

A{{ 3 3 B{{ 3 3 & C{{ mat*
3 3 C{{ }}fprint


/*REXX program generates and displays a  rectangular  solvable maze  (of any size).     */
parse arg rows cols seed .                       /*allow user to specify the maze size. */
if rows='' | rows==','  then rows= 19            /*No rows given?  Then use the default.*/
if cols='' | cols==','  then cols= 19            /* " cols   "  ?    "   "   "     "    */
if datatype(seed, 'W')  then call random ,,seed  /*use a random  seed for repeatability.*/
ht=0;                        @.=0                /*HT= # rows in grid;  @.: default cell*/
call makeRow  '┌'copies("~┬", cols - 1)'~┐'      /*construct the top edge of the maze.  */
                                                 /* [↓]  construct the maze's grid.     */
      do    r=1  for rows;   _=;     __=;      hp= "|";              hj= '├'
         do c=1  for cols;   _= _ || hp'1';    __= __ || hj"~";      hj= '┼';      hp= "│"
         end   /*c*/
                        call makeRow  _'│'       /*construct the right edge of the cells*/
      if r\==rows  then call makeRow __'┤'       /*    "      "    "     "   "  "  maze.*/
      end      /*r*/                             /* [↑]  construct the maze's grid.     */

call makeRow  '└'copies("~┴",  cols - 1)'~┘'     /*construct the bottom edge of the maze*/
r!= random(1, rows) *2;     c!= random(1, cols) *2;      @.r!.c!= 0   /*choose 1st cell.*/
                                                 /* [↓]  traipse through the maze.      */
  do forever;    n= hood(r!, c!);    if n==0  then if \fCell()  then leave  /*¬freecell?*/
  call ?;        @._r._c= 0                      /*get the (next) maze direction to go. */
  ro= r!;        co= c!;     r!= _r;    c!= _c   /*save original maze cell coordinates. */
  ?.zr= ?.zr % 2;            ?.zc= ?.zc % 2      /*get the maze row and cell directions.*/
  rw= ro + ?.zr;             cw= co + ?.zc       /*calculate the next row and column.   */
  @.rw.cw= .                                     /*mark the maze cell as being visited. */
  end   /*forever*/
                                                 /* [↓]  display maze to the terminal.  */
         do     r=1  for ht;            _=
             do c=1  for cols*2 + 1;    _= _ || @.r.c;    end  /*c*/
         if \(r//2)  then _= translate(_, '\', .)                   /*trans to backslash*/
         @.r= _                                                     /*save the row in @.*/
         end   /*r*/

      do #=1  for ht;           _= @.#           /*display the maze to the terminal.    */
      call makeNice                              /*prettify cell corners and dead─ends. */
      _=  changestr( 1 ,  _   , 111     )        /*──────these four ────────────────────*/
      _=  changestr( 0 ,  _   , 000     )        /*───────── statements are ────────────*/
      _=  changestr( . ,  _   , "   "   )        /*────────────── used for preserving ──*/
      _=  changestr('~',  _   , "───"   )        /*────────────────── the aspect ratio. */
      say translate( _ , '─│' , "═|\10" )        /*make it presentable for the screen.  */
      end   /*#*/
  exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
@:       parse arg _r,_c;     return  @._r._c    /*a fast way to reference a maze cell. */
makeRow: parse arg z; ht= ht+1;  do c=1  for length(z); @.ht.c=substr(z,c,1);  end; return
hood:    parse arg rh,ch;     return  @(rh+2,ch)  + @(rh-2,ch)  + @(rh,ch-2)  + @(rh,ch+2)
/*──────────────────────────────────────────────────────────────────────────────────────*/
?:         do forever;  ?.= 0;   ?= random(1, 4);     if ?==1  then ?.zc= -2     /*north*/
                                                      if ?==2  then ?.zr=  2     /* east*/
                                                      if ?==3  then ?.zc=  2     /*south*/
                                                      if ?==4  then ?.zr= -2     /* west*/
           _r= r! + ?.zr;       _c= c! + ?.zc;        if @._r._c == 1    then return
           end   /*forever*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
fCell:     do     r=1  for rows;                rr= r + r
               do c=1  for cols;                         cc= c + c
               if hood(rr,cc)==1  then do;  r!= rr;  c!= cc;   @.r!.c!= 0;  return 1;  end
               end   /*c*/                       /* [↑]  r! and c!  are used by invoker.*/
           end       /*r*/;       return 0
/*──────────────────────────────────────────────────────────────────────────────────────*/
makeNice: width= length(_);     old= # - 1;     new= # + 1;     old_= @.old;   new_= @.new
          if left(_, 2)=='├.'  then _= translate(_, "|", '├')
          if right(_,2)=='.┤'  then _= translate(_, "|", '┤')

             do  k=1  for  width  while #==1;         z= substr(_, k, 1) /*maze top row.*/
             if z\=='┬'                  then iterate
             if substr(new_, k, 1)=='\'  then _= overlay("═", _, k)
             end   /*k*/

             do  k=1  for  width  while #==ht;        z= substr(_, k, 1) /*maze bot row.*/
             if z\=='┴'                  then iterate
             if substr(old_, k, 1)=='\'  then _= overlay("═", _, k)
             end   /*k*/

             do  k=3  to  width-2  by 2  while #//2;  z= substr(_, k, 1) /*maze mid rows*/
             if z\=='┼'   then iterate
             le= substr(_   , k-1, 1)
             ri= substr(_   , k+1, 1)
             up= substr(old_, k  , 1)
             dw= substr(new_, k  , 1)
                    select
                    when le== .  & ri== .  & up=='│' & dw=="│"  then _= overlay('|', _, k)
                    when le=='~' & ri=="~" & up=='\' & dw=="\"  then _= overlay('═', _, k)
                    when le=='~' & ri=="~" & up=='\' & dw=="│"  then _= overlay('┬', _, k)
                    when le=='~' & ri=="~" & up=='│' & dw=="\"  then _= overlay('┴', _, k)
                    when le=='~' & ri== .  & up=='\' & dw=="\"  then _= overlay('═', _, k)
                    when le== .  & ri=="~" & up=='\' & dw=="\"  then _= overlay('═', _, k)
                    when le== .  & ri== .  & up=='│' & dw=="\"  then _= overlay('|', _, k)
                    when le== .  & ri== .  & up=='\' & dw=="│"  then _= overlay('|', _, k)
                    when le== .  & ri=="~" & up=='\' & dw=="│"  then _= overlay('┌', _, k)
                    when le== .  & ri=="~" & up=='│' & dw=="\"  then _= overlay('└', _, k)
                    when le=='~' & ri== .  & up=='\' & dw=="│"  then _= overlay('┐', _, k)
                    when le=='~' & ri== .  & up=='│' & dw=="\"  then _= overlay('┘', _, k)
                    when le=='~' & ri== .  & up=='│' & dw=="│"  then _= overlay('┤', _, k)
                    when le== .  & ri=="~" & up=='│' & dw=="│"  then _= overlay('├', _, k)
                    otherwise   nop
                    end   /*select*/
             end          /*k*/;                   return


real, dimension(n,m) :: a = reshape( [ (i, i=1, n*m) ], [ n, m ] )
real, dimension(m,k) :: b = reshape( [ (i, i=1, m*k) ], [ m, k ] )
real, dimension(size(a,1), size(b,2)) :: c    ! C is an array whose first dimension (row) size
                                              ! is the same as A's first dimension size, and
                                              ! whose second dimension (column) size is the same
                                              ! as B's second dimension size.

c = matmul( a, b )

print *, 'A'
do i = 1, n
    print *, a(i,:)
end do

print *,
print *, 'B'
do i = 1, m
    print *, b(i,:)
end do

print *,
print *, 'C = AB'
do i = 1, n
    print *, c(i,:)
end do


type Matrix
    dim as double m( any , any )
    declare constructor ( )
    declare constructor ( byval x as uinteger , byval y as uinteger )
end type

constructor Matrix ( )
end constructor

constructor Matrix ( byval x as uinteger , byval y as uinteger )
    redim this.m( x - 1 , y - 1 )
end constructor

operator * ( byref a as Matrix , byref b as Matrix ) as Matrix
    dim as Matrix ret
    dim as uinteger i, j, k
    if ubound( a.m , 2 ) = ubound( b.m , 1 ) and ubound( a.m , 1 ) = ubound( b.m , 2 ) then
        redim ret.m( ubound( a.m , 1 ) , ubound( b.m , 2 ) )
        for i = 0 to ubound( a.m , 1 )
            for j = 0 to ubound( b.m , 2 )
                for k = 0 to ubound( b.m , 1 )
                    ret.m( i , j ) += a.m( i , k ) * b.m( k , j )
                next k
            next j
        next i
    end if
    return ret
end operator

'some garbage matrices for demonstration
dim as Matrix a = Matrix(4 , 2)
a.m(0 , 0) = 1 : a.m(0 , 1) = 0
a.m(1 , 0) = 0 : a.m(1 , 1) = 1
a.m(2 , 0) = 2 : a.m(2 , 1) = 3
a.m(3 , 0) = 0.75 : a.m(3 , 1) = -0.5
dim as Matrix b = Matrix( 2 , 4 )
b.m(0 , 0) = 3.1 : b.m(0 , 1) = 1.6 : b.m(0 , 2) = -99 : b.m (0, 3) = -8
b.m(1 , 0) = 2.7 : b.m(1 , 1) = 0.6 : b.m(1 , 2) = 0 : b.m(1,3) = 21
dim as Matrix c = a * b
print c.m(0, 0), c.m(0, 1), c.m(0, 2), c.m(0, 3)
print c.m(1, 0), c.m(1, 1), c.m(1, 2), c.m(1, 3)
print c.m(2, 0), c.m(2, 1), c.m(2, 2), c.m(2, 3)
print c.m(3, 0), c.m(3, 1), c.m(3, 2), c.m(3, 3)


class Maze
  DIRECTIONS = [ [1, 0], [-1, 0], [0, 1], [0, -1] ]

  def initialize(width, height)
    @width   = width
    @height  = height
    @start_x = rand(width)
    @start_y = 0
    @end_x   = rand(width)
    @end_y   = height - 1

    # Which walls do exist? Default to "true". Both arrays are
    # one element bigger than they need to be. For example, the
    # @vertical_walls[x][y] is true if there is a wall between
    # (x,y) and (x+1,y). The additional entry makes printing easier.
    @vertical_walls   = Array.new(width) { Array.new(height, true) }
    @horizontal_walls = Array.new(width) { Array.new(height, true) }
    # Path for the solved maze.
    @path             = Array.new(width) { Array.new(height) }

    # "Hack" to print the exit.
    @horizontal_walls[@end_x][@end_y] = false

    # Generate the maze.
    generate
  end

  # Print a nice ASCII maze.
  def print
    # Special handling: print the top line.
    puts @width.times.inject("+") {|str, x| str << (x == @start_x ? "   +" : "---+")}

    # For each cell, print the right and bottom wall, if it exists.
    @height.times do |y|
      line = @width.times.inject("|") do |str, x|
        str << (@path[x][y] ? " * " : "   ") << (@vertical_walls[x][y] ? "|" : " ")
      end
      puts line

      puts @width.times.inject("+") {|str, x| str << (@horizontal_walls[x][y] ? "---+" : "   +")}
    end
  end

  private

  # Reset the VISITED state of all cells.
  def reset_visiting_state
    @visited = Array.new(@width) { Array.new(@height) }
  end

  # Is the given coordinate valid and the cell not yet visited?
  def move_valid?(x, y)
    (0[email protected]).cover?(x) && (0[email protected]).cover?(y) && [email protected][x][y]
  end

  # Generate the maze.
  def generate
    reset_visiting_state
    generate_visit_cell(@start_x, @start_y)
  end

  # Depth-first maze generation.
  def generate_visit_cell(x, y)
    # Mark cell as visited.
    @visited[x][y] = true

    # Randomly get coordinates of surrounding cells (may be outside
    # of the maze range, will be sorted out later).
    coordinates = DIRECTIONS.shuffle.map { |dx, dy| [x + dx, y + dy] }

    for new_x, new_y in coordinates
      next unless move_valid?(new_x, new_y)

      # Recurse if it was possible to connect the current and
      # the cell (this recursion is the "depth-first" part).
      connect_cells(x, y, new_x, new_y)
      generate_visit_cell(new_x, new_y)
    end
  end

  # Try to connect two cells. Returns whether it was valid to do so.
  def connect_cells(x1, y1, x2, y2)
    if x1 == x2
      # Cells must be above each other, remove a horizontal wall.
      @horizontal_walls[x1][ [y1, y2].min ] = false
    else
      # Cells must be next to each other, remove a vertical wall.
      @vertical_walls[ [x1, x2].min ][y1] = false
    end
  end
end

# Demonstration:
maze = Maze.new 20, 10
maze.print


matprod[a is array, b is array] :=
{
   c = makeArray[[length[a], length[[email protected]]], 0]

   a_row = length[a]-1
   a_col = length[[email protected]]-1
   b_col = length[b]-1

   for row = 0 to a_row
      for col = 0 to b_col
         for inc = 0 to a_col
            [email protected]@col = [email protected]@col + ([email protected]@inc * [email protected]@col)

   return c
}


fun main(x: [n][m]int, y: [m][p]int): [n][p]int =
  map (fn xr => map (fn yc => reduce (+) 0 (zipWith (*) xr yc))
                    (transpose y))
       x


use rand::{thread_rng, Rng, rngs::ThreadRng};

const WIDTH: usize = 16;
const HEIGHT: usize = 16;

#[derive(Clone, Copy)]
struct Cell {
    col: usize,
    row: usize,
}

impl Cell {
    fn from(col: usize, row: usize) -> Cell {
        Cell {col, row}
    }
}

struct Maze {
    cells: [[bool; HEIGHT]; WIDTH],         //cell visited/non visited
    walls_h: [[bool; WIDTH]; HEIGHT + 1],   //horizontal walls existing/removed
    walls_v: [[bool; WIDTH + 1]; HEIGHT],   //vertical walls existing/removed
    thread_rng: ThreadRng,                  //Random numbers generator
}

impl Maze {

    ///Inits the maze, with all the cells unvisited and all the walls active
    fn new() -> Maze {
        Maze {
            cells: [[true; HEIGHT]; WIDTH],
            walls_h: [[true; WIDTH]; HEIGHT + 1],
            walls_v: [[true; WIDTH + 1]; HEIGHT],
            thread_rng: thread_rng(),
        }
    }

    ///Randomly chooses the starting cell
    fn first(&mut self) -> Cell {
        Cell::from(self.thread_rng.gen_range(0, WIDTH), self.thread_rng.gen_range(0, HEIGHT))
    }

    ///Opens the enter and exit doors
    fn open_doors(&mut self) {
        let from_top: bool = self.thread_rng.gen();
        let limit = if from_top { WIDTH } else { HEIGHT };
        let door = self.thread_rng.gen_range(0, limit);
        let exit = self.thread_rng.gen_range(0, limit);
        if from_top {
            self.walls_h[0][door] = false;
            self.walls_h[HEIGHT][exit] = false;
        } else {
            self.walls_v[door][0] = false;
            self.walls_v[exit][WIDTH] = false;
        }
    }

    ///Removes a wall between the two Cell arguments
    fn remove_wall(&mut self, cell1: &Cell, cell2: &Cell) {
        if cell1.row == cell2.row {
            self.walls_v[cell1.row][if cell1.col > cell2.col { cell1.col } else { cell2.col }] = false;
        } else {
            self.walls_h[if cell1.row > cell2.row { cell1.row } else { cell2.row }][cell1.col] = false;
        };
    }

    ///Returns a random non-visited neighbor of the Cell passed as argument
    fn neighbor(&mut self, cell: &Cell) -> Option<Cell> {
        self.cells[cell.col][cell.row] = false;
        let mut neighbors = Vec::new();
        if cell.col > 0 && self.cells[cell.col - 1][cell.row] { neighbors.push(Cell::from(cell.col - 1, cell.row)); }
        if cell.row > 0 && self.cells[cell.col][cell.row - 1] { neighbors.push(Cell::from(cell.col, cell.row - 1)); }
        if cell.col < WIDTH - 1 && self.cells[cell.col + 1][cell.row] { neighbors.push(Cell::from(cell.col + 1, cell.row)); }
        if cell.row < HEIGHT - 1 && self.cells[cell.col][cell.row + 1] { neighbors.push(Cell::from(cell.col, cell.row + 1)); }
        if neighbors.is_empty() {
            None
        } else {
            let next = neighbors.get(self.thread_rng.gen_range(0, neighbors.len())).unwrap();
            self.remove_wall(cell, next);
            Some(*next)
        }
    }

    ///Builds the maze (runs the Depth-first search algorithm)
    fn build(&mut self) {
        let mut cell_stack: Vec<Cell> = Vec::new();
        let mut next = self.first();
        loop {
            while let Some(cell) = self.neighbor(&next) {
                cell_stack.push(cell);
                next = cell;
            }
            match cell_stack.pop() {
                Some(cell) => next = cell,
                None => break,
            }
        }
    }

    ///Displays a wall
    fn paint_wall(h_wall: bool, active: bool) {
        if h_wall {
            print!("{}", if active { "+---" } else { "+   " });
        } else {
            print!("{}", if active { "|   " } else { "    " });
        }
    }

    ///Displays a final wall for a row
    fn paint_close_wall(h_wall: bool) {
        if h_wall { println!("+") } else { println!() }
    }

    ///Displays a whole row of walls
    fn paint_row(&self, h_walls: bool, index: usize) {
        let iter = if h_walls { self.walls_h[index].iter() } else { self.walls_v[index].iter() };
        for &wall in iter {
            Maze::paint_wall(h_walls, wall);
        }
        Maze::paint_close_wall(h_walls);
    }

    ///Paints the maze
    fn paint(&self) {
        for i in 0 .. HEIGHT {
            self.paint_row(true, i);
            self.paint_row(false, i);
        }
        self.paint_row(true, HEIGHT);
    }
}

fn main() {
    let mut maze = Maze::new();
    maze.build();
    maze.open_doors();
    maze.paint();
}


import scala.util.Random

object MazeTypes {
  case class Direction(val dx: Int, val dy: Int)

  case class Loc(val x: Int, val y: Int) {
    def +(that: Direction): Loc = Loc(x + that.dx, y + that.dy)
  }

  case class Door(val from: Loc, to: Loc)

  val North = Direction(0,-1)
  val South = Direction(0,1)
  val West = Direction(-1,0)
  val East = Direction(1,0)
  val directions = Set(North, South, West, East)
}

object MazeBuilder {
  import MazeTypes._

  def shuffle[T](set: Set[T]): List[T] = Random.shuffle(set.toList)

  def buildImpl(current: Loc, grid: Grid): Grid = {
    var newgrid = grid.markVisited(current)
    val nbors = shuffle(grid.neighbors(current))
    nbors.foreach { n =>
      if (!newgrid.isVisited(n)) {
        newgrid = buildImpl(n, newgrid.markVisited(current).addDoor(Door(current, n)))
      }
    }
    newgrid
  }

  def build(width: Int, height: Int): Grid = {
    val exit = Loc(width-1, height-1)
    buildImpl(exit, new Grid(width, height, Set(), Set()))
  }
}

class Grid(val width: Int, val height: Int, val doors: Set[Door], val visited: Set[Loc]) {

  def addDoor(door: Door): Grid =
    new Grid(width, height, doors + door, visited)

  def markVisited(loc: Loc): Grid =
    new Grid(width, height, doors, visited + loc)

  def isVisited(loc: Loc): Boolean =
    visited.contains(loc)

  def neighbors(current: Loc): Set[Loc] =
    directions.map(current + _).filter(inBounds(_)) -- visited

  def printGrid(): List[String] = {
    (0 to height).toList.flatMap(y => printRow(y))
  }

  private def inBounds(loc: Loc): Boolean =
    loc.x >= 0 && loc.x < width && loc.y >= 0 && loc.y < height

  private def printRow(y: Int): List[String] = {
    val row = (0 until width).toList.map(x => printCell(Loc(x, y)))
    val rightSide = if (y == height-1) " " else "|"
    val newRow = row :+ List("+", rightSide)
    List.transpose(newRow).map(_.mkString)
  }

  private val entrance = Loc(0,0)

  private def printCell(loc: Loc): List[String] = {
    if (loc.y == height)
      List("+--")
    else List(
      if (openNorth(loc)) "+  " else "+--",
      if (openWest(loc) || loc == entrance) "   " else "|  "
    )
  }

  def openNorth(loc: Loc): Boolean = openInDirection(loc, North)

  def openWest(loc: Loc): Boolean = openInDirection(loc, West)

  private def openInDirection(loc: Loc, dir: Direction): Boolean =
    doors.contains(Door(loc, loc + dir)) || doors.contains(Door(loc + dir, loc))
}


generic coordinaat
{
 ecs
 uuii

 coordinaat() { ecs=+a uuii=+a}

 coordinaat(ecs_set uuii_set) { ecs = ecs_set uuii=uuii_set }

 operaator<(c)
 {
   iph ecs < c.ecs return troo
   iph c.ecs < ecs return phals
   iph uuii < c.uuii return troo
   return phals
 }

 operaator==(connpair) // eecuuols and not eecuuols deriiu phronn operaator<
 {
   iph this < connpair return phals
   iph connpair < this return phals
   return troo
 }

 operaator!=(connpair)
 {
   iph this < connpair return troo
   iph connpair < this return troo
   return phals
 }

 too_string()
 {
     return "(" + ecs.too_string() + "," + uuii.too_string() + ")"
 }

 print()
 {
   str = too_string()
   str.print()
 }

 println()
 {
   str = too_string()
   str.println()
 }
}

generic nnaatrics
{
  s         // this is a set of coordinaat/ualioo pairs.
  iteraator // this field holds an iteraator phor the nnaatrics.

  nnaatrics()   // no parameters required phor nnaatrics construction.
  {
   s = nioo set()   // create a nioo set of coordinaat/ualioo pairs.
   iteraator = nul // the iteraator is initially set to nul.
  }

  nnaatrics(copee)   // copee the nnaatrics.
  {
   s = nioo set()   // create a nioo set of coordinaat/ualioo pairs.
   iteraator = nul // the iteraator is initially set to nul.

   r = copee.rouus
   c = copee.cols
   i = 0
   uuiil i < r
   {
     j = 0
     uuiil j < c
     {
        this[i j] = copee[i j]
       j++
     }
     i++
   }
  }

  begin { get { return s.begin } } // property: used to commence manual iteraashon.

  end { get { return s.end } } // property: used to dephiin the end itenn of iteraashon

  operaator<(a) // les than operaator is corld bii the avl tree algorithnns
  {             // this operaator innpliis phor instance that you could potenshalee hav sets ou nnaatricss.
    iph cees < a.cees  // connpair the cee sets phurst.
       return troo
    els iph a.cees < cees
       return phals
    els                // the cee sets are eecuuol thairphor connpair nnaatrics elennents.
    {
     phurst1 = begin
     lahst1 = end
     phurst2 = a.begin
     lahst2 = a.end

     uuiil phurst1 != lahst1 && phurst2 != lahst2
     {
       iph phurst1.daata.ualioo < phurst2.daata.ualioo
        return troo
       els
       {
         iph phurst2.daata.ualioo < phurst1.daata.ualioo
          return phals
         els
         {
            phurst1 = phurst1.necst
            phurst2 = phurst2.necst
         }
       }
     }

     return phals
    }
  }

    operaator==(connpair) // eecuuols and not eecuuols deriiu phronn operaator<
    {
     iph this < connpair return phals
     iph connpair < this return phals
     return troo
    }

    operaator!=(connpair)
    {
     iph this < connpair return troo
     iph connpair < this return troo
     return phals
    }

   operaator[cee_a cee_b] // this is the nnaatrics indexer.
   {
       set
       {
           trii { s >> nioo cee_ualioo(new coordinaat(cee_a cee_b)) } catch {}
           s << nioo cee_ualioo(new coordinaat(nioo integer(cee_a) nioo integer(cee_b)) ualioo)
       }
       get
       {
          d = s.get(nioo cee_ualioo(new coordinaat(cee_a cee_b)))
          return d.ualioo
       }
   }

  operaator>>(coordinaat) // this operaator reennoous an elennent phronn the nnaatrics.
  {
   s >> nioo cee_ualioo(coordinaat)
   return this
  }

  iteraat() // and this is how to iterate on the nnaatrics.
  {
      iph iteraator.nul()
      {
         iteraator = s.lepht_nnohst
         iph iteraator == s.heder
             return nioo iteraator(phals nioo nun())
         els
             return nioo iteraator(troo iteraator.daata.ualioo)
      }
      els
      {
         iteraator = iteraator.necst

         iph iteraator == s.heder
         {
             iteraator = nul
             return nioo iteraator(phals nioo nun())
         }
         els
             return nioo iteraator(troo iteraator.daata.ualioo)
      }
   }

   couunt // this property returns a couunt ou elennents in the nnaatrics.
   {
      get
      {
         return s.couunt
      }
   }

   ennptee // is the nnaatrics ennptee?
   {
       get
       {
           return s.ennptee
       }
   }

   lahst // returns the ualioo of the lahst elennent in the nnaatrics.
   {
       get
       {
           iph ennptee
                 throuu "ennptee nnaatrics"
           els
               return s.lahst.ualioo
       }
   }

    too_string() // conuerts the nnaatrics too aa string
    {
       return s.too_string()
    }

    print() // prints the nnaatrics to the consohl.
    {
        out = too_string()
        out.print()
    }

   println() // prints the nnaatrics as a liin too the consohl.
    {
        out = too_string()
        out.println()
    }

   cees // return the set ou cees ou the nnaatrics (a set of coordinaats).
   {
      get
      {
          k = nioo set()
          phor e : s k << e.cee
          return k
      }
   }

  operaator+(p)
  {
     ouut = nioo nnaatrics()
     phurst1 = begin
     lahst1 = end
     phurst2 = p.begin
     lahst2 = p.end
     uuiil phurst1 != lahst1 && phurst2 != lahst2
     {
        ouut[phurst1.daata.cee.ecs phurst1.daata.cee.uuii] = phurst1.daata.ualioo + phurst2.daata.ualioo
        phurst1 = phurst1.necst
        phurst2 = phurst2.necst
     }
     return ouut
  }

  operaator-(p)
  {
     ouut = nioo nnaatrics()
     phurst1 = begin
     lahst1 = end
     phurst2 = p.begin
     lahst2 = p.end
     uuiil phurst1 != lahst1 && phurst2 != lahst2
     {
        ouut[phurst1.daata.cee.ecs phurst1.daata.cee.uuii] = phurst1.daata.ualioo - phurst2.daata.ualioo
        phurst1 = phurst1.necst
        phurst2 = phurst2.necst
     }
     return ouut
  }

  rouus
  {
     get
     {
        r = +a
        phurst1 = begin
        lahst1 = end
        uuiil phurst1 != lahst1
        {
            iph r < phurst1.daata.cee.ecs r = phurst1.daata.cee.ecs
            phurst1 = phurst1.necst
        }
        return r + +b
     }
  }

  cols
  {
     get
     {
        c = +a
        phurst1 = begin
        lahst1 = end
        uuiil phurst1 != lahst1
        {
            iph c < phurst1.daata.cee.uuii c = phurst1.daata.cee.uuii
            phurst1 = phurst1.necst
        }
        return c + +b
     }
  }

  operaator*(o)
  {
      iph cols != o.rouus throw "rouus-cols nnisnnatch"
      reesult = nioo nnaatrics()
      rouu_couunt = rouus
      colunn_couunt = o.cols
      loop = cols
      i = +a
      uuiil i < rouu_couunt
      {
        g = +a
        uuiil g < colunn_couunt
        {
           sunn = +a.a
           h = +a
           uuiil h < loop
           {
             a = this[i  h]

             b = o[h  g]
             nn = a * b
             sunn = sunn +  nn
             h++
           }

            reesult[i  g] = sunn

            g++
         }
        i++
     }
     return reesult
 }

  suuop_rouus(a  b)
  {
    c = cols
    i = 0
    uuiil u < cols
    {
      suuop = this[a  i]
      this[a  i] = this[b  i]
      this[b  i] = suuop
      i++
    }
  }

  suuop_colunns(a  b)
  {
    r = rouus
    i = 0
    uuiil i < rouus
    {
     suuopp = this[i  a]
     this[i  a] = this[i  b]
     this[i  b] = suuop
     i++
    }
  }

  transpohs
  {
     get
     {
         reesult = new nnaatrics()

         r = rouus
         c = cols
         i=0
         uuiil i < r
         {
              g = 0
              uuiil g < c
              {
                 reesult[g  i] = this[i  g]
                 g++
              }
             i++
         }

         return reesult
      }
   }

   deternninant
   {
        get
        {
            rouu_couunt = rouus
            colunn_count = cols

            if rouu_couunt != colunn_count
                throw "not a scuuair nnaatrics"

            if rouu_couunt == 0
               throw "the nnaatrics is ennptee"

            if rouu_couunt == 1
               return this[0  0]

            if rouu_couunt == 2
                return this[0  0] * this[1  1] -
                       this[0  1] * this[1  0]

            temp = nioo nnaatrics()

            det = 0.0
            parity = 1.0

            j = 0
            uuiil j < rouu_couunt
            {
                 k = 0
                 uuiil k < rouu_couunt-1
                 {
                      skip_col = phals

                      l = 0
                      uuiil l < rouu_couunt-1
                      {
                           if l == j skip_col = troo

                           if skip_col
                               n = l + 1
                           els
                               n = l

                            temp[k  l] = this[k + 1  n]
                            l++
                       }
                       k++
                  }

                  det = det + parity * this[0  j] * temp.deeternninant

                  parity = 0.0 - parity
                  j++
            }

        return det
      }
  }

   ad_rouu(a  b)
   {
       c = cols
       i = 0
       uuiil i < c
       {
         this[a  i] = this[a  i] + this[b  i]
         i++
        }
   }

   ad_colunn(a  b)
   {
       c = rouus
       i = 0
       uuiil i < c
       {
         this[i  a] = this[i  a] + this[i  b]
         i++
        }
   }

   subtract_rouu(a  b)
   {
       c = cols
       i = 0
       uuiil i < c
       {
         this[a  i] = this[a  i] - this[b  i]
         i++
        }
   }

   subtract_colunn(a  b)
   {
       c = rouus
       i = 0
       uuiil i < c
       {
         this[i  a] = this[i  a] - this[i  b]
         i++
        }
   }

   nnultiplii_rouu(rouu  scalar)
   {
       c = cols
       i = 0
       uuiil i < c
       {
          this[rouu  i] = this[rouu  i] * scalar
           i++
       }
   }

   nnultiplii_colunn(colunn  scalar)
   {
       r = rouus
       i = 0
       uuiil i < r
       {
          this[i  colunn] = this[i  colunn] * scalar
           i++
       }
   }

   diuiid_rouu(rouu  scalar)
   {
       c = cols
       i = 0
       uuiil i < c
       {
          this[rouu  i] = this[rouu  i] / scalar
           i++
       }
   }

   diuiid_colunn(colunn  scalar)
   {
       r = rouus
       i = 0
       uuiil i < r
       {
          this[i  colunn] = this[i  colunn] / scalar
           i++
       }
   }

   connbiin_rouus_ad(a b phactor)
   {
       c = cols
       i = 0
       uuiil i < c
       {
          this[a  i] = this[a  i] + phactor * this[b  i]
          i++
       }
    }

   connbiin_rouus_subtract(a b phactor)
   {
       c = cols
       i = 0
       uuiil i < c
       {
          this[a  i] = this[a  i] - phactor * this[b  i]
          i++
       }
    }

   connbiin_colunns_ad(a b phactor)
   {
       r = rouus
       i = 0
       uuiil i < r
       {
          this[i  a] = this[i  a] + phactor * this[i  b]
          i++
       }
    }

   connbiin_colunns_subtract(a b phactor)
   {
       r = rouus
       i = 0
       uuiil i < r
       {
          this[i  a] = this[i  a] - phactor * this[i  b]
          i++
       }
    }

    inuers
    {
        get
        {
            rouu_couunt = rouus
            colunn_couunt = cols

            iph rouu_couunt != colunn_couunt
                throw "nnatrics not scuuair"

            els iph rouu_couunt == 0
                throw "ennptee nnatrics"

            els iph rouu_couunt == 1
            {
                r = nioo nnaatrics()
                r[0  0] = 1.0 / this[0  0]
                return r
            }

            gauss = nioo nnaatrics(this)

            i = 0
            uuiil i < rouu_couunt
            {
                 j = 0
                 uuiil j < rouu_couunt
                 {
                       iph i == j

                            gauss[i  j + rouu_couunt] = 1.0
                        els
                            gauss[i  j + rouu_couunt] = 0.0
                      j++
                 }

                 i++
             }

              j = 0
              uuiil j < rouu_couunt
              {
                 iph gauss[j  j] == 0.0
                 {
                      k = j + 1

                      uuiil k < rouu_couunt
                      {
                          if gauss[k  j] != 0.0 {gauss.nnaat.suuop_rouus(j  k) break }
                           k++
                       }

                       if k == rouu_couunt throw "nnatrics is singioolar"
                 }

                 phactor = gauss[j  j]
                 iph phactor != 1.0 gauss.diuiid_rouu(j  phactor)

                 i = j+1
                 uuiil i < rouu_couunt
                 {
                     gauss.connbiin_rouus_subtract(i  j  gauss[i  j])
                     i++
                  }

                 j++
              }

              i = rouu_couunt - 1
              uuiil i > 0
              {
                  k = i - 1
                  uuiil k >= 0
                  {
                      gauss.connbiin_rouus_subtract(k  i  gauss[k  i])
                      k--
                  }
                  i--
              }

               reesult = nioo nnaatrics()

                i = 0
                uuiil i < rouu_couunt
                {
                     j = 0
                     uuiil  j < rouu_couunt
                     {
                         reesult[i  j] = gauss[i  j + rouu_couunt]
                         j++
                     }
                    i++
                }

              return reesult
            }
        }

}


var(w:5, h:5) = ARGV.map{.to_i}...
var avail = (w * h)

# cell is padded by sentinel col and row, so I don't check array bounds
var cell = (1..h -> map {([true] * w) + [false]} + [[false] * w+1])
var ver  = (1..h -> map {["|  "] * w })
var hor  = (0..h -> map {["+--"] * w })

func walk(x, y) {
    cell[y][x] = false;
    avail-- > 0 || return;  # no more bottles, er, cells

    var d = [[-1, 0], [0, 1], [1, 0], [0, -1]]
    while (!d.is_empty) {
        var i = d.pop_rand
        var (x1, y1) = (x + i[0], y + i[1])

        cell[y1][x1] || next

        if (x == x1) { hor[[y1, y].max][x] = '+  ' }
        if (y == y1) { ver[y][[x1, x].max] = '   ' }
        walk(x1, y1)
    }
}

walk(w.rand.int, h.rand.int)   # generate

for i in (0 .. h) {
    say (hor[i].join('') + '+')
    if (i < h) {
        say (ver[i].join('') + '|')
    }
}


package main

import (
    "fmt"

    "gonum.org/v1/gonum/mat"
)

func main() {
    a := mat.NewDense(2, 4, []float64{
        1, 2, 3, 4,
        5, 6, 7, 8,
    })
    b := mat.NewDense(4, 3, []float64{
        1, 2, 3,
        4, 5, 6,
        7, 8, 9,
        10, 11, 12,
    })
    var m mat.Dense
    m.Mul(a, b)
    fmt.Println(mat.Formatted(&m))
}


def assertConformable = { a, b ->
    assert a instanceof List
    assert b instanceof List
    assert a.every { it instanceof List && it.size() == b.size() }
    assert b.every { it instanceof List && it.size() == b[0].size() }
}

def matmulWOIL = { a, b ->
    assertConformable(a, b)

    def bt = b.transpose()
    a.collect { ai ->
        bt.collect { btj ->
            [ai, btj].transpose().collect { it[0] * it[1] }.sum()
        }
    }
}