"""Display an outline as a nested table. Requires Python >=3.6."""

import itertools
import re
import sys

from collections import deque
from typing import NamedTuple

RE_OUTLINE = re.compile(r"^((?: |\t)*)(.+)$", re.M)

COLORS = itertools.cycle(
    [
        "#ffffe6",
        "#ffebd2",
        "#f0fff0",
        "#e6ffff",
        "#ffeeff",
    ]
)

class Node:
    def __init__(self, indent, value, parent, children=None):
        self.indent = indent
        self.value = value
        self.parent = parent
        self.children = children or []

        self.color = None

    def depth(self):
        if self.parent:
            return self.parent.depth() + 1
        return -1

    def height(self):
        """Height of the subtree rooted at this node."""
        if not self.children:
            return 0
        return max(child.height() for child in self.children) + 1

    def colspan(self):
        if self.leaf:
            return 1
        return sum(child.colspan() for child in self.children)

    @property
    def leaf(self):
        return not bool(self.children)

    def __iter__(self):
        # Level order tree traversal.
        q = deque()
        q.append(self)
        while q:
            node = q.popleft()
            yield node
            q.extend(node.children)

class Token(NamedTuple):
    indent: int
    value: str

def tokenize(outline):
    """Generate ``Token``s from the given outline."""
    for match in RE_OUTLINE.finditer(outline):
        indent, value = match.groups()
        yield Token(len(indent), value)

def parse(outline):
    """Return the given outline as a tree of ``Node``s."""
    # Split the outline into lines and count the level of indentation.
    tokens = list(tokenize(outline))

    # Parse the tokens into a tree of nodes.
    temp_root = Node(-1, "", None)
    _parse(tokens, 0, temp_root)

    # Pad the tree so that all branches have the same depth.
    root = temp_root.children[0]
    pad_tree(root, root.height())

    return root

def _parse(tokens, index, node):
    """Recursively build a tree of nodes.

    Args:
        tokens (list): A collection of ``Token``s.
        index (int): Index of the current token.
        node (Node): Potential parent or sibling node.
    """
    # Base case. No more lines.
    if index >= len(tokens):
        return

    token = tokens[index]

    if token.indent == node.indent:
        # A sibling of node
        current = Node(token.indent, token.value, node.parent)
        node.parent.children.append(current)
        _parse(tokens, index + 1, current)

    elif token.indent > node.indent:
        # A child of node
        current = Node(token.indent, token.value, node)
        node.children.append(current)
        _parse(tokens, index + 1, current)

    elif token.indent < node.indent:
        # Try the node's parent until we find a sibling.
        _parse(tokens, index, node.parent)

def pad_tree(node, height):
    """Pad the tree with blank nodes so all branches have the same depth."""
    if node.leaf and node.depth() < height:
        pad_node = Node(node.indent + 1, "", node)
        node.children.append(pad_node)

    for child in node.children:
        pad_tree(child, height)

def color_tree(node):
    """Walk the tree and color each node as we go."""
    if not node.value:
        node.color = "#F9F9F9"
    elif node.depth() <= 1:
        node.color = next(COLORS)
    else:
        node.color = node.parent.color

    for child in node.children:
        color_tree(child)

def table_data(node):
    """Return an HTML table data element for the given node."""
    indent = "    "

    if node.colspan() > 1:
        colspan = f'colspan="{node.colspan()}"'
    else:
        colspan = ""

    if node.color:
        style = f'style="background-color: {node.color};"'
    else:
        style = ""

    attrs = " ".join([colspan, style])
    return f"{indent}{node.value}	"

def html_table(tree):
    """Return the tree as an HTML table."""
    # Number of columns in the table.
    table_cols = tree.colspan()

    # Running count of columns in the current row.
    row_cols = 0

    # HTML buffer
    buf = ["
"]

    # Breadth first iteration.
    for node in tree:
        if row_cols == 0:
            buf.append("
")

        buf.append(table_data(node))
        row_cols += node.colspan()

        if row_cols == table_cols:
            buf.append("
")
            row_cols = 0

    buf.append("
")
    return "\n".join(buf)

def wiki_table_data(node):
    """Return an wiki table data string for the given node."""
    if not node.value:
        return "|  |"

    if node.colspan() > 1:
        colspan = f"colspan={node.colspan()}"
    else:
        colspan = ""

    if node.color:
        style = f'style="background: {node.color};"'
    else:
        style = ""

    attrs = " ".join([colspan, style])
    return f"| {attrs} | {node.value}"

def wiki_table(tree):
    """Return the tree as a wiki table."""
    # Number of columns in the table.
    table_cols = tree.colspan()

    # Running count of columns in the current row.
    row_cols = 0

    # HTML buffer
    buf = ['{| class="wikitable" style="text-align: center;"']

    for node in tree:
        if row_cols == 0:
            buf.append("|-")

        buf.append(wiki_table_data(node))
        row_cols += node.colspan()

        if row_cols == table_cols:
            row_cols = 0

    buf.append("|}")
    return "\n".join(buf)

def example(table_format="wiki"):
    """Write an example table to stdout in either HTML or Wiki format."""

    outline = (
        "Display an outline as a nested table.\n"
        "    Parse the outline to a tree,\n"
        "        measuring the indent of each line,\n"
        "        translating the indentation to a nested structure,\n"
        "        and padding the tree to even depth.\n"
        "    count the leaves descending from each node,\n"
        "        defining the width of a leaf as 1,\n"
        "        and the width of a parent node as a sum.\n"
        "            (The sum of the widths of its children)\n"
        "    and write out a table with 'colspan' values\n"
        "        either as a wiki table,\n"
        "        or as HTML."
    )

    tree = parse(outline)
    color_tree(tree)

    if table_format == "wiki":
        print(wiki_table(tree))
    else:
        print(html_table(tree))

if __name__ == "__main__":
    args = sys.argv[1:]

    if len(args) == 1:
        table_format = args[0]
    else:
        table_format = "wiki"

    example(table_format)


#include<stdlib.h>
#include<stdio.h>
#include<math.h> /*Optional, but better if included as fabs, labs and abs functions are being used. */

int main(int argC, char* argV[])
{

	int i,zeroCount= 0,firstNonZero = -1;
	double* vector;

	if(argC == 1){
		printf("Usage : %s <Vector component coefficients seperated by single space>",argV[0]);
	}

	else{

		printf("Vector for [");
		for(i=1;i<argC;i++){
			printf("%s,",argV[i]);
		}
		printf("\b] -> ");

		vector = (double*)malloc((argC-1)*sizeof(double));

		for(i=1;i<=argC;i++){
			vector[i-1] = atof(argV[i]);
			if(vector[i-1]==0.0)
				zeroCount++;
			if(vector[i-1]!=0.0 && firstNonZero==-1)
				firstNonZero = i-1;
		}

		if(zeroCount == argC){
			printf("0");
		}

		else{
			for(i=0;i<argC;i++){
				if(i==firstNonZero && vector[i]==1)
					printf("e%d ",i+1);
				else if(i==firstNonZero && vector[i]==-1)
					printf("- e%d ",i+1);
				else if(i==firstNonZero && vector[i]<0 && fabs(vector[i])-abs(vector[i])>0.0)
					printf("- %lf e%d ",fabs(vector[i]),i+1);
				else if(i==firstNonZero && vector[i]<0 && fabs(vector[i])-abs(vector[i])==0.0)
					printf("- %ld e%d ",labs(vector[i]),i+1);
				else if(i==firstNonZero && vector[i]>0 && fabs(vector[i])-abs(vector[i])>0.0)
					printf("%lf e%d ",vector[i],i+1);
				else if(i==firstNonZero && vector[i]>0 && fabs(vector[i])-abs(vector[i])==0.0)
					printf("%ld e%d ",vector[i],i+1);
				else if(fabs(vector[i])==1.0 && i!=0)
					printf("%c e%d ",(vector[i]==-1)?'-':'+',i+1);
				else if(i!=0 && vector[i]!=0 && fabs(vector[i])-abs(vector[i])>0.0)
					printf("%c %lf e%d ",(vector[i]<0)?'-':'+',fabs(vector[i]),i+1);
				else if(i!=0 && vector[i]!=0 && fabs(vector[i])-abs(vector[i])==0.0)
					printf("%c %ld e%d ",(vector[i]<0)?'-':'+',labs(vector[i]),i+1);
			}
		}
	}

	free(vector);

	return 0;
}


Shoes.app(:width=>205, :height => 228, :title => "A Clock") do
  def draw_ray(width, start, stop, ratio)
    angle = Math::PI * 2 * ratio - Math::PI/2
    strokewidth width
    cos = Math::cos(angle)
    sin = Math::sin(angle)
    line 101+cos*start, 101+sin*start, 101+cos*stop, 101+sin*stop
  end

  def update
    t = Time.now
    @time.text = t.strftime("%H:%M:%S")
    h, m, s = (t.hour % 12).to_f, t.min.to_f, t.sec.to_f
    s += t.to_f - t.to_i  # add the fractional seconds

    @hands.clear do
      draw_ray(3, 0, 70, (h + m/60)/12)
      draw_ray(2, 0, 90, (m + s/60)/60)
      draw_ray(1, 0, 95, s/60)
    end
  end

  # a place for the text display
  @time = para(:align=>"center", :family => "monospace")

  # draw the clock face
  stack(:width=>203, :height=>203) do
    strokewidth 1
    fill gradient(deepskyblue, aqua)
    oval 1, 1, 200
    fill black
    oval 98, 98, 6
    # draw the minute indicators
    0.upto(59) {|m| draw_ray(1, (m % 5 == 0 ? 96 : 98), 100, m.to_f/60)}
  end.move(0,23)

  # the drawing area for the hands
  @hands = stack(:width=>203, :height=>203) {}.move(0,23)

  animate(5) {update}
end


MODULE DotProduct;
IMPORT StdLog;

PROCEDURE Calculate*(x,y: ARRAY OF INTEGER): INTEGER;
VAR
	i,sum: INTEGER;
BEGIN
	sum := 0;
	FOR i:= 0 TO LEN(x) - 1 DO
		INC(sum,x[i] * y[i]);
	END;
	RETURN sum
END Calculate;

PROCEDURE Test*;
VAR
	i,sum: INTEGER;
	v1,v2: ARRAY 3 OF INTEGER;
BEGIN
	v1[0] := 1;v1[1] := 3;v1[2] := -5;
	v2[0] := 4;v2[1] := -2;v2[2] := -1;

	StdLog.Int(Calculate(v1,v2));StdLog.Ln
END Test;

END DotProduct.


include "cowgol.coh";

sub dotproduct(a: [int32], b: [int32], len: intptr): (n: int32) is
    n := 0;
    while len > 0 loop
        n := n + [a] * [b];
        a := @next a;
        b := @next b;
        len := len - 1;
    end loop;
end sub;

sub printsgn(n: int32) is
    if n<0 then
        print_char('-');
        n := -n;
    end if;
    print_i32(n as uint32);
end sub;

var A: int32[] := {1, 3, -5};
var B: int32[] := {4, -2, -1};

printsgn(dotproduct(&A[0], &B[0], @sizeof A));
print_nl();


{def dcr
 {lambda {:step :length}
  {let { {:step {- :step 1}}
         {:length {/ :length 1.41421}}
       } {if {> :step 0}
          then T45
               {dcr :step :length}
               T-90
               {dcl :step :length}
               T45
          else T45
               M:length
               T-90
               M:length
               T45}
}}}
-> dcr

{def dcl
 {lambda {:step :length}
  {let { {:step {- :step 1}}
         {:length {/ :length 1.41421}}
       } {if {> :step 0}
          then T-45
               {dcr :step :length}
               T90
               {dcl :step :length}
               T-45
          else T-45
               M:length
               T90
               M:length
               T-45}
}}}
-> dcl


nomainwin
    mainwin 50 20

    WindowHeight =620
    WindowWidth  =690

    open "Graphics library" for graphics as #a

    #a, "trapclose [quit]"

    #a "down"

    Turn$ ="R"
    Pace  =100
    s     = 16

[again]
    print Turn$

    #a "cls ; home ; north ; down ; fill black"

    for i =1 to len( Turn$)
        v =255 *i /len( Turn$)
        #a "color "; v; " 120 "; 255 -v
        #a "go "; Pace
        if mid$(  Turn$, i, 1) ="R" then #a "turn 90" else #a "turn -90"
    next i

    #a "color 255 120 0"
    #a "go "; Pace
    #a "flush"

    FlippedTurn$ =""
    for i =len( Turn$) to 1 step -1
        if mid$( Turn$, i, 1) ="R" then FlippedTurn$ =FlippedTurn$ +"L" else FlippedTurn$ =FlippedTurn$ +"R"
    next i

    Turn$ =Turn$ +"R" +FlippedTurn$

    Pace  =Pace /1.35

    scan

    timer 1000, [j]
    wait
[j]
    timer 0

    if len( Turn$) <40000 then goto [again]

wait

[quit]
    close #a
    end


my $outline = q:to/END/;
    Display an outline as a nested table.
        Parse the outline to a tree,
            measuring the indent of each line,
            translating the indentation to a nested structure,
            and padding the tree to even depth.
        count the leaves descending from each node,
            defining the width of a leaf as 1,
            and the width of a parent node as a sum.
                (The sum of the widths of its children)
                Propagating the sums upward as necessary.
        and write out a table with 'colspan' values
            either as a wiki table,
            or as HTML.
        Optionally add color to the nodes.
    END

# Import outline paragraph into native data structure
sub import (Str $trees, $level = '  ') {
    my $forest;
    my $last = -Inf;

    for $trees.lines -> $branch {
        $branch ~~ / ($($level))* /;
        my $this = +$0;
        $forest ~= do {
            given $this cmp $last {
                when More { "\['{esc $branch.trim}', " }
                when Same { "'{esc $branch.trim}', " }
                when Less { "{']' x $last - $this}, '{esc $branch.trim}', " }
            }
        }
        $last = $this;
    }

    sub esc { $^s.subst( /(<['\\]>)/, -> $/ { "\\$0" }, :g) }

    $forest ~= ']' x 1 + $last;
    use MONKEY-SEE-NO-EVAL;
    $forest.EVAL;
}

my @AoA = import $outline, '    ';
my @layout;

# Collect information about node depth, position and children
{
    my @width = 0;
    my $depth = -1;
    @AoA.&insert;

    multi insert ($item) {
        @width[*-1]++;
        @layout.push: { :depth($depth.clone), :id(@width[*-1].clone), :text($item) };
    }

    multi insert (@array) {
        @width.push: @width[*-1] * 10;
        ++$depth;
        @array.map: &insert;
        --$depth;
        @width.pop;
    }
}

my $max-depth = @layout.max( *.<depth> )<depth>;

# Pad ragged nodes
for (^$max-depth) -> $d {
    my @nodes = @layout.grep( *.<depth> == $d );
    for @nodes.sort( +*.<id> ) -> $n {
        unless @layout.first( *.<id> == $n<id> ~ 1 ) {
            @layout.push: { :depth($n<depth> + 1), :id($n<id> *10 + 1), :text('') };
        }
    }
}

# Calculate spans (child nodes)
for (0..$max-depth).reverse -> $d {
    my @nodes = @layout.grep( *.<depth> == $d );
    for @nodes.sort( +*.<id> ) -> $n {
        my @span = @layout.grep: {.<depth> == $d + 1 && .<id>.starts-with: $n<id> };
        $n = ( sum @span.map( { . // 0} )) || +@span || 1;
    }
}

# Programatically assign colors
for (0..$max-depth) -> $d {
    my @nodes = @layout.grep( *.<depth> == $d );
    my $incr = 1 / (1 + @nodes);
    for @nodes.sort( +*.<id> ) -> $n {
        my $color = $d > 1 ??
        @layout.first( *.<id> eq $n<id>.chop )<color> !!
        "style=\"background: #" ~ hsv2rgb( ++$ * $incr, .1, 1) ~ '" ';
        $n<color> = $n<text> ?? $color !! '';
    }
}

# Generate wikitable
say '{| class="wikitable" style="text-align: center;"' ~ "\n" ~
(join "\n|-\n", (0..$max-depth).map: -> $d {
    my @nodes = @layout.grep( *.<depth> == $d );
    (join "\n", @nodes.sort( +*.<id> ).map( -> $node {
        '| ' ~
        ($node<color> // '' ) ~
        ($node > 1 ?? "colspan=$node" !! '' ) ~
        ' | ' ~ $node<text> }
    ))
}) ~ "\n|}";

say "\n\nSometimes it makes more sense to display an outline as...
well... as an outline, rather than as a table." ~ Q|¯\_(ツ)_/¯| ~ "\n";

{ ## Outline - Ordered List #######
    my @type = <upper-roman upper-latin decimal lower-latin lower-roman>;
    my $depth = 0;

    multi ol ($item) { "\
$item\n" }

    multi ol (@array) {
        my $li = $depth ?? "
" !! '';
        $depth++;
        my $list = "
\n" ~
        ( @array.map( &ol ).join ) ~ "
$li\n";
        $depth--;
        $list
    }

    say "
\n" ~ @AoA.&ol ~ "
";
}

sub hsv2rgb ( $h, $s, $v ){
    my $c = $v * $s;
    my $x = $c * (1 - abs( (($h*6) % 2) - 1 ) );
    my $m = $v - $c;
    my ($r, $g, $b) = do given $h {
        when   0..^(1/6) { $c, $x, 0 }
        when 1/6..^(1/3) { $x, $c, 0 }
        when 1/3..^(1/2) { 0, $c, $x }
        when 1/2..^(2/3) { 0, $x, $c }
        when 2/3..^(5/6) { $x, 0, $c }
        when 5/6..1      { $c, 0, $x }
    }
    ( $r, $g, $b ).map( ((*+$m) * 255).Int)».base(16).join
}


using System;
using System.Collections.Generic;
using System.Text;

namespace DisplayLinearCombination {
    class Program {
        static string LinearCombo(List<int> c) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < c.Count; i++) {
                int n = c[i];
                if (n < 0) {
                    if (sb.Length == 0) {
                        sb.Append('-');
                    } else {
                        sb.Append(" - ");
                    }
                } else if (n > 0) {
                    if (sb.Length != 0) {
                        sb.Append(" + ");
                    }
                } else {
                    continue;
                }

                int av = Math.Abs(n);
                if (av != 1) {
                    sb.AppendFormat("{0}*", av);
                }
                sb.AppendFormat("e({0})", i + 1);
            }
            if (sb.Length == 0) {
                sb.Append('0');
            }
            return sb.ToString();
        }

        static void Main(string[] args) {
            List<List<int>> combos = new List<List<int>>{
                new List<int> { 1, 2, 3},
                new List<int> { 0, 1, 2, 3},
                new List<int> { 1, 0, 3, 4},
                new List<int> { 1, 2, 0},
                new List<int> { 0, 0, 0},
                new List<int> { 0},
                new List<int> { 1, 1, 1},
                new List<int> { -1, -1, -1},
                new List<int> { -1, -2, 0, -3},
                new List<int> { -1},
            };

            foreach (List<int> c in combos) {
                var arr = "[" + string.Join(", ", c) + "]";
                Console.WriteLine("{0,15} -> {1}", arr, LinearCombo(c));
            }
        }
    }
}


// cargo-deps: time="0.1"
extern crate time;

use std::thread;
use std::time::Duration;

const TOP: &str = " ⡎⢉⢵ ⠀⢺⠀ ⠊⠉⡱ ⠊⣉⡱ ⢀⠔⡇ ⣏⣉⡉ ⣎⣉⡁ ⠊⢉⠝ ⢎⣉⡱ ⡎⠉⢱ ⠀⠶⠀";
const BOT: &str = " ⢗⣁⡸ ⢀⣸⣀ ⣔⣉⣀ ⢄⣀⡸ ⠉⠉⡏ ⢄⣀⡸ ⢇⣀⡸ ⢰⠁⠀ ⢇⣀⡸ ⢈⣉⡹ ⠀⠶⠀";

fn main() {
    let top: Vec<&str> = TOP.split_whitespace().collect();
    let bot: Vec<&str> = BOT.split_whitespace().collect();

    loop {
        let tm = &time::now().rfc822().to_string()[17..25];
        let top_str: String = tm.chars().map(|x| top[x as usize - '0' as usize]).collect();
        let bot_str: String = tm.chars().map(|x| bot[x as usize - '0' as usize]).collect();

        clear_screen();
        println!("{}", top_str);
        println!("{}", bot_str);

        thread::sleep(Duration::from_secs(1));
    }
}

fn clear_screen() {
    println!("{}[H{}[J", 27 as char, 27 as char);
}


class Vector
  property x, y, z

  def initialize(@x : Int64, @y : Int64, @z : Int64) end

  def dot_product(other : Vector)
    (self.x * other.x) + (self.y * other.y) + (self.z * other.z)
  end
end

puts Vector.new(1, 3, -5).dot_product Vector.new(4, -2, -1) # => 3

class Array
  def dot_product(other)
    raise "not the same size!" if self.size != other.size
    self.zip(other).sum { |(a, b)| a * b }
  end
end

p [8, 13, -5].dot_product [4, -7, -11]   # => -4


void main() {
    import std.stdio, std.numeric;

    [1.0, 3.0, -5.0].dotProduct([4.0, -2.0, -1.0]).writeln;
}


to dcr :step :length
  make "step :step - 1
  make "length :length / 1.41421
  if :step > 0 [rt 45 dcr :step :length lt 90 dcl :step :length rt 45]
  if :step = 0 [rt 45 fd :length lt 90 fd :length rt 45]
end

to dcl :step :length
  make "step :step - 1
  make "length :length / 1.41421
  if :step > 0 [lt 45 dcr :step :length rt 90 dcl :step :length lt 45]
  if :step = 0 [lt 45 fd :length rt 90 fd :length lt 45]
end


function dragon()
    local l = "l"
    local r = "r"
    local inverse = {l = r, r = l}
    local field = {r}
    local num = 1
    local loop_limit = 6 --increase this number to render a bigger curve
    for discard=1,loop_limit do
        field[num+1] = r
        for i=1,num do
            field[i+num+1] = inverse[field[num-i+1]]
        end
        num = num*2+1
    end
    return field
end

function render(field, w, h, l)
    local x = 0
    local y = 0
    local points = {}
    local highest_x = 0
    local highest_y = 0
    local lowest_x = 0
    local lowest_y = 0
    local l = "l"
    local r = "r"
    local u = "u"
    local d = "d"
    local heading = u
    local turn = {r = {r = d, d = l, l = u, u = r}, l = {r = u, u = l, l = d, d = r}}
    for k, v in ipairs(field) do
        heading = turn[v][heading]
        for i=1,3 do
            points[#points+1] = {x, y}
            if heading == l then
                x = x-w
            elseif heading == r then
                x = x+w
            elseif heading == u then
                y = y-h
            elseif heading == d then
                y = y+h
            end
            if x > highest_x then
                highest_x = x
            elseif x < lowest_x then
                lowest_x = x
            end
            if y > highest_y then
                highest_y = y
            elseif y < lowest_y then
                lowest_y = y
            end
        end
    end
    points[#points+1] = {x, y}
    highest_x = highest_x - lowest_x + 1
    highest_y = highest_y - lowest_y + 1
    for k, v in ipairs(points) do
        v[1] = v[1] - lowest_x + 1
        v[2] = v[2] - lowest_y + 1
    end
    return highest_x, highest_y, points
end

function render_text_mode()
    local width, height, points = render(dragon(), 1, 1, 1)
    local rows = {}
    for i=1,height do
        rows[i] = {}
        for j=1,width do
            rows[i][j] = ' '
        end
    end
    for k, v in ipairs(points) do
        rows[v[2]][v[1]] = "*"
    end

    for i=1,height do
        print(table.concat(rows[i], ""))
    end
end

function dump_points()
    local width, height, points = render(dragon(), 4, 4, 1)
    for k, v in ipairs(points) do
        print(unpack(v))
    end
end

--replace this line with dump_points() to output a list of coordinates:
render_text_mode()


import "/dynamic" for Struct
import "/fmt" for Fmt

var NNode = Struct.create("NNode", ["name", "children"])
var INode = Struct.create("INode", ["level", "name"])

var toNest // recursive function
toNest = Fn.new { |iNodes, start, level, n|
    if (level == 0) n.name = iNodes[0].name
    var i = start + 1
    while (i < iNodes.count) {
        if (iNodes[i].level == level+1) {
            var c = NNode.new(iNodes[i].name, [])
            toNest.call(iNodes, i, level+1, c)
            n.children.add(c)
        } else if (iNodes[i].level <= level) {
            return
        }
        i = i + 1
    }
}

var makeIndent = Fn.new { |outline, tab|
    var lines = outline.split("\n")
    var iNodes = List.filled(lines.count, null)
    var i = 0
    for (line in lines) {
        var line2 = line.trimStart(" ")
        var le  = line.count
        var le2 = line2.count
        var level = ((le - le2) / tab).floor
        iNodes[i] = INode.new(level, line2)
        i = i + 1
    }
    return iNodes
}

var toMarkup = Fn.new { |n, cols, depth|
    var span = 0
    var colSpan  // recursive closure
    colSpan = Fn.new { |nn|
        var i = 0
        for (c in nn.children) {
            if (i > 0) span = span + 1
            colSpan.call(c)
            i = i + 1
        }
    }

    for (c in n.children) {
        span = 1
        colSpan.call(c)
    }
    var lines = []
    lines.add("{| class=\"wikitable\" style=\"text-align: center;\"")
    var l1 = "|-"
    var l2 = "|  |"
    lines.add(l1)
    span = 1
    colSpan.call(n)
    var s = Fmt.swrite("| style=\"background: $s \" colSpan=$d | $s", cols[0], span, n.name)
    lines.add(s)
    lines.add(l1)

    var nestedFor // recursive function
    nestedFor = Fn.new { |nn, level, maxLevel, col|
        if (level == 1 && maxLevel > level) {
            var i = 0
            for (c in nn.children) {
                nestedFor.call(c, 2, maxLevel, i)
                i = i + 1
            }
        } else if (level < maxLevel) {
            for (c in nn.children) {
                nestedFor.call(c, level+1, maxLevel, col)
            }
        } else {
            if (nn.children.count > 0) {
                var i = 0
                for (c in nn.children) {
                    span = 1
                    colSpan.call(c)
                    var cn = col + 1
                    if (maxLevel == 1) cn = i + 1
                    var s = Fmt.swrite("| style=\"background: $s \" colspan=$d | $s", cols[cn], span, c.name)
                    lines.add(s)
                    i = i + 1
                }
            } else {
                lines.add(l2)
            }
        }
    }
    for (maxLevel in 1...depth) {
        nestedFor.call(n, 1, maxLevel, 0)
        if (maxLevel < depth-1) lines.add(l1)
    }
    lines.add("|}")
    return lines.join("\n")
}

var outline = """
Display an outline as a nested table.
    Parse the outline to a tree,
        measuring the indent of each line,
        translating the indentation to a nested structure,
        and padding the tree to even depth.
    count the leaves descending from each node,
        defining the width of a leaf as 1,
        and the width of a parent node as a sum.
            (The sum of the widths of its children)
    and write out a table with 'colspan' values
        either as a wiki table,
        or as HTML.
"""
var yellow = "#ffffe6;"
var orange = "#ffebd2;"
var green  = "#f0fff0;"
var blue   = "#e6ffff;"
var pink   = "#ffeeff;"

var cols = [yellow, orange, green, blue, pink]
var iNodes = makeIndent.call(outline, 4)
var n = NNode.new("", [])
toNest.call(iNodes, 0, 0, n)
System.print(toMarkup.call(n, cols, 4))

System.print("\n")
var outline2 = """
Display an outline as a nested table.
    Parse the outline to a tree,
        measuring the indent of each line,
        translating the indentation to a nested structure,
        and padding the tree to even depth.
    count the leaves descending from each node,
        defining the width of a leaf as 1,
        and the width of a parent node as a sum.
            (The sum of the widths of its children)
            Propagating the sums upward as necessary.
    and write out a table with 'colspan' values
        either as a wiki table,
        or as HTML.
    Optionally add color to the nodes.
"""
var cols2 = [blue, yellow, orange, green, pink]
var n2 = NNode.new("", [])
var iNodes2 = makeIndent.call(outline2, 4)
toNest.call(iNodes2, 0, 0, n2)
System.print(toMarkup.call(n2, cols2, 4))


#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>

template<typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    auto it = v.cbegin();
    auto end = v.cend();

    os << '[';
    if (it != end) {
        os << *it;
        it = std::next(it);
    }
    while (it != end) {
        os << ", " << *it;
        it = std::next(it);
    }
    return os << ']';
}

std::ostream& operator<<(std::ostream& os, const std::string& s) {
    return os << s.c_str();
}

std::string linearCombo(const std::vector<int>& c) {
    std::stringstream ss;
    for (size_t i = 0; i < c.size(); i++) {
        int n = c[i];
        if (n < 0) {
            if (ss.tellp() == 0) {
                ss << '-';
            } else {
                ss << " - ";
            }
        } else if (n > 0) {
            if (ss.tellp() != 0) {
                ss << " + ";
            }
        } else {
            continue;
        }

        int av = abs(n);
        if (av != 1) {
            ss << av << '*';
        }
        ss << "e(" << i + 1 << ')';
    }
    if (ss.tellp() == 0) {
        return "0";
    }
    return ss.str();
}

int main() {
    using namespace std;

    vector<vector<int>> combos{
        {1, 2, 3},
        {0, 1, 2, 3},
        {1, 0, 3, 4},
        {1, 2, 0},
        {0, 0, 0},
        {0},
        {1, 1, 1},
        {-1, -1, -1},
        {-1, -2, 0, -3},
        {-1},
    };

    for (auto& c : combos) {
        stringstream ss;
        ss << c;
        cout << setw(15) << ss.str() << " -> ";
        cout << linearCombo(c) << '\n';
    }

    return 0;
}


import java.util.{ Timer, TimerTask }
import java.time.LocalTime
import scala.math._

object Clock extends App {
  private val (width, height) = (80, 35)

  def getGrid(localTime: LocalTime): Array[Array[Char]] = {
    val (minute, second) = (localTime.getMinute, localTime.getSecond())
    val grid = Array.fill[Char](height, width)(' ')

    def toGridCoord(x: Double, y: Double): (Int, Int) =
      (floor((y + 1.0) / 2.0 * height).toInt, floor((x + 1.0) / 2.0 * width).toInt)

    def makeText(grid: Array[Array[Char]], r: Double, theta: Double, str: String) {
      val (row, col) = toGridCoord(r * cos(theta), r * sin(theta))
      (0 until str.length).foreach(i =>
        if (row >= 0 && row < height && col + i >= 0 && col + i < width) grid(row)(col + i) = str(i))
    }

    def makeCircle(grid: Array[Array[Char]], r: Double, c: Char) {
      var theta = 0.0
      while (theta < 2 * Pi) {
        val (row, col) = toGridCoord(r * cos(theta), r * sin(theta))
        if (row >= 0 && row < height && col >= 0 && col < width) grid(row)(col) = c
        theta = theta + 0.01
      }
    }

    def makeHand(grid: Array[Array[Char]], maxR: Double, theta: Double, c: Char) {
      var r = 0.0
      while (r < maxR) {
        val (row, col) = toGridCoord(r * cos(theta), r * sin(theta))
        if (row >= 0 && row < height && col >= 0 && col < width) grid(row)(col) = c
        r = r + 0.01
      }
    }

    makeCircle(grid, 0.98, '@')
    makeHand(grid, 0.6, (localTime.getHour() + minute / 60.0 + second / 3600.0) * Pi / 6 - Pi / 2, 'O')
    makeHand(grid, 0.85, (minute + second / 60.0) * Pi / 30 - Pi / 2, '*')
    makeHand(grid, 0.90, second * Pi / 30 - Pi / 2, '.')

    (1 to 12).foreach(n => makeText(grid, 0.87, n * Pi / 6 - Pi / 2, n.toString))
    grid
  } // def getGrid(

  private val timerTask = new TimerTask {
    private def printGrid(grid: Array[Array[Char]]) = grid.foreach(row => println(row.mkString))
    def run() = printGrid(getGrid(LocalTime.now()))
  }
  (new Timer).schedule(timerTask, 0, 1000)
}


num dot(List<num> A, List<num> B){
  if (A.length != B.length){
    throw new Exception('Vectors must be of equal size');
  }
  num result = 0;
  for (int i = 0; i < A.length; i++){
    result += A[i] * B[i];
  }
  return result;
}

void main(){
  var l = [1,3,-5];
  var k = [4,-2,-1];
  print(dot(l,k));
}


program Project1;

{$APPTYPE CONSOLE}

type
  doublearray = array of Double;

function DotProduct(const A, B : doublearray): Double;
var
I: integer;
begin
  assert (Length(A) = Length(B), 'Input arrays must be the same length');
  Result := 0;
  for I := 0 to Length(A) - 1 do
    Result := Result + (A[I] * B[I]);
end;

var
  x,y: doublearray;
begin
  SetLength(x, 3);
  SetLength(y, 3);
  x[0] := 1; x[1] := 3; x[2] := -5;
  y[0] := 4; y[1] :=-2; y[2] := -1;
  WriteLn(DotProduct(x,y));
  ReadLn;
end.


Module Checkit {
      def  double angle, d45, d90, change=5000
      const sr2 as double= .70710676237
      Cls 0
      Pen 14
      \\ move console full screen to second monitor
      Window 12, 1
      \\ reduce size (tv as second monitor cut pixels from edges)
      Window 12, scale.x*.9, scale.y*.9;
      \\ opacity 100%, but for 0 (black is 100%, and we can hit anything under console window)
      Desktop 255, 0
      \\ M2000 console can divide screen to characters/lines with automatic line space
      Form 60, 30
      \\ cut the border from window
      Form
      \\ scale.x and scale.y in twips
      \\ all graphic/console commands works for printer also (except for Input)
      Move scale.x/2,scale.y/10
      \\ outline graphics, here outline text
      \\ legend text$, font, size, angle, justify(2 for center), quality (non zero for antialiasing, works for angle 0), letter spacing.
      Color  {
                  Legend "DRAGON CURVE", "Courier",SCALE.Y/200,0,2, 1, SCALE.X/50
      }
      angle=0
      d45=pi/4
      d90=pi/2
      Move scale.x/3, scale.y*2/3
      bck=point
      \\ twipsx is width in twips of pixel. twipsy are height in twips of a pixel
      \\ so we use length:twips.x*scale.x/40  or scale.x/40 pixels.
      \\ use % for integer - we can omit these, and we get integer by automatic conversion (overflow raise error)
      dragon(twipsx*scale.x/40,14%, 1)
      Pen 14
      a$=key$
      Cls 5
      \\ set opacity to 100%
      Desktop 255
      End
      \\ Subs are private to this module
      \\ Subs have same scope as module
      Sub turn(rand as double)
            angle+=rand
      End Sub
      \\ angle is absolute, length is relative
      Sub forward(length as double)
            Draw Angle angle, length
      End Sub
      Sub dragon(length as double, split as integer, d as double)
            If split=0 then {
                  forward(length)
            } else {
                  Gosub turn(d*d45)
                  \\ we can omit Gosub
                  dragon(length*sr2,split-1,1)
                  turn(-d*d90)
                  dragon(length*sr2,split-1,-1)
                  turn(d*d45)
                  change--
                  If change else {
                        push 0: do {drop: push random(11,15) : over } until number<>pen: pen number
                        change=5000
                  }
            }
      End Sub
}
Checkit


# The macros which return a pair of values x,y expand to an unquoted 123,456
# which is suitable as arguments to a further macro.  The quoting is slack
# because the values are always integers and so won't suffer unwanted macro
# expansion.

#                0,1                 Vertex and segment x,y numbering.
#                 |
#                 |                  Segments are numbered as if a
#                 |s=0,1             square grid turned anti-clockwise
#                 |                  by 45 degrees.
#                 |
#  -1,0 -------- 0,0 -------- 1,0    vertex_to_seg_east(x,y) returns
#        s=-1,1   |   s=0,0          the segment x,y to the East,
#                 |                  so vertex_to_seg_east(0,0) is 0,0
#                 |
#                 |s=-1,0            vertex_to_seg_west(x,y) returns
#                 |                  the segment x,y to the West,
#                0,-1                so vertex_to_seg_west(0,0) is -1,1
#
define(`vertex_to_seg_east',  `eval($1 + $2),     eval($2 - $1)')
define(`vertex_to_seg_west',  `eval($1 + $2 - 1), eval($2 - $1 + 1)')
define(`vertex_to_seg_south', `eval($1 + $2 - 1), eval($2 - $1)')

# Some past BSD m4 didn't have "&" operator, so mod2(n) using % instead.
# mod2() returns 0,1 even if "%" gives -1 for negative odds.
#
define(`mod2', `ifelse(eval($1 % 2),0,0,1)')

# seg_to_even(x,y) returns x,y moved to an "even" position by subtracting an
# offset in a way which suits the segment predicate test.
#
# seg_offset_y(x,y) is a repeating pattern
#
#    | 1,1,0,0
#    | 1,1,0,0
#    | 0,0,1,1
#    | 0,0,1,1
#    +---------
#
# seg_offset_x(x,y) is the same but offset by 1 in x,y
#
#    | 0,1,1,0
#    | 1,0,0,1
#    | 1,0,0,1
#    | 0,1,1,0
#    +---------
#
# Incidentally these offset values also give n which is the segment number
# along the curve.  "x_offset XOR y_offset" is 0,1 and is a bit of n from
# low to high.
#
define(`seg_offset_y', `mod2(eval(($1 >> 1) + ($2 >> 1)))')
define(`seg_offset_x', `seg_offset_y(eval($1+1), eval($2+1))')
define(`seg_to_even', `eval($1 - seg_offset_x($1,$2)),
                       eval($2 - seg_offset_y($1,$2))');

# xy_div_iplus1(x,y) returns x,y divided by complex number i+1.
# So (x+i*y)/(i+1) which means newx = (x+y)/2, newy = (y-x)/2.
# Must have x,y "even", meaning x+y even, so newx and newy are integers.
#
define(`xy_div_iplus1', `eval(($1 + $2)/2), eval(($2 - $1)/2)')

# seg_is_final(x,y) returns 1 if x,y is one of the final four points.
# On these four points xy_div_iplus1(seg_to_even(x,y)) returns x,y
# unchanged, so the seg_pred() recursion does not reduce any further.
#
#       ..   |  ..
#      final | final      y=+1
#      final | final      y=0
#     -------+--------
#       ..   |  ..
#       x=-1    x=0
#
define(`seg_is_final', `eval(($1==-1 || $1==0) && ($2==1 || $2==0))')

# seg_pred(x,y) returns 1 if segment x,y is on the dragon curve.
# If the final point reached is 0,0 then the original x,y was on the curve.
# (If a different final point then x,y was one of four rotated copies of the
# curve.)
#
define(`seg_pred', `ifelse(seg_is_final($1,$2), 1,
                           `eval($1==0 && $2==0)',
                           `seg_pred(xy_div_iplus1(seg_to_even($1,$2)))')')

# vertex_pred(x,y) returns 1 if point x,y is on the dragon curve.
# The curve always turns left or right at a vertex, it never crosses itself,
# so if a vertex is visited then either the segment to the east or to the
# west must have been traversed.  Prefer ifelse() for the two checks since
# eval() || operator is not a short-circuit.
#
define(`vertex_pred', `ifelse(seg_pred(vertex_to_seg_east($1,$2)),1,1,
                             `seg_pred(vertex_to_seg_west($1,$2))')')

# forloop(varname, start,end, body)
# Expand body with varname successively define()ed to integers "start" to
# "end" inclusive.  "start" to "end" can go either increasing or decreasing.
#
define(`forloop', `define(`$1',$2)$4`'dnl
ifelse($2,$3,,`forloop(`$1',eval($2 + 2*($2 < $3) - 1), $3, `$4')')')

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

# dragon01(xmin,xmax, ymin,ymax) prints an array of 0s and 1s which are the
# vertex_pred() values.  `y' runs from ymax down to ymin so that y
# coordinate increases up the screen.
#
define(`dragon01',
`forloop(`y',$4,$3, `forloop(`x',$1,$2, `vertex_pred(x,y)')
')')

# dragon_ascii(xmin,xmax, ymin,ymax) prints an ascii art dragon curve.
# Each y value results in two output lines.  The first has "+" vertices and
# "--" horizontals.  The second has "|" verticals.
#
define(`dragon_ascii',
`forloop(`y',$4,$3,
`forloop(`x',$1,$2,
`ifelse(vertex_pred(x,y),1, `+', ` ')dnl
ifelse(seg_pred(vertex_to_seg_east(x,y)), 1, `--', `  ')')
forloop(`x',$1,$2,
`ifelse(seg_pred(vertex_to_seg_south(x,y)), 1, `|  ', `   ')')
')')

#--------------------------------------------------------------------------
divert`'dnl

# 0s and 1s directly from vertex_pred().
#
dragon01(-7,23,      dnl X range
         -11,10)     dnl Y range

# ASCII art lines.
#
dragon_ascii(-6,5,      dnl X range
             -10,2)     dnl Y range


fcn parseOutline(outline){  //--> "tree" annotated with spans
   var [const] indent=" "*100;		// no tabs

   parse:=fcn(ow,tree,parent,col,prevD,unit){
      rows,span,spans,cell := 0, 0,List(), Void;
      foreach line in (ow){
	 if(not line) continue;
	 d,text,d := line.prefix(indent), line[d,*], d/unit;  // d==0 is boo-boo
         if(d==prevD){		// assume a leaf
	    rows=rows.max(d);	// zero based
	    col+=1; span+=1;
	    cell=List(d,col,1,text);  // cell: (depth, col offset, span, text)
	    tree.append(cell);
	 }
	 else if(d>prevD){	// down a level
	    ow.push(line);
	    r,s := self.fcn(ow,tree,cell,col-1,d,unit);
	    rows = rows.max(r);
	    spans.append(s);
	 }
	 else{   // d<prevD: done with this branch, back out to level above
	    ow.push(line);
	    break;
	 }
      }
      span=( spans and (spans.sum(0) + span - 1) or span ).max(1);
      parent[2]=span;
      return(rows,span);
   };

   ow,title,trees := outline.walker(11), ow.next(), List();
   line,unit := ow.peek(), line.prefix(indent);	// no leading space == bad
   rows,cols := 0,0;
   foreach line in (ow){	// the major (same color) columns
      tree:=List(0, cell:=List(1, 1,1, line.strip()) );
      trees.append(tree);
      r,c := parse(ow,tree,cell,0,2,unit);
      tree[0]=c;	// span for this "branch"
      rows,cols = rows.max(r), cols + c;
   }
   return(rows+1,cols,title,trees);
}

fcn makeMarkup(rows,cols,title,trees){
   var [const] colors=L("#ffebd2","#f0fff0","#e6ffff","#ffeeff");
   out,cell := Data(Void), 0'~| style="background: %s " colspan=%d | %s~.fmt;
   out.writeln(0'~{| class="wikitable" style="text-align: center;"~,"\n|-\n",
     cell("#ffffe6;",cols,title));
   foreach row in ([1..rows-1]){
      clrs:=Walker.cycle(colors);
      out.writeln("|-");
      foreach t in (trees){	// create this row
	 span,clr := t[0], clrs.next();
	 col,cols := 1, t[1,*].filter('wrap([(d,_,text)]){ d==row });
	 foreach _,cpos,cspan,text in (cols){
	    if(col<cpos){ out.writeln(cell(clr,cpos-col,"")); col=cpos }
	    out.writeln(cell(clr,cspan,text)); col+=cspan;
	 }  // col is span+1 after loop if all cells had text
	 if(col<=span) out.writeln(cell(clr,span-col+1,""));
      }
   }
   out.writeln("|}");
   out.text
}


import std.array;
import std.conv;
import std.format;
import std.math;
import std.stdio;

string linearCombo(int[] c) {
    auto sb = appender!string;
    foreach (i, n; c) {
        if (n==0) continue;
        string op;
        if (n < 0) {
            if (sb.data.empty) {
                op = "-";
            } else {
                op = " - ";
            }
        } else if (n > 0) {
            if (!sb.data.empty) {
                op = " + ";
            }
        }
        auto av = abs(n);
        string coeff;
        if (av != 1) {
            coeff = to!string(av) ~ "*";
        }
        sb.formattedWrite("%s%se(%d)", op, coeff, i+1);
    }
    if (sb.data.empty) {
        return "0";
    }
    return sb.data;
}

void main() {
    auto combos = [
        [1, 2, 3],
        [0, 1, 2, 3],
        [1, 0, 3, 4],
        [1, 2, 0],
        [0, 0, 0],
        [0],
        [1, 1, 1],
        [-1, -1, -1],
        [-1, -2, 0, -3],
        [-1],
    ];
    foreach (c; combos) {
        auto arr = c.format!"%s";
        writefln("%-15s  ->  %s", arr, linearCombo(c));
    }
}


(import (scheme base)
        (scheme inexact)
        (scheme time)
        (pstk))

(define PI 3.1415927)

;; Draws the hands on the canvas using the current time, and repeats each second
(define (hands canvas)
  (canvas 'delete 'withtag "hands")

  (let* ((time (current-second)) ; no time locality used, so displays time in GMT
         (hours (floor (/ time 3600)))
         (rem (- time (* hours 3600)))
         (mins (floor (/ rem 60)))
         (secs (- rem (* mins 60)))
         (second-angle (* secs (* 2 PI 1/60)))
         (minute-angle (* mins (* 2 PI 1/60)))
         (hour-angle (* hours (* 2 PI 1/12))))
    (canvas 'create 'line ; second hand
            100 100
            (+ 100 (* 90 (sin second-angle)))
            (- 100 (* 90 (cos second-angle)))
            'width: 1 'tags: "hands")
    (canvas 'create 'line ; minute hand
            100 100
            (+ 100 (* 85 (sin minute-angle)))
            (- 100 (* 85 (cos minute-angle)))
            'width: 3
            'capstyle: "projecting"
            'tags: "hands")
    (canvas 'create 'line ; hour hand
            100 100
            (+ 100 (* 60 (sin hour-angle)))
            (- 100 (* 60 (cos hour-angle)))
            'width: 7
            'capstyle: "projecting"
            'tags: "hands"))
  (tk/after 1000 (lambda () (hands canvas))))

;; Create the initial frame, clock frame and hours
(let ((tk (tk-start)))
  (tk/wm 'title tk "GMT Clock")

  (let ((canvas (tk 'create-widget 'canvas)))
    (tk/pack canvas)
    (canvas 'configure 'height: 200 'width: 200)
    (canvas 'create 'oval 2 2 198 198 'fill: "white" 'outline: "black")
    (do ((h 1 (+ 1 h)))
      ((> h 12) )
      (let ((angle (- (/ PI 2) (* h PI 1/6))))
        (canvas 'create 'text
                (+ 100 (* 90 (cos angle)))
                (- 100 (* 90 (sin angle)))
                'text: (number->string h)
                'font: "{Helvetica -12}")))

    (hands canvas))
  (tk-event-loop tk))


function DotProduct(a, b : array of Float) : Float;
require
   a.Length = b.Length;
var
   i : Integer;
begin
   Result := 0;
   for i := 0 to a.High do
      Result += a[i]*b[i];
end;

PrintLn(DotProduct([1,3,-5], [4,-2,-1]));


dot a b:
	if /= len a len b:
		Raise value-error "dot product needs two vectors with the same length"

	0
	while a:
		+ * pop-from a pop-from b

!. dot [ 1 3 -5 ] [ 4 -2 -1 ]


mode_setup;
dragoniter := 8;
beginchar("D", 25pt#, 25pt#, 0pt#);
  pickup pencircle scaled .5pt;
  x1 = 0; x2 = w; y1 = y2 = .5h;
  mstep := .5; sg := -1;
  for i = 1 upto dragoniter:
    for v = 1 step mstep until (2-mstep):
      if unknown z[v+mstep]:
	pair t;
	t := .7071[ z[v], z[v+2mstep] ];
	z[v+mstep] = t rotatedaround(z[v], 45sg);
	sg := -1*sg;
      fi
    endfor
    mstep := mstep/2;
  endfor
  draw for v:=1 step 2mstep until (2-2mstep): z[v] -- endfor z[2];
endchar;
end


import math
import imageman

const
  ## Separation of the two endpoints.
  ## Make this a power of 2 for prettier output.
  Sep = 512
  ## Depth of recursion. Adjust as desired for different visual effects.
  Depth = 18

  S = sqrt(2.0) / 2
  Sin = [float 0, S, 1, S, 0, -S, -1, -S]
  Cos = [float 1, S, 0, -S, -1, -S, 0, S]

  LineColor = ColorRGBU [byte 64, 192, 96]
  Width = Sep * 11 div 6
  Height = Sep * 4 div 3

  Output = "dragon.png"

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

func dragon(img: var Image; n, a, t: int; d, x, y: float) =
  if n <= 1:
    img.drawLine((x.toInt, y.toInt), ((x + d * Cos[a]).toInt, (y + d * Sin[a]).toInt), LineColor)
    return
  let d = d * S
  let a1 = (a - t) and 7
  let a2 = (a + t) and 7
  img.dragon(n - 1, a1, 1, d, x, y)
  img.dragon(n - 1, a2, -1, d, x + d * Cos[a1], y + d * Sin[a1])

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

var image = initImage[ColorRGBU](Width, Height)
image.fill(ColorRGBU [byte 0, 0, 0])
image.dragon(Depth, 0, 1, Sep, Sep / 2, Sep * 5 / 6)

# Save into a PNG file.
image.savePNG(Output, compression = 9)


;; build an html string from list of coeffs

(define (linear->html coeffs)
    (define plus #f)
    (or*
    (for/fold (html "") ((a coeffs) (i (in-naturals 1)))
      (unless (zero? a)
 		(set! plus (if plus "+" "")))
      (string-append html
	 (cond
	  ((= a 1)  (format "%a e%d " plus i))
	  ((= a -1) (format "- e%d " i))
	  ((> a 0)  (format "%a %d*e%d " plus a i))
	  ((< a 0)  (format "- %d*e%d " (abs a) i))
	  (else ""))))
     "0"))

(define linears '((1 2 3)
   (0 1 2 3)
   (1 0 3 4)
   (1 2 0)
   (0 0 0)
   (0)
   (1 1 1)
   (-1 -1 -1)
   (-1 -2 0 -3)
   (-1)))

(define (task linears)
    (html-print ;; send string to stdout
    (for/string ((linear linears))
      (format "%a -> %a
" linear (linear->html linear)))))


$ include "seed7_05.s7i";
  include "float.s7i";
  include "math.s7i";
  include "draw.s7i";
  include "keybd.s7i";
  include "time.s7i";
  include "duration.s7i";

const integer: WINDOW_WIDTH is 200;
const integer: WINDOW_HEIGHT is 200;
const color: BACKGROUND is White;
const color: FOREGROUND is Black;
const color: CLOCKCOLOR is Aqua;

const proc: main is func
  local
    var char: command is ' ';
    var time: start_time is time.value;
    var float: alpha is 0.0;
    var integer: x is 0;
  begin
    screen(WINDOW_WIDTH, WINDOW_HEIGHT);
    clear(curr_win, BACKGROUND);
    KEYBOARD := GRAPH_KEYBOARD;
    command := busy_getc(KEYBOARD);
    while command <> 'q' do
      start_time := truncToSecond(time(NOW));
      clear(curr_win, BACKGROUND);
      fcircle(100, 100, 95, CLOCKCOLOR);
      circle(100, 100, 95, FOREGROUND);
      for x range 0 to 60 do
        alpha := flt(x-15) * PI / 30.0;
        if x mod 5 = 0 then
          lineTo(100 + round(cos(alpha)*95.0),
                 100 + round(sin(alpha)*95.0),
                 100 + round(cos(alpha)*85.0),
                 100 + round(sin(alpha)*85.0), FOREGROUND);
        else
          lineTo(100 + round(cos(alpha)*95.0),
                 100 + round(sin(alpha)*95.0),
                 100 + round(cos(alpha)*92.0),
                 100 + round(sin(alpha)*92.0), FOREGROUND);
        end if;
      end for;
      alpha := flt(start_time.second-15) * PI / 30.0;
      lineTo(100, 100, 100 + round(cos(alpha)*85.0), 100 + round(sin(alpha)*85.0), FOREGROUND);
      alpha := flt(start_time.minute-15) * PI / 30.0;
      lineTo(100 + round(cos(alpha-PI/2.0)*5.0),
             100 + round(sin(alpha-PI/2.0)*5.0),
             100 + round(cos(alpha)*75.0),
             100 + round(sin(alpha)*75.0), FOREGROUND);
      lineTo(100 + round(cos(alpha+PI/2.0)*5.0),
             100 + round(sin(alpha+PI/2.0)*5.0),
             100 + round(cos(alpha)*75.0),
             100 + round(sin(alpha)*75.0), FOREGROUND);
      alpha := (flt(start_time.hour)+flt(start_time.minute)/60.0-3.0) * PI / 6.0;
      lineTo(100 + round(cos(alpha-PI/2.0)*7.0),
             100 + round(sin(alpha-PI/2.0)*7.0),
             100 + round(cos(alpha)*50.0),
             100 + round(sin(alpha)*50.0), FOREGROUND);
      lineTo(100 + round(cos(alpha+PI/2.0)*7.0),
             100 + round(sin(alpha+PI/2.0)*7.0),
             100 + round(cos(alpha)*50.0),
             100 + round(sin(alpha)*50.0), FOREGROUND);
      fcircle(100, 100, 7, CLOCKCOLOR);
      circle(100, 100, 7, FOREGROUND);
      DRAW_FLUSH;
      await(start_time + 1 . SECONDS);
      command := busy_getc(KEYBOARD);
    end while;
  end func;


proc nonrec dot_product([*] int a, b) int:
    int total;
    word i;
    total := 0;
    for i from 0 upto dim(a,1)-1 do
        total := total + a[i] * b[i]
    od;
    total
corp

proc nonrec main() void:
    [3] int a = (1, 3, -5);
    [3] int b = (4, -2, -1);
    write(dot_product(a, b))
corp


(define a #(1 3 -5))
(define b #(4 -2 -1))

;; function definition
(define ( ⊗ a b) (for/sum ((x a)(y b)) (* x y)))
(⊗ a b) → 3

;; library
(lib 'math)
(dot-product a b) → 3


class
	APPLICATION

create
	make

feature {NONE} -- Initialization

	make
			-- Run application.
		do
			print(dot_product(<<1, 3, -5>>, <<4, -2, -1>>).out)
		end

feature -- Access

	dot_product (a, b: ARRAY[INTEGER]): INTEGER
			-- Dot product of vectors `a' and `b'.
		require
			a.lower = b.lower
			a.upper = b.upper
		local
			i: INTEGER
		do
			from
				i := a.lower
			until
				i > a.upper
			loop
				Result := Result + a[i] * b[i]
				i := i + 1
			end
		end
end


(* This constant does not seem to be defined anywhere in the standard modules *)
let pi = acos (-1.0);

(*
** CLASS dragon_curve_computer:
** ----------------------------
** Computes the coordinates for the line drawing the curve.
** - initial_x initial_y: coordinates for starting point for curve
** - total_length: total length for the curve
** - total_splits: total number of splits to perform
*)
class dragon_curve_computer initial_x initial_y total_length total_splits =
  object(self)
    val mutable current_x = (float_of_int initial_x)  (* current x coordinate in curve *)
    val mutable current_y = (float_of_int initial_y)  (* current y coordinate in curve *)
    val mutable current_angle = 0.0                   (* current angle *)

    (*
    ** METHOD compute_coords:
    ** ----------------------
    ** Actually computes the coordinates in the line for the curve
    ** - length: length for current iteration
    ** - nb_splits: number of splits to perform for current iteration
    ** - direction: direction for current line (-1.0 or 1.0)
    ** Returns: the list of coordinates for the line in this iteration
    *)
    method compute_coords length nb_splits direction =
      (* If all splits have been done *)
      if nb_splits = 0
      then
        begin
          (* Draw line segment, updating current coordinates *)
          current_x <- current_x +. length *. cos current_angle;
          current_y <- current_y +. length *. sin current_angle;
          [(int_of_float current_x, int_of_float current_y)]
        end
      (* If there are still splits to perform *)
      else
        begin
          (* Compute length for next iteration *)
          let sub_length = length /. sqrt 2.0 in
          (* Turn 45 degrees to left or right depending on current direction and draw part
             of curve in this direction *)
          current_angle <- current_angle +. direction *. pi /. 4.0;
          let coords1 = self#compute_coords sub_length (nb_splits - 1) 1.0 in
          (* Turn 90 degrees in the other direction and draw part of curve in that direction *)
          current_angle <- current_angle -. direction *. pi /. 2.0;
          let coords2 = self#compute_coords sub_length (nb_splits - 1) (-1.0) in
          (* Turn back 45 degrees to set head in the initial direction again *)
          current_angle <- current_angle +. direction *. pi /. 4.0;
          (* Concatenate both sub-curves to get the full curve for this iteration *)
          coords1 @ coords2
        end

    (*
    ** METHOD get_coords:
    ** ------------------
    ** Returns the coordinates for the curve with the parameters set in the object initializer
    *)
    method get_coords = self#compute_coords total_length total_splits 1.0
  end;;

(*
** MAIN PROGRAM:
** =============
*)
let () =
  (* Curve is displayed in a Tk canvas *)
  let top=Tk.openTk() in
  let c = Canvas.create ~width:400 ~height:400 top in
  Tk.pack [c];
  (* Create instance computing the curve coordinates *)
  let dcc = new dragon_curve_computer 100 200 200.0 16 in
  (* Create line with these coordinates in canvas *)
  ignore (Canvas.create_line ~xys: dcc#get_coords c);
  Tk.mainLoop ();
;;


// Display a linear combination. Nigel Galloway: March 28th., 2018
let fN g =
  let rec fG n g=match g with
                 |0::g    ->                        fG (n+1) g
                 |1::g    -> printf "+e(%d)" n;     fG (n+1) g
                 |(-1)::g -> printf "-e(%d)" n;     fG (n+1) g
                 |i::g    -> printf "%+de(%d)" i n; fG (n+1) g
                 |_       -> printfn ""
  let rec fN n g=match g with
                 |0::g    ->                        fN (n+1) g
                 |1::g    -> printf "e(%d)" n;      fG (n+1) g
                 |(-1)::g -> printf "-e(%d)" n;     fG (n+1) g
                 |i::g    -> printf "%de(%d)" i n;  fG (n+1) g
                 |_       -> printfn "0"
  fN 1 g


STDOUT.autoflush(true)

var (rows, cols) = `stty size`.nums...

var x = (rows/2 - 1  -> int)
var y = (cols/2 - 16 -> int)

var chars = [
                 "┌─┐  ╷╶─┐╶─┐╷ ╷┌─╴┌─╴╶─┐┌─┐┌─┐   ",
                 "│ │  │┌─┘╶─┤└─┤└─┐├─┐  │├─┤└─┤ : ",
                 "└─┘  ╵└─╴╶─┘  ╵╶─┘└─┘  ╵└─┘╶─┘   "
             ].map {|s| s.split(3) }

func position(i,j) {
    "\e[%d;%dH" % (i, j)
}

func indices {
    var t = Time.local
    "%02d:%02d:%02d" % (t.hour, t.min, t.sec) -> split(1).map{|c| c.ord - '0'.ord }
}

loop {
    print "\e[H\e[J"
    for i in ^chars {
      print position(x + i, y)
      print [chars[i][indices()]].join(' ')
    }
    print position(1, 1)
    Sys.sleep(0.1)
}


open list

dotp a b | length a == length b = sum (zipWith (*) a b)
         | else = fail "Vector sizes must match."

dotp [1,3,-5] [4,-2,-1]


import extensions;
import system'routines;

extension op
{
    method dotProduct(int[] array)
        = self.zipBy(array, (x,y => x * y)).summarize();
}

public program()
{
    console.printLine(new int[]{1, 3, -5}.dotProduct(new int[]{4, -2, -1}))
}


defmodule Vector do
  def dot_product(a,b) when length(a)==length(b), do: dot_product(a,b,0)
  def dot_product(_,_) do
    raise ArgumentError, message: "Vectors must have the same length."
  end

  defp dot_product([],[],product), do: product
  defp dot_product([h1|t1], [h2|t2], product), do: dot_product(t1, t2, product+h1*h2)
end

IO.puts Vector.dot_product([1,3,-5],[4,-2,-1])


level = 8;
linewidth = .1;  // fraction of segment length
sqrt2 = pow(2, .5);

// Draw a dragon curve "level" going from [0,0] to [1,0]
module dragon(level) {
    if (level <= 0) {
        translate([.5,0]) cube([1+linewidth,linewidth,linewidth],center=true);
    } else {
        rotate(-45) scale(1/sqrt2) dragon(level-1);
        translate([1,0]) rotate(-135) scale(1/sqrt2) dragon(level-1);
    }
}

scale(40) {  // scale to nicely visible in the default GUI
    sphere(1.5*linewidth / pow(2,level/2));  // mark the start of the curve
    dragon(level);
}


level = 13
p = [0, 1];  \\ complex number points, initially 0 to 1

\\ "unfold" at the current endpoint p[#p].
\\ p[^-1] so as not to duplicate that endpoint.
\\
\\           *  end
\\      -->  |
\\     /     |
\\           v
\\  *------->*
\\ 0,0       p[#p]
\\
for(i=1,level, my(end = (1+I)*p[#p]); \
               p = concat(p, apply(z->(end - I*z), Vecrev(p[^-1]))))

plothraw(apply(real,p),apply(imag,p), 1); \\ flag=1 join points


USING: formatting kernel match math pair-rocket regexp sequences ;

MATCH-VARS: ?a ?b ;

: choose-term ( coeff i -- str )
    1 + { } 2sequence {
        {  0  _ } => [       ""                 ]
        {  1 ?a } => [ ?a    "e(%d)"    sprintf ]
        { -1 ?a } => [ ?a    "-e(%d)"   sprintf ]
        { ?a ?b } => [ ?a ?b "%d*e(%d)" sprintf ]
    } match-cond ;

: linear-combo ( seq -- str )
    [ choose-term ] map-index harvest " + " join
    R/ \+ -/ "- " re-replace [ "0" ] when-empty ;

{ { 1 2 3 } { 0 1 2 3 } { 1 0 3 4 } { 1 2 0 } { 0 0 0 } { 0 }
  { 1 1 1 } { -1 -1 -1 } { -1 -2 0 -3 } { -1 } }
[ dup linear-combo "%-14u  ->  %s\n" printf ] each


Dim scalars(1 To 10, 1 To 4) As Integer => {{1,  2,  3}, {0,  1,  2,  3}, _
{1,  0,  3,  4}, {1,  2,  0}, {0,  0,  0}, {0}, {1,  1,  1}, {-1, -1, -1}, _
{-1, -2,  0, -3}, {-1}}

For n As Integer = 1 To Ubound(scalars)
    Dim As String cadena = ""
    Dim As Integer scalar
    For m As Integer = 1 To Ubound(scalars,2)
        scalar = scalars(n, m)
        If scalar <> 0 Then
            If scalar = 1 Then
                cadena &= "+e" & m
            Elseif scalar = -1 Then
                cadena &= "-e" & m
            Else
                If scalar > 0 Then
                    cadena &= Chr(43) & scalar & "*e" & m
                Else
                    cadena &= scalar & "*e" & m
                End If
            End If
        End If
    Next m
    If cadena = "" Then cadena = "0"
    If Left(cadena, 1) = "+" Then cadena = Right(cadena, Len(cadena)-1)
    Print cadena
Next n
Sleep


<svg viewBox="0 0 100 100" width="480px" height="480px" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="48" style="fill:peru; stroke:black; stroke-width:2" />
<g transform="translate(50,50) rotate(0)" style="fill:none; stroke-linecap:round">
  <line y2="-36" style="stroke:black; stroke-width:5">
    <animateTransform
      attributeName="transform"
      type="rotate"
      by="30"
      dur="3600s"
      accumulate="sum"
      repeatCount="indefinite"/>
  </line>
  <line y2="-42" style="stroke:white; stroke-width:2">
    <animateTransform
      attributeName="transform"
      type="rotate"
      by="6"
      dur="60s"
      accumulate="sum"
      repeatCount="indefinite"/>
  </line>
  <line y2="-46" style="stroke:red; stroke-width:1">
    <animateTransform
      attributeName="transform"
      type="rotate"
      calcMode="discrete"
      by="6"
      dur="1s"
      accumulate="sum"
      repeatCount="indefinite"/>
  </line>
</g>
<circle cx="50" cy="50" r="4" style="fill:gold; stroke:black; stroke-width:1" />
</svg>


package require Tcl 8.5
package require Tk

# GUI code
pack [canvas .c -width 200 -height 200]
.c create oval 20 20 180 180 -width 10 -fill {} -outline grey70
.c create line 0 0 1 1 -tags hour   -width 6 -cap round -fill black
.c create line 0 0 1 1 -tags minute -width 4 -cap round -fill black
.c create line 0 0 1 1 -tags second -width 2 -cap round -fill grey30
proc updateClock t {
    scan [clock format $t -format "%H %M %S"] "%d%d%d" h m s
    # On an analog clock, the hour and minute hands move gradually
    set m [expr {$m + $s/60.0}]
    set h [expr {($h % 12 + $m/60.0) * 5}]
    foreach tag {hour minute second} value [list $h $m $s] len {50 80 80} {
	.c coords $tag 100 100 \
	    [expr {100 + $len*sin($value/30.0*3.14159)}] \
	    [expr {100 - $len*cos($value/30.0*3.14159)}]
    }
}

# Timer code, accurate to within a quarter second
set time 0
proc ticker {} {
    global time
    set t [clock seconds]
    after 250 ticker
    if {$t != $time} {
	set time $t
	updateClock $t
    }
}
ticker


dotp: List number -> List number -> Maybe number
dotp a b =
    if List.length a /= List.length b then
        Nothing
    else
        Just (List.sum <| List.map2 (*) a b)

dotp [1,3,-5] [4,-2,-1])


(defun dot-product (v1 v2)
  (let ((res 0))
    (dotimes (i (length v1))
      (setq res (+ (* (elt v1 i) (elt v2 i)) res)))
    res))

(dot-product [1 2 3] [1 2 3]) ;=> 14
(dot-product '(1 2 3) '(1 2 3)) ;=> 14


dotProduct(A,B) when length(A) == length(B) -> dotProduct(A,B,0);
dotProduct(_,_) -> erlang:error('Vectors must have the same length.').

dotProduct([H1|T1],[H2|T2],P) -> dotProduct(T1,T2,P+H1*H2);
dotProduct([],[],P) -> P.

dotProduct([1,3,-5],[4,-2,-1]).


procedure dcr(step,dir:integer;length:real);
 begin;
  step:=step -1;
  length:= length/sqrt(2);
  if dir > 0 then
   begin
     if step > 0 then
     begin
       turnright(45);
       dcr(step,1,length);
       turnleft(90);
       dcr(step,0,length);
       turnright(45);
     end
     else
     begin
       turnright(45);
       forward(length);
       turnleft(90);
       forward(length);
       turnright(45);
     end;
   end
  else
   begin
     if step > 0 then
     begin
       turnleft(45);
       dcr(step,1,length);
       turnright(90);
       dcr(step,0,length);
       turnleft(45);
     end
     else
     begin
       turnleft(45);
       forward(length);
       turnright(90);
       forward(length);
       turnleft(45);
     end;
   end;
end;


use SVG;
use List::Util qw(max min);

use constant pi => 2 * atan2(1, 0);

# Compute the curve with a Lindemayer-system
my %rules = (
    X => 'X+YF+',
    Y => '-FX-Y'
);
my $dragon = 'FX';
$dragon =~ s/([XY])/$rules{$1}/eg for 1..10;

# Draw the curve in SVG
($x, $y) = (0, 0);
$theta   = 0;
$r       = 6;

for (split //, $dragon) {
    if (/F/) {
        push @X, sprintf "%.0f", $x;
        push @Y, sprintf "%.0f", $y;
        $x += $r * cos($theta);
        $y += $r * sin($theta);
    }
    elsif (/\+/) { $theta += pi/2; }
    elsif (/\-/) { $theta -= pi/2; }
}

$xrng =  max(@X) - min(@X);
$yrng =  max(@Y) - min(@Y);
$xt   = -min(@X)+10;
$yt   = -min(@Y)+10;
$svg = SVG->new(width=>$xrng+20, height=>$yrng+20);
$points = $svg->get_path(x=>\@X, y=>\@Y, -type=>'polyline');
$svg->rect(width=>"100%", height=>"100%", style=>{'fill'=>'black'});
$svg->polyline(%$points, style=>{'stroke'=>'orange', 'stroke-width'=>1}, transform=>"translate($xt,$yt)");

open  $fh, '>', 'dragon_curve.svg';
print $fh  $svg->xmlify(-namespace=>'svg');
close $fh;


package main

import (
    "fmt"
    "strings"
)

func linearCombo(c []int) string {
    var sb strings.Builder
    for i, n := range c {
        if n == 0 {
            continue
        }
        var op string
        switch {
        case n < 0 && sb.Len() == 0:
            op = "-"
        case n < 0:
            op = " - "
        case n > 0 && sb.Len() == 0:
            op = ""
        default:
            op = " + "
        }
        av := n
        if av < 0 {
            av = -av
        }
        coeff := fmt.Sprintf("%d*", av)
        if av == 1 {
            coeff = ""
        }
        sb.WriteString(fmt.Sprintf("%s%se(%d)", op, coeff, i+1))
    }
    if sb.Len() == 0 {
        return "0"
    } else {
        return sb.String()
    }
}

func main() {
    combos := [][]int{
        {1, 2, 3},
        {0, 1, 2, 3},
        {1, 0, 3, 4},
        {1, 2, 0},
        {0, 0, 0},
        {0},
        {1, 1, 1},
        {-1, -1, -1},
        {-1, -2, 0, -3},
        {-1},
    }
    for _, c := range combos {
        t := strings.Replace(fmt.Sprint(c), " ", ", ", -1)
        fmt.Printf("%-15s  ->  %s\n", t, linearCombo(c))
    }
}


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

var Degrees06 = Num.pi / 30
var Degrees30 = Degrees06 * 5
var Degrees90 = Degrees30 * 3

class Clock {
    construct new(hour, minute, second) {
        Window.title = "Clock"
        _size = 590
        Window.resize(_size, _size)
        Canvas.resize(_size, _size)
        _spacing = 40
        _diameter = _size - 2 * _spacing
        _cx = (_diameter / 2).floor + _spacing
        _cy = _cx
        _hour = hour
        _minute = minute
        _second = second
    }

    drawFace() {
        var radius = (_diameter / 2).floor
        Canvas.circlefill(_cx, _cy, radius, Color.yellow)
        Canvas.circle(_cx, _cy, radius, Color.black)
    }

    drawHand(angle, radius, color) {
        var x = _cx + (radius * Math.cos(angle)).truncate
        var y = _cy - (radius * Math.sin(angle)).truncate
        Canvas.line(_cx, _cy, x, y, color, 2)
    }

    drawClock() {
        Canvas.cls(Color.white)
        drawFace()
        var angle = Degrees90 - Degrees06 * _second
        drawHand(angle, (_diameter/2).floor - 30, Color.red)
        var minsecs = _minute + _second/60
        angle = Degrees90 - Degrees06 * minsecs
        drawHand(angle, (_diameter / 3).floor + 10, Color.black)
        var hourmins = _hour + minsecs / 60
        angle = Degrees90 - Degrees30 * hourmins
        drawHand(angle, (_diameter / 4).floor + 10, Color.black)
    }

    init() {
        _frame = 0
        drawClock()
    }

    update() {
        _frame = _frame + 1
        if (_frame == 60) {
            _frame = 0
            _second = _second + 1
            if (_second == 60) {
               _minute = _minute + 1
               _second = 0
                if (_minute == 60) {
                    _hour = _hour + 1
                    _minute = 0
                    if (_hour == 24) _hour = 0
                }
            }
        }
    }

    draw(alpha) {
        drawClock()
    }
}

var Game = Clock.new(0, 0, 0) // start at midnight


function dotprod(sequence a, sequence b)
    atom sum
    a *= b
    sum = 0
    for n = 1 to length(a) do
        sum += a[n]
    end for
    return sum
end function

? dotprod({1,3,-5},{4,-2,-1})


let dot_product (a:array<'a>) (b:array<'a>) =
    if Array.length a <> Array.length b then failwith "invalid argument: vectors must have the same lengths"
    Array.fold2 (fun acc i j -> acc + (i * j)) 0 a b


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

Ihandle dlg, canvas
cdCanvas cddbuffer, cdcanvas

integer colour = 0

procedure Dragon(integer depth, atom x1, y1, x2, y2)
    depth -= 1
    if depth<=0 then
        cdCanvasSetForeground(cddbuffer, colour)
        cdCanvasLine(cddbuffer, x1, y1, x2, y2)
        -- (some interesting colour patterns emerge)
        colour += 2
--      colour += 2000
--      colour += #100
    else
        atom dx = x2-x1, dy = y2-y1,
             nx = x1+(dx-dy)/2,
             ny = y1+(dx+dy)/2
        Dragon(depth,x1,y1,nx,ny)
        Dragon(depth,x2,y2,nx,ny)
    end if
end procedure

function redraw_cb(Ihandle /*ih*/, integer /*posx*/, /*posy*/)
    cdCanvasActivate(cddbuffer)
    cdCanvasClear(cddbuffer)
    -- (note: depths over 21 take a long time to draw,
    --        depths <= 16 look a little washed out)
    Dragon(17,100,100,100+256,100)
    cdCanvasFlush(cddbuffer)
    return IUP_DEFAULT
end function

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

procedure main()
    IupOpen()

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

    dlg = IupDialog(canvas,"RESIZE=NO")
    IupSetAttribute(dlg, "TITLE", "Dragon Curve")

    IupShow(dlg)
    if platform()!=JS then
        IupMainLoop()
        IupClose()
    end if
end procedure

main()


class LinearCombination {
    private static String linearCombo(int[] c) {
        StringBuilder sb = new StringBuilder()
        for (int i = 0; i < c.length; ++i) {
            if (c[i] == 0) continue
            String op
            if (c[i] < 0 && sb.length() == 0) {
                op = "-"
            } else if (c[i] < 0) {
                op = " - "
            } else if (c[i] > 0 && sb.length() == 0) {
                op = ""
            } else {
                op = " + "
            }
            int av = Math.abs(c[i])
            String coeff = av == 1 ? "" : "" + av + "*"
            sb.append(op).append(coeff).append("e(").append(i + 1).append(')')
        }
        if (sb.length() == 0) {
            return "0"
        }
        return sb.toString()
    }

    static void main(String[] args) {
        int[][] combos = [
                [1, 2, 3],
                [0, 1, 2, 3],
                [1, 0, 3, 4],
                [1, 2, 0],
                [0, 0, 0],
                [0],
                [1, 1, 1],
                [-1, -1, -1],
                [-1, -2, 0, -3],
                [-1]
        ]

        for (int[] c : combos) {
            printf("%-15s  ->  %s\n", Arrays.toString(c), linearCombo(c))
        }
    }
}


clear screen
open window 300,100
backcolor 0, 0, 0
window origin "cc"

// Display digital clock
sub digital_clock()
    local t$(1), void
    static as$

    void = token(time$, t$(), "-")

    if t$(3) <> as$ then
        draw_clock(t$(1), t$(2), t$(3))
        as$ = t$(3)
    end if
end sub

sub draw_clock(hour$, mint$, ssec$)
    local d$(1), void

    void = token(date$, d$(), "-")
    clear window
    color 200, 255, 0
    text -140, -30, d$(3) + "/" + d$(2) + "/" + d$(4), "modern12"
    text 0, 0, hour$ + ":" + mint$ + ":" + ssec$, "cc", "swiss50"
end sub

if peek$("library") = "main" then
    repeat
        digital_clock()
    until(upper$(inkey$(.01))="ESC")
    exit
end if


var
  t=T("⡎⢉⢵","⠀⢺⠀","⠊⠉⡱","⠊⣉⡱","⢀⠔⡇","⣏⣉⡉","⣎⣉⡁","⠊⢉⠝","⢎⣉⡱","⡎⠉⢱","⠀⠶⠀"),
  b=T("⢗⣁⡸","⢀⣸⣀","⣔⣉⣀","⢄⣀⡸","⠉⠉⡏","⢄⣀⡸","⢇⣀⡸","⢰⠁⠀","⢇⣀⡸","⢈⣉⡹","⠀⠶ ");
while(True){
   x:=Time.Date.ctime()[11,8]  // or Time.Date.to24HString() (no seconds)
      .pump(List,fcn(n){ n.toAsc() - 0x30 }); //-->L(2,3,10,4,3,10,5,2)
   print("\e[H\e[J");	// home and clear screen on ANSI terminals
   println(x.pump(String,t.get),"\n",x.pump(String,b.get));
   Atomic.sleep(1);
}


USING: kernel math.vectors sequences ;

: dot-product ( u v -- w )
    2dup [ length ] [email protected] =
    [ v. ] [ "Vector lengths must be equal" throw ] if ;


class DotProduct
{
  static Int dotProduct (Int[] a, Int[] b)
  {
    Int result := 0
    [a.size,b.size].min.times |i|
    {
      result += a[i] * b[i]
    }
    return result
  }

  public static Void main ()
  {
    Int[] x := [1,2,3,4]
    Int[] y := [2,3,4]

    echo ("Dot product of $x and $y is ${dotProduct(x, y)}")
  }
}


# Need some turtle graphics
(load "@lib/math.l")

(setq
   *TurtleX 100      # X position
   *TurtleY  75      # Y position
   *TurtleA 0.0 )    # Angle

(de fd (Img Len)  # Forward
   (let (R (*/ *TurtleA pi 180.0)  DX (*/ (cos R) Len 1.0)  DY (*/ (sin R) Len 1.0))
      (brez Img *TurtleX *TurtleY DX DY)
      (inc '*TurtleX DX)
      (inc '*TurtleY DY) ) )

(de rt (A)  # Right turn
   (inc '*TurtleA A) )

(de lt (A)  # Left turn
   (dec '*TurtleA A) )

# Dragon curve stuff
(de *DragonStep . 4)

(de dragon (Img Depth Dir)
   (if (=0 Depth)
      (fd Img *DragonStep)
      (rt Dir)
      (dragon Img (dec Depth) 45.0)
      (lt (* 2 Dir))
      (dragon Img (dec Depth) -45.0)
      (rt Dir) ) )

# Run it
(let Img (make (do 200 (link (need 300 0))))       # Create image 300 x 200
   (dragon Img 10 45.0)                            # Build dragon curve
   (out "img.pbm"                                  # Write to bitmap file
      (prinl "P1")
      (prinl 300 " " 200)
      (mapc prinl Img) ) )


* PROCESS GONUMBER, MARGINS(1,72), NOINTERRUPT, MACRO;
TEST:PROCEDURE OPTIONS(MAIN);
 DECLARE
  SYSIN FILE STREAM INPUT,
  DRAGON FILE STREAM OUTPUT PRINT,
  SYSPRINT FILE STREAM OUTPUT PRINT;
 DECLARE (MIN,MAX,MOD,INDEX,LENGTH,SUBSTR,VERIFY,TRANSLATE) BUILTIN;
 DECLARE (COMPLEX,SQRT,REAL,IMAG,ATAN,SIN,EXP,COS,ABS) BUILTIN;
 %INCLUDE PLILIB(GOODIES);
 %INCLUDE PLILIB(SCAN);
 %INCLUDE PLILIB(GRAMMAR);
 %INCLUDE PLILIB(CARDINAL);
 %INCLUDE PLILIB(ORDINAL);
 %INCLUDE PLILIB(ANSWAROD);
 %INCLUDE PLILIB(RUNFILE);
 %INCLUDE PLILIB(PSTUFF);

 DECLARE (TWOPI,TORAD) REAL;
 DECLARE RANGE(4) REAL;
 DECLARE TRACERANGE BOOLEAN INITIAL(FALSE);
 DECLARE FRESHRANGE BOOLEAN INITIAL(TRUE);

 BOUND:PROCEDURE(Z);
  DECLARE Z COMPLEX;
  DECLARE (ZX,ZY) REAL;
   ZX = REAL(Z); ZY = IMAG(Z);
   IF FRESHRANGE THEN
    DO;
     RANGE(1),RANGE(2) = ZX;
     RANGE(3),RANGE(4) = ZY;
    END;
    ELSE
     DO;
      RANGE(1) = MIN(RANGE(1),ZX);
      RANGE(2) = MAX(RANGE(2),ZX);
      RANGE(3) = MIN(RANGE(3),ZY);
      RANGE(4) = MAX(RANGE(4),ZY);
     END;
   FRESHRANGE = FALSE;
 END BOUND;

 PLOTZ:PROCEDURE(Z,PEN);
  DECLARE Z COMPLEX;
  DECLARE PEN INTEGER;
   IF TRACERANGE THEN CALL BOUND(Z);
   CALL PLOT(REAL(Z),IMAG(Z),PEN);
 END PLOTZ;

 %PAGE;
 DRAGONCURVE:PROCEDURE(ORDER,HOP); /*Folding paper in two...*/
/*Some statistics on runs with x = 56.25", y = 32.6"
&(the calcomp plotter).*/
/*The actual size of the picture determines the number of steps
&to each quarter-turn.*/
/*   n      turns       x         y     secs     dx    dy
&*/
/*  20  1,048,575  -2389:681  -682:1364  180+  3070  2046
&*/
/*  19    524,287  -1365:681  -340:1364  119   2046  1704
&*/
/*  18    262,143   -341:681  -340:1194   71   1022  1554
&*/
/*  17    131,071   -171:681  -340:682    35    852  1022
&*/
  DECLARE ORDER BIGINT; /*So how many folds.*/
  DECLARE HOP BOOLEAN;
  DECLARE FOLD(0:31,0:32767) BOOLEAN; /*Oh for (0:1000000) or so..*/
  DECLARE (TURN,N,IT,I,I1,I2,J1,J2,L,LL) BIGINT;
  DECLARE (XMIN,XMAX,YMIN,YMAX,XMID,YMID) REAL;
  DECLARE (IXMIN,IXMAX,IYMIN,IYMAX) BIGINT;
  DECLARE (S,H,TORAD) REAL;
  DECLARE (ZMID,Z,Z2,DZ,ZL) COMPLEX;
  DECLARE (FULLTURN,ABOUTTURN,QUARTERTURN) INTEGER;
  DECLARE (WAY,DIRECTION,ND,LD,LD1,LD2) INTEGER;
  DECLARE LEAF(0:3,0:360) COMPLEX; /*Corner turning.*/
  DECLARE SWAPXY BOOLEAN; /*Try to align rectangles.*/
  DECLARE (T1,T2) CHARACTER(200) VARYING;
   IF ¬PLOTCHOICE('') THEN RETURN; /*Ascertain the plot device.*/
   N = 0;
   FOR TURN = 1 TO ORDER;
    IT = N + 1;
    I1 = IT/32768; I2 = MOD(IT,32768);
    FOLD(I1,I2) = TRUE;
    FOR I = 1 TO N;
     I1 = (IT + I)/32768; I2 = MOD(IT + I,32768);
     J1 = (IT - I)/32768; J2 = MOD(IT - I,32768);
     FOLD(I1,I2) = ¬FOLD(J1,J2);
    END;
    N = N*2 + 1;
    IF HOP & TURN < ORDER THEN GO TO XX;
    XMIN,XMAX,YMIN,YMAX = 0;
    Z = 0; /*Start at the origin.*/
    DZ = 1; /*Step out unilaterally.*/
    FOR I = 1 TO N;
     Z = Z + DZ; /*Take the step before the kink.*/
     I1 = I/32768; I2 = MOD(I,32768);
     IF FOLD(I1,I2) THEN DZ = DZ*(0 + 1I); ELSE DZ = DZ*(0 - 1I);
     Z = Z + DZ; /*The step after the kink.*/
     XMIN = MIN(XMIN,REAL(Z)); XMAX = MAX(XMAX,REAL(Z));
     YMIN = MIN(YMIN,IMAG(Z)); YMAX = MAX(YMAX,IMAG(Z));
    END;
    SWAPXY = ((XMAX - XMIN) >= (YMAX - YMIN)) /*Contemplate */
     ¬= (PLOTSTUFF.XSIZE >= PLOTSTUFF.YSIZE); /* rectangularities.*/
    IF SWAPXY THEN
     DO;
      H = XMIN;
      XMIN = YMIN;
      YMIN = -XMAX;
      XMAX = YMAX;
      YMAX = -H;
     END;
    IXMAX = XMAX; IYMAX = YMAX; IXMIN = XMIN; IYMIN = YMIN;
    XMID = (XMAX + XMIN)/2; YMID = (YMAX + YMIN)/2;
    ZMID = COMPLEX(XMID,YMID);
    XMAX = XMAX - XMID; YMAX = YMAX - YMID;
    XMIN = XMIN - XMID; YMIN = YMIN - YMID;
    T1 = 'Order ' || IFMT(TURN) || ' Dragoncurve, '
     || SAYNUM(0,N,'turn') || '.';
    IF SWAPXY THEN T2 = 'y range ' || IFMT(IYMIN) || ':' || IFMT(IYMAX)
     || ', x range ' || IFMT(IXMIN) || ':' || IFMT(IXMAX);
     ELSE T2 = 'x range ' || IFMT(IXMIN) || ':' || IFMT(IXMAX)
     || ', y range ' || IFMT(IYMIN) || ':' || IFMT(IYMAX);
    S = MIN(PLOTSTUFF.XSIZE/(XMAX - XMIN), /*Rectangularity */
     (PLOTSTUFF.YSIZE - 4*H)/(YMAX - YMIN)); /* matching?*/
    H = MIN(PLOTSTUFF.XSIZE,S*(XMAX - XMIN)); /*X-width for text.*/
    H = MIN(PLOTCHAR,H/(MAX(LENGTH(T1),LENGTH(T2)) + 6));
    IF ¬NEWRANGE(XMIN*S,XMAX*S,YMIN*S-2*H,YMAX*S+2*H) THEN STOP('Urp!');
    CALL PLOTTEXT(-LENGTH(T1)*H/2,YMAX*S + 2*PLOTTICK,H,T1,0);
    CALL PLOTTEXT(-LENGTH(T2)*H/2,YMIN*S - 2*H + 2*PLOTTICK,H,T2,0);
    QUARTERTURN = MIN(MAX(3,12*SQRT(S)),90); /*Angle refinement.*/
    ABOUTTURN = QUARTERTURN*2;
    FULLTURN = QUARTERTURN*4; /*Ensures divisibility.*/
    TORAD = TWOPI/FULLTURN; /*Imagine if FULLTURN was 360.*/
    ZL = 1; /*Start with 0 degrees.*/
    FOR L = 0 TO 3; /*The four directions.*/
     FOR I = 0 TO FULLTURN; /*Fill out the petals in the corner.*/
      LEAF(L,I) = ZL + EXP((0 + 1I)*I*TORAD); /*Poke!*/
     END; /*Fill out the full circle for each for simplicity.*/
     ZL = ZL*(0 + 1I); /*Rotate to the next axis.*/
    END; /*Four circles, centred one unit along each axial direction.*/
    Z = -ZMID; /*The start point. Was 0, before shift by ZMID.*/
    CALL PLOTZ(S*Z,3); /*Position the pen.*/
    DIRECTION = 0; /*The way ahead is along the x-axis.*/
    DZ = 1; /*The step before the kink.*/
    IF SWAPXY THEN DIRECTION = -QUARTERTURN; /*Or maybe y.*/
    IF SWAPXY THEN DZ = (0 - 1I); /*An x-y swap.*/
    FRESHRANGE = TRUE; /*A sniffing.*/
    FOR I = 1 TO N; /*The deviationism begins.*/
     I1 = I/32768; I2 = MOD(I,32768);
     IF FOLD(I1,I2) THEN WAY = +1; ELSE WAY = -1;
     ND = DIRECTION + QUARTERTURN*WAY;
     IF ND >= FULLTURN THEN ND = ND - FULLTURN;
     IF ND < 0 THEN ND = ND + FULLTURN;
     LD = ND/QUARTERTURN; /*Select a leaf.*/
     LD1 = MOD(ND + ABOUTTURN,FULLTURN);
     LD2 = LD1 + WAY*QUARTERTURN; /*No mod, see the FOR loop below.*/
     FOR L = LD1 TO LD2 BY WAY; /*Round the kink.*/
      LL = L; /*A copy to wrap into range.*/
      IF LL < 0 THEN LL = LL + FULLTURN;
      IF LL >= FULLTURN THEN LL = LL - FULLTURN;
      ZL = Z + LEAF(LD,LL); /*Work along the curve.*/
      CALL PLOTZ(S*ZL,2); /*Move a bit.*/
     END; /*On to the next step.*/
     DIRECTION = ND; /*The new direction.*/
     Z = Z + DZ; /*The first half of the step that has been rounded.*/
     DZ = DZ*(0 + 1I)*WAY; /*A right-angle, one way or the other.*/
     Z = Z + DZ; /*Avoid the roundoff of hordes of fractional moves.*/
    END; /*On to the next fold.*/
    CALL PLOT(0,0,998);
    IF TRACERANGE THEN PUT SKIP(3) FILE(DRAGON) LIST('Dragoncurve: ');
    IF TRACERANGE THEN PUT FILE(DRAGON) DATA(RANGE,ORDER,S,ZMID);
XX:END;
 END DRAGONCURVE;
 %PAGE;
 %PAGE;
 %PAGE;
 RANDOM:PROCEDURE(SEED) RETURNS(REAL);
  DECLARE SEED INTEGER;
   SEED = SEED*497 + 4032;
   IF SEED <= 0 THEN SEED = SEED + 32767;
   IF SEED > 32767 THEN SEED = MOD(SEED,32767);
   RETURN(SEED/32767.0);
 END RANDOM;

 %PAGE;
 TRACE:PROCEDURE(O,R,A,N,G);
  DECLARE (I,N,G) INTEGER;
  DECLARE (O,R,A(*),X0,X1,X2) COMPLEX;
   X1 = O + R*A(1);
   X0 = X1;
   CALL PLOT(REAL(X1),IMAG(X1),3);
   FOR I = 2 TO N;
    X2 = O + R*A(I);
    CALL PLOT(REAL(X2),IMAG(X2),2);
    X1 = X2;
   END;
   CALL PLOT(REAL(X0),IMAG(X0),2);
 END TRACE;

 CENTREZ:PROCEDURE(A,N);
  DECLARE (A(*),T) COMPLEX;
  DECLARE (I,N) INTEGER;
   T = 0;
   FOR I = 1 TO N;
    T = T + A(I);
   END;
   T = T/N;
   FOR I = 1 TO N;
    A(I) = A(I) - T;
   END;
 END CENTREZ;
 %PAGE;
 %PAGE;
 DECLARE (BELCH,ORDER,CHASE,TWIRL) INTEGER;
 DECLARE HOP BOOLEAN;

  TWOPI = 8*ATAN(1);
  TORAD = TWOPI/360;
  BELCH = REPLYN('How many dragoncurves (max 20)');
  IF BELCH < 12 THEN HOP = FALSE;
   ELSE HOP = YEA('Go directly to order ' || IFMT(BELCH));
/*ORDER = REPLYN('The depth of recursion (eg 4)');
  CHASE = REPLYN('How many pursuits');
  TWIRL = REPLYN('How many twirls');
  TRACERANGE = YEA('Trace the ranges');*/
  CALL DRAGONCURVE(BELCH,HOP);
/*CALL TRIANGLEPLEX(ORDER);
  CALL SQUAREBASH(ORDER,+1);
  CALL SQUAREBASH(ORDER,-1);
  CALL SNOWFLAKE(ORDER);
  CALL SNOWFLAKE3(ORDER);
  CALL PURSUE(CHASE);
  CALL LISSAJOU(TWIRL);
  CALL CARDIOD;
  CALL HEART;*/
  CALL PLOT(0,0,-3); CALL PLOT(0,0,999);
END TEST;


import Text.Printf (printf)

linearForm :: [Int] -> String
linearForm = strip . concat . zipWith term [1..]
  where
    term :: Int -> Int -> String
    term i c = case c of
      0  -> mempty
      1  -> printf "+e(%d)" i
      -1 -> printf "-e(%d)" i
      c  -> printf "%+d*e(%d)" c i

    strip str = case str of
      '+':s -> s
      ""    -> "0"
      s     -> s


fourbanger=:3 :0
  e=. ('e(',')',~])@":&.> 1+i.#y
  firstpos=. 0< {.y-.0
  if. */0=y do. '0' else. firstpos}.;y gluedto e end.
)

gluedto=:4 :0 each
  pfx=. '+-' {~ x<0
  select. |x
    case. 0 do. ''
    case. 1 do. pfx,y
    case.   do. pfx,(":|x),'*',y
  end.
)


import java.util.Arrays;

public class LinearCombination {
    private static String linearCombo(int[] c) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < c.length; ++i) {
            if (c[i] == 0) continue;
            String op;
            if (c[i] < 0 && sb.length() == 0) {
                op = "-";
            } else if (c[i] < 0) {
                op = " - ";
            } else if (c[i] > 0 && sb.length() == 0) {
                op = "";
            } else {
                op = " + ";
            }
            int av = Math.abs(c[i]);
            String coeff = av == 1 ? "" : "" + av + "*";
            sb.append(op).append(coeff).append("e(").append(i + 1).append(')');
        }
        if (sb.length() == 0) {
            return "0";
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        int[][] combos = new int[][]{
            new int[]{1, 2, 3},
            new int[]{0, 1, 2, 3},
            new int[]{1, 0, 3, 4},
            new int[]{1, 2, 0},
            new int[]{0, 0, 0},
            new int[]{0},
            new int[]{1, 1, 1},
            new int[]{-1, -1, -1},
            new int[]{-1, -2, 0, -3},
            new int[]{-1},
        };
        for (int[] c : combos) {
            System.out.printf("%-15s  ->  %s\n", Arrays.toString(c), linearCombo(c));
        }
    }
}


10 REM First we draw the clock face
20 FOR n=1 TO 12
30 PRINT AT 10-10*COS (n/6*PI),16+10*SIN (n/6*PI);n
40 NEXT n
50 DEF FN t()=INT (65536*PEEK 23674+256*PEEK 23673+PEEK 23672)/50: REM number of seconds since start
100 REM Now we start the clock
110 LET t1=FN t()
120 LET a=t1/30*PI: REM a is the angle of the second hand in radians
130 LET sx=72*SIN a: LET sy=72*COS a
140 PLOT 131,91: DRAW OVER 1;sx,sy: REM draw hand
200 LET t=FN t()
210 IF INT t<=INT t1 THEN GO TO 200: REM wait for time for next hand; the INTs were not in the original but force it to wait for the next second
220 PLOT 131,91: DRAW OVER 1;sx,sy: REM rub out old hand
230 LET t1=t: GO TO 120


: vector create cells allot ;
: th cells + ;

3 constant /vector
/vector vector a
/vector vector b

: dotproduct                           ( a1 a2 -- n)
  0 tuck ?do -rot over i th @ over i th @ * >r rot r> + loop nip nip
;

: vector! cells over + swap ?do i ! 1 cells +loop ;

-5  3 1 a /vector vector!
-1 -2 4 b /vector vector!

a b /vector dotproduct . 3 ok


program test_dot_product

  write (*, '(i0)') dot_product ([1, 3, -5], [4, -2, -1])

end program test_dot_product


dotProduct[v1, v2] :=
{
   if length[v1] != length[v2]
   {
      println["dotProduct: vectors are of different lengths."]
      return undef
   }

   return sum[map[{|c1,c2| c1 * c2}, zip[v1, v2]]]
}


%!PS
%%BoundingBox: 0 0 550 400
/ifpendown false def
/rotation 0 def
/srootii 2 sqrt def
/turn {
         rotation add /rotation exch def
      } def
/forward {
            dup rotation cos mul
           exch rotation sin mul
           ifpendown
                { rlineto }
                { rmoveto }
           ifelse
         } def
/penup {
          /ifpendown false def
       } def
/pendown {
             /ifpendown true def
         } def

/dragon { % [ length, split, d ]
          dup
          dup 1 get 0 eq
              { 0 get forward }
              { dup 2 get 45 mul turn
                  dup aload pop pop
                  1 sub exch srootii div exch
                  1 3 array astore dragon pop
                dup 2 get 90 mul neg turn
                  dup aload pop pop
                  1 sub exch srootii div exch
                  -1 3 array astore dragon
                dup 2 get 45 mul turn
              }
          ifelse
          pop
        } def
150 150 moveto pendown [ 300 12 1 ] dragon stroke
% 0 0 moveto 550 0 rlineto 0 400 rlineto -550 0 rlineto closepath stroke
showpage
%%END


# handy constants with script-wide scope
[Single]$script:QUARTER_PI=0.7853982
[Single]$script:HALF_PI=1.570796

# leverage GDI (Forms and Drawing)
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms
$script:TurtlePen = New-Object Drawing.Pen darkGreen
$script:Form = New-Object Windows.Forms.Form
$script:Canvas = $Form.CreateGraphics()

# implement a turtle graphics model
Class Turtle { # relies on the script-scoped $TurtlePen and $Canvas
  # member properties for turtle's position and orientation
  [Single]$TurtleX
  [Single]$TurtleY
  [Single]$TurtleAngle

  # constructors
  Turtle() {
    $this.TurtleX, $this.TurtleY = 44.0, 88.0
    $this.TurtleAngle = 0.0
  }
  Turtle([Single]$InitX, [Single]$InitY, [Single]$InitAngle) {
    $this.TurtleX, $this.TurtleY = $InitX, $InitY
    $this.TurtleAngle = $InitAngle
  }

  # methods for turning and drawing
  [Void]Turn([Single]$Angle) {  # $Angle measured in radians
    $this.TurtleAngle += $Angle  # use positive $Angle for right turn, negative for left turn
  }
  [Void]Forward([Single]$Distance) {
    # draw line segment
    $TargetX = $this.TurtleX + $Distance * [Math]::Cos($this.TurtleAngle)
    $TargetY = $this.TurtleY + $Distance * [Math]::Sin($this.TurtleAngle)
    $script:Canvas.DrawLine($script:TurtlePen, $this.TurtleX, $this.TurtleY, $TargetX, $TargetY)
    # relocate turtle to other end of segment
    $this.TurtleX = $TargetX
    $this.TurtleY = $TargetY
  }
} # end of Turtle class definition

# Implement dragon curve drawing methods in a subclass that inherits Turtle
Class DragonTurtle : Turtle {

  # DCL: recursive dragon curve, starting with left turns
  [Void]DCL([Byte]$Step, [Single]$Length) {
    $AdjustedStep = $Step - 1
    $AdjustedLength = $Length / [Math]::Sqrt(2.0)

    $this.Turn(-$script:QUARTER_PI)
    if ($AdjustedStep -gt 0) {
      $this.DCR($AdjustedStep, $AdjustedLength)
    } else {
      $this.Forward($AdjustedLength)
    }
    $this.Turn($script:HALF_PI)
    if ($AdjustedStep -gt 0) {
      $this.DCL($AdjustedStep, $AdjustedLength)
    } else {
      $this.Forward($AdjustedLength)
    }
    $this.Turn(-$script:QUARTER_PI)
  }

  # DCR: recursive dragon curve, starting with right turns
  [Void]DCR([Byte]$Step, [Single]$Length) {
    $AdjustedStep = $Step - 1
    $AdjustedLength = $Length / [Math]::Sqrt(2.0)

    $this.Turn($script:QUARTER_PI)
    if ($AdjustedStep -gt 0) {
      $this.DCR($AdjustedStep, $AdjustedLength)
    } else {
      $this.Forward($AdjustedLength)
    }
    $this.Turn(-$script:HALF_PI)
    if ($AdjustedStep -gt 0) {
      $this.DCL($AdjustedStep, $AdjustedLength)
    } else {
      $this.Forward($AdjustedLength)
    }
    $this.Turn($script:QUARTER_PI)
  }
} # end of DragonTurtle subclass definition

# prepare anonymous dragon-curve painting function for WinForms dialog
$Form.add_paint({
  [DragonTurtle]$Dragon = [DragonTurtle]::new()
  $Dragon.DCR(14,128)
})

# display the GDI Form window, which triggers its prepared anonymous drawing function
$Form.ShowDialog()


def linearCombo:
  reduce to_entries[] as {key: $k,value: $v} ("";
     if $v == 0 then .
     else
        (if $v < 0 and length==0 then   "-"
         elif $v < 0 then               " - "
         elif $v > 0 and length==0 then ""
         else                           " + "
         end) as $sign
        | ($v|fabs) as $av
        | (if ($av == 1) then "" else "\($av)*" end) as $coeff
        | .  + "\($sign)\($coeff)e\($k)"
     end)
  | if length==0 then "0" else . end ;

# The exercise
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;

[1, 2, 3],
[0, 1, 2, 3],
[1, 0, 3, 4],
[1, 2, 0],
[0, 0, 0],
[0],
[1, 1, 1],
[-1, -1, -1],
[-1, -2, 0, -3],
[-1]
| "\(lpad(15)) => \(linearCombo)"


// version 1.1.2

fun linearCombo(c: IntArray): String {
    val sb = StringBuilder()
    for ((i, n) in c.withIndex()) {
        if (n == 0) continue
        val op = when {
            n < 0 && sb.isEmpty() -> "-"
            n < 0                 -> " - "
            n > 0 && sb.isEmpty() -> ""
            else                  -> " + "
        }
        val av = Math.abs(n)
        val coeff = if (av == 1) "" else "$av*"
        sb.append("$op${coeff}e(${i + 1})")
    }
    return if(sb.isEmpty()) "0" else sb.toString()
}

fun main(args: Array<String>) {
    val combos = arrayOf(
        intArrayOf(1, 2, 3),
        intArrayOf(0, 1, 2, 3),
        intArrayOf(1, 0, 3, 4),
        intArrayOf(1, 2, 0),
        intArrayOf(0, 0, 0),
        intArrayOf(0),
        intArrayOf(1, 1, 1),
        intArrayOf(-1, -1, -1),
        intArrayOf(-1, -2, 0, -3),
        intArrayOf(-1)
    )
    for (c in combos) {
        println("${c.contentToString().padEnd(15)}  ->  ${linearCombo(c)}")
    }
}


import lists.zipWith

def dot( a, b )
  | a.length() == b.length() = sum( zipWith((*), a, b) )
  | otherwise = error( "Vector sizes must match" )

println( dot([1, 3, -5], [4, -2, -1]) )


#define NAN 0.0/0.0  'dot product of different-dimensioned vectors is no more defined than 0/0

function dot( a() as double, b() as double ) as double
    if ubound(a)<>ubound(b) then return NAN
    dim as uinteger i
    dim as double dp = 0.0
    for i = 0 to ubound(a)
        dp += a(i)*b(i)
    next i
    return dp
end function

dim as double zero3d(0 to 2) = {0.0, 0.0, 0.0}     'some example vectors
dim as double zero5d(0 to 4) = {0.0, 0.0, 0.0, 0.0, 0.0}
dim as double x(0 to 2) = {1.0, 0.0, 0.0}
dim as double y(0 to 2) = {0.0, 1.0, 0.0}
dim as double z(0 to 2) = {0.0, 0.0, 1.0}
dim as double q(0 to 2) = {1.0, 1.0, 3.14159}
dim as double r(0 to 2) = {-1.0, 2.618033989, 3.0}

print " q dot r           = ", dot(q(), r())
print " zero3d dot zero5d = ", dot(zero3d(), zero5d())
print " zero3d dot x      = ", dot(zero3d(), x())
print " z dot z           = ", dot(z(), z())
print " y dot z           = ", dot(y(), z())


{def linearcomb
 {def linearcomb.r
  {lambda {:a :n :i}
   {if {= :i :n}
    then
    else {let { {:e e({+ :i 1})}
                {:v {abs {A.get :i :a}}}
                {:s {if {< {A.get :i :a} 0} then - else +}}
              } {if {= :v 0} then  else
                {if {= :v 1} then :s :e else :s :v*:e}}}
         {linearcomb.r :a :n {+ :i 1}} }}}
 {lambda {:a}
  {S.replace _LAMB_[^\s]+ by 0 in
   {let { {:r {linearcomb.r {A.new :a} {S.length :a} 0}}
        } {if {W.equal? {S.first :r} +} then {S.rest :r} else :r} }}}}
-> linearcomb

{linearcomb 1 2 3}      -> e(1) + 2*e(2) + 3*e(3)
{linearcomb -1 -2 0 -3} -> - e(1) - 2*e(2) - 3*e(4)
{linearcomb 0 1 2 3}    -> e(2) + 2*e(3) + 3*e(4)
{linearcomb 1 0 3 4}    -> e(1) + 3*e(3) + 4*e(4)
{linearcomb 1 2 0}      -> e(1) + 2*e(2)
{linearcomb 0 0 0}      -> 0
{linearcomb 0}          -> 0
{linearcomb 1 1 1}      -> e(1) + e(2) + e(3)
{linearcomb -1 -1 -1}   -> - e(1) - e(2) - e(3)
{linearcomb -1}         -> - e(1)


float l = 3;
int ints = 13;

void setup() {
  size(700, 600);
  background(0, 0, 255);
  translate(150, 100);
  stroke(255);
  turn_left(l, ints);
  turn_right(l, ints);
}

void turn_right(float l, int ints) {
  if (ints == 0) {
    line(0, 0, 0, -l);
    translate(0, -l);
  } else {
    turn_left(l, ints-1);
    rotate(radians(90));
    turn_right(l, ints-1);
  }
}

void turn_left(float l, int ints) {
  if (ints == 0) {
    line(0, 0, 0, -l);
    translate(0, -l);
  } else {
    turn_left(l, ints-1);
    rotate(radians(-90));
    turn_right(l, ints-1);
  }
}


function t2s(t)
    local s = "["
    for i,v in pairs(t) do
        if i > 1 then
            s = s .. ", " .. v
        else
            s = s .. v
        end
    end
    return s .. "]"
end

function linearCombo(c)
    local sb = ""
    for i,n in pairs(c) do
        local skip = false

        if n < 0 then
            if sb:len() == 0 then
                sb = sb .. "-"
            else
                sb = sb .. " - "
            end
        elseif n > 0 then
            if sb:len() ~= 0 then
                sb = sb .. " + "
            end
        else
            skip = true
        end

        if not skip then
            local av = math.abs(n)
            if av ~= 1 then
                sb = sb .. av .. "*"
            end
            sb = sb .. "e(" .. i .. ")"
        end
    end
    if sb:len() == 0 then
        sb = "0"
    end
    return sb
end

function main()
    local combos = {
        {  1,  2,  3},
        {  0,  1,  2,  3 },
        {  1,  0,  3,  4 },
        {  1,  2,  0 },
        {  0,  0,  0 },
        {  0 },
        {  1,  1,  1 },
        { -1, -1, -1 },
        { -1, -2, 0, -3 },
        { -1 }
    }

    for i,c in pairs(combos) do
        local arr = t2s(c)
        print(string.format("%15s -> %s", arr, linearCombo(c)))
    end
end

main()


package main

import (
    "errors"
    "fmt"
    "log"
)

var (
    v1 = []int{1, 3, -5}
    v2 = []int{4, -2, -1}
)

func dot(x, y []int) (r int, err error) {
    if len(x) != len(y) {
        return 0, errors.New("incompatible lengths")
    }
    for i, xi := range x {
        r += xi * y[i]
    }
    return
}

func main() {
    d, err := dot([]int{1, 3, -5}, []int{4, -2, -1})
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(d)
}


def dotProduct = { x, y ->
    assert x && y && x.size() == y.size()
    [x, y].transpose().collect{ xx, yy -> xx * yy }.sum()
}


dragonCurve(N) :-
	dcg_dg(N, [left], DCL, []),
	Side = 4,
	Angle is -N * (pi/4),
	dcg_computePath(Side, Angle, DCL, point(180,400), P, []),
	new(D, window('Dragon Curve')),
	send(D, size, size(800,600)),
	new(Path, path(poly)),
	send_list(Path, append, P),
	send(D, display, Path),
	send(D, open).

% compute the list of points of the Dragon Curve
dcg_computePath(Side, Angle, [left | DCT], point(X1, Y1)) -->
	   [point(X1, Y1)],
	   {	X2 is X1 + Side * cos(Angle),
		Y2 is Y1 + Side * sin(Angle),
		Angle1 is Angle + pi / 2
	   },
	   dcg_computePath(Side, Angle1, DCT, point(X2, Y2)).

dcg_computePath(Side, Angle, [right | DCT], point(X1, Y1)) -->
	   [point(X1, Y1)],
	   {	X2 is X1 + Side * cos(Angle),
		Y2 is Y1 + Side * sin(Angle),
		Angle1 is Angle - pi / 2
	   },
	   dcg_computePath(Side, Angle1, DCT, point(X2, Y2)).

dcg_computePath(_Side, _Angle, [], point(X1, Y1)) -->
	[ point(X1, Y1)].

% compute the list of the "turns" of the Dragon Curve
dcg_dg(1, L) --> L.

dcg_dg(N, L) -->
	{dcg_dg(L, L1, []),
	  N1 is N - 1},
	  dcg_dg(N1, L1).

% one interation of the process
dcg_dg(L) -->
	L,
	[left],
	inverse(L).

inverse([H | T]) -->
	inverse(T),
	inverse(H).

inverse([]) --> [].

inverse(left) -->
	[right].

inverse(right) -->
	[left].


MODULE Linear;
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;

PROCEDURE WriteInt(n : INTEGER);
VAR buf : ARRAY[0..15] OF CHAR;
BEGIN
    FormatString("%i", buf, n);
    WriteString(buf)
END WriteInt;

PROCEDURE WriteLinear(c : ARRAY OF INTEGER);
VAR
    buf : ARRAY[0..15] OF CHAR;
    i,j : CARDINAL;
    b : BOOLEAN;
BEGIN
    b := TRUE;
    j := 0;

    FOR i:=0 TO HIGH(c) DO
        IF c[i]=0 THEN CONTINUE END;

        IF c[i]<0 THEN
            IF b THEN WriteString("-")
            ELSE      WriteString(" - ") END;
        ELSIF c[i]>0 THEN
            IF NOT b THEN WriteString(" + ") END;
        END;

        IF c[i] > 1 THEN
            WriteInt(c[i]);
            WriteString("*")
        ELSIF c[i] < -1 THEN
            WriteInt(-c[i]);
            WriteString("*")
        END;

        FormatString("e(%i)", buf, i+1);
        WriteString(buf);

        b := FALSE;
        INC(j)
    END;

    IF j=0 THEN WriteString("0") END;
    WriteLn
END WriteLinear;

TYPE
    Array1 = ARRAY[0..0] OF INTEGER;
    Array3 = ARRAY[0..2] OF INTEGER;
    Array4 = ARRAY[0..3] OF INTEGER;
BEGIN
    WriteLinear(Array3{1,2,3});
    WriteLinear(Array4{0,1,2,3});
    WriteLinear(Array4{1,0,3,4});
    WriteLinear(Array3{1,2,0});
    WriteLinear(Array3{0,0,0});
    WriteLinear(Array1{0});
    WriteLinear(Array3{1,1,1});
    WriteLinear(Array3{-1,-1,-1});
    WriteLinear(Array4{-1,-2,0,-3});
    WriteLinear(Array1{-1});

    ReadChar
END Linear.


dotp :: Num a => [a] -> [a] -> a
dotp a b | length a == length b = sum (zipWith (*) a b)
         | otherwise = error "Vector sizes must match"

main = print $ dotp [1, 3, -5] [4, -2, -1] -- prints 3


|=  [a=(list @sd) b=(list @sd)]
  =|  [email protected]
  |-
  ?:  |(?=(~ a) ?=(~ b))  sum
  $(a t.a, b t.b, sum (sum:si sum (pro:si i.a i.b)))


(defn dotp [a b]
  (assert (= (len a) (len b)))
  (sum (genexpr (* aterm bterm)
                [(, aterm bterm) (zip a b)])))

(assert (= 3 (dotp [1 3 -5] [4 -2 -1])))


#SqRt2 = 1.4142136
#SizeH = 800: #SizeV = 550
Global angle.d, px, py, imageNum

Procedure turn(degrees.d)
  angle + degrees * #PI / 180
EndProcedure

Procedure forward(length.d)
  Protected w = Cos(angle) * length
  Protected h = Sin(angle) * length
  LineXY(px, py, px + w, py + h, RGB(255,255,255))
  px + w: py + h
EndProcedure

Procedure dragon(length.d, split, d.d)
  If split = 0
    forward(length)
  Else
    turn(d * 45)
    dragon(length / #SqRt2, split - 1, 1)
    turn(-d * 90)
    dragon(length / #SqRt2, split - 1, -1)
    turn(d * 45)
  EndIf
EndProcedure

OpenWindow(0, 0, 0, #SizeH, #SizeV, "DragonCurve", #PB_Window_SystemMenu)
imageNum = CreateImage(#PB_Any, #SizeH, #SizeV, 32)
ImageGadget(0, 0, 0, 0, 0, ImageID(imageNum))

angle = 0: px = 185: py = 190
If StartDrawing(ImageOutput(imageNum))
    dragon(400, 15, 1)
  StopDrawing()
  SetGadgetState(0, ImageID(imageNum))
EndIf

Repeat: Until WaitWindowEvent(10) = #PB_Event_CloseWindow


import strformat

proc linearCombo(c: openArray[int]): string =

  for i, n in c:
    if n == 0: continue
    let op = if n < 0:
               if result.len == 0: "-" else: " - "
             else:
               if n > 0 and result.len == 0: "" else: " + "
    let av = abs(n)
    let coeff = if av == 1: "" else: $av & '*'
    result &= fmt"{op}{coeff}e({i + 1})"
  if result.len == 0:
    result = "0"

const Combos = [@[1, 2, 3],
                @[0, 1, 2, 3],
                @[1, 0, 3, 4],
                @[1, 2, 0],
                @[0, 0, 0],
                @[0],
                @[1, 1, 1],
                @[-1, -1, -1],
                @[-1, -2, 0, -3],
                @[-1]]

for c in Combos:
  echo fmt"{($c)[1..^1]:15}  →  {linearCombo(c)}"


procedure main()
write("a dot b := ",dotproduct([1, 3, -5],[4, -2, -1]))
end

procedure dotproduct(a,b)   #: return dot product of vectors a & b or error
if *a ~= *b & type(a) == type(b) == "list" then runerr(205,a) # invalid value
every (dp := 0) +:= a[i := 1 to *a] * b[i]
return dp
end


a = [1, 3, -5]
b = [4, -2, -1]
c = a#TRANSPOSE(b)
c = TOTAL(a*b,/PRESERVE_TYPE)