from turtle import *

def dragon(step, length):
    dcr(step, length)

def dcr(step, length):
    step -= 1
    length /= 1.41421
    if step > 0:
        right(45)
        dcr(step, length)
        left(90)
        dcl(step, length)
        right(45)
    else:
        right(45)
        forward(length)
        left(90)
        forward(length)
        right(45)

def dcl(step, length):
    step -= 1
    length /= 1.41421

    if step > 0:
        left(45)
        dcr(step, length)
        right(90)
        dcl(step, length)
        left(45)
    else:
        left(45)
        forward(length)
        right(90)
        forward(length)
        left(45)


 [ $ "turtleduck.qky" loadfile ] now!

 [ 2 *
   2dup turn
   4 1 walk
   turn ]                        is corner ( n/d --> )

                         forward is right  (   n --> )

                         forward is left   (   n --> )

 [ dup 0 = iff
     [ drop 8 1 walk ] done
   1 - dup
   left
   1 4 corner
   right ]                 resolves right  (   n --> )

 [ dup 0 = iff
     [ drop 8 1 walk ] done
   1 - dup
   left
   -1 4 corner
   right ]                 resolves left   (   n --> )

turtle
-260 1 fly
3 4 turn
100 1 fly
5 8 turn
11 left


with javascript_semantics
function linear_combination(sequence f)
    string res = ""
    for e=1 to length(f) do
        integer fe = f[e]
        if fe!=0 then
            if fe=1 then
                if length(res) then res &= "+" end if
            elsif fe=-1 then
                res &= "-"
            elsif fe>0 and length(res) then
                res &= sprintf("+%d*",fe)
            else
                res &= sprintf("%d*",fe)
            end if
            res &= sprintf("e(%d)",e)
        end if
    end for
    if res="" then res = "0" end if
    return res
end function

constant tests = {{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=1 to length(tests) do
    sequence ti = tests[i]
    printf(1,"%12s -> %s\n",{sprint(ti), linear_combination(ti)})
end for


module Main

import Data.Vect

dotProduct : (Num a) => Vect n a -> Vect n a -> a
dotProduct = (sum .) . zipWith (*)

main : IO ()
main = printLn $ dotProduct [1,2,3] [1,2,3]


Dragon<-function(Iters){
  Rotation<-matrix(c(0,-1,1,0),ncol=2,byrow=T) ########Rotation multiplication matrix
  Iteration<-list() ###################################Set up list for segment matrices for 1st
  Iteration[[1]] <- matrix(rep(0,16), ncol = 4)
  Iteration[[1]][1,]<-c(0,0,1,0)
  Iteration[[1]][2,]<-c(1,0,1,-1)
  Moveposition<-rep(0,Iters) ##########################Which point should be shifted to origin
  Moveposition[1]<-4
  if(Iters > 1){#########################################where to move to get to origin
    for(l in 2:Iters){#####################################only if >1, because 1 set before for loop
      Moveposition[l]<-(Moveposition[l-1]*2)-2#############sets vector of all positions in matrix where last point is
    }}
  Move<-list() ########################################vector to add to all points to shift start at origin
for (i in 1:Iters){
half<-dim(Iteration[[i]])[1]/2
half<-1:half
for(j in half){########################################Rotate all points 90 degrees clockwise
  Iteration[[i]][j+length(half),]<-c(Iteration[[i]][j,1:2]%*%Rotation,Iteration[[i]][j,3:4]%*%Rotation)
}
Move[[i]]<-matrix(rep(0,4),ncol=4)
Move[[i]][1,1:2]<-Move[[i]][1,3:4]<-(Iteration[[i]][Moveposition[i],c(3,4)]*-1)
Iteration[[i+1]]<-matrix(rep(0,2*dim(Iteration[[i]])[1]*4),ncol=4)##########move the dragon, set next Iteration's matrix
for(k in 1:dim(Iteration[[i]])[1]){#########################################move dragon by shifting all previous iterations point
  Iteration[[i+1]][k,]<-Iteration[[i]][k,]+Move[[i]]###so the start is at the origin
}
xlimits<-c(min(Iteration[[i]][,3])-2,max(Iteration[[i]][,3]+2))#Plot
ylimits<-c(min(Iteration[[i]][,4])-2,max(Iteration[[i]][,4]+2))
plot(0,0,type='n',axes=FALSE,xlab="",ylab="",xlim=xlimits,ylim=ylimits)
s<-dim(Iteration[[i]])[1]
s<-1:s
segments(Iteration[[i]][s,1], Iteration[[i]][s,2], Iteration[[i]][s,3], Iteration[[i]][s,4], col= 'red')
}}#########################################################################


#lang racket

(require plot)

(define (dragon-turn n)
  (if (> (bitwise-and (arithmetic-shift (bitwise-and n (- n)) 1) n) 0)
      'L
      'R))

(define (rotate heading dir)
  (cond
    [(eq? dir 'R) (cond [(eq? heading 'N) 'E]
                        [(eq? heading 'E) 'S]
                        [(eq? heading 'S) 'W]
                        [(eq? heading 'W) 'N])]
    [(eq? dir 'L) (cond [(eq? heading 'N) 'W]
                        [(eq? heading 'E) 'N]
                        [(eq? heading 'S) 'E]
                        [(eq? heading 'W) 'S])]))
(define (step pos heading)
  (cond
    [(eq? heading 'N) (list (car pos) (add1 (cadr pos)))]
    [(eq? heading 'E) (list (add1 (car pos)) (cadr pos))]
    [(eq? heading 'S) (list (car pos) (sub1 (cadr pos)))]
    [(eq? heading 'W) (list (sub1 (car pos)) (cadr pos))]
    ))

(let-values ([(dir pos trail)
              (for/fold ([dir 'N]
                         [pos (list 0 0)]
                         [trail '((0 0))])
                ([n (in-range 0 50000)])
                (let* ([new-dir (rotate dir (dragon-turn n))]
                       [new-pos (step pos new-dir)])
                  (values new-dir
                          new-pos
                          (cons new-pos trail))))])
  (plot-file (lines trail) "dragon.png" 'png))


; Process and output values.
Procedure WriteLinear(Array c.i(1))
  Define buf$,
         i.i, j.i, b,i

  b = #True
  j = 0

  For i = 0 To ArraySize(c(), 1)
    If c(i) = 0 : Continue : EndIf

    If c(i) < 0
      If b : Print("-") : Else : Print(" - ") : EndIf
    ElseIf c(i) > 0
      If Not b : Print(" + ") : EndIf
    EndIf

    If c(i) > 1
      Print(Str(c(i))+"*")
    ElseIf c(i) < -1
      Print(Str(-c(i))+"*")
    EndIf

    Print("e("+Str(i+1)+")")

    b = #False
    j+1
  Next

  If j = 0 : Print("0") : EndIf
  PrintN("")
EndProcedure

Macro VectorHdl(Adr_Start, Adr_Stop)
  ; 1. Output of the input values
  Define buf$ = "[", *adr_ptr
  For *adr_ptr = Adr_Start To Adr_Stop - SizeOf(Integer) Step SizeOf(Integer)
    buf$ + Str(PeekI(*adr_ptr))
    If *adr_ptr >= Adr_Stop - SizeOf(Integer)
      buf$ + "]  ->  "
    Else
      buf$ + ", "
    EndIf
  Next
  buf$ =  RSet(buf$, 25)
  Print(buf$)

  ; 2. Reserve memory, pass and process values.
  Dim a.i((Adr_Stop - Adr_Start) / SizeOf(Integer) -1)
  CopyMemory(Adr_Start, @a(0), Adr_Stop - Adr_Start)
  WriteLinear(a())
EndMacro

If OpenConsole("")
  ; Pass memory addresses of the data.
  VectorHdl(?V1, ?_V1)
  VectorHdl(?V2, ?_V2)
  VectorHdl(?V3, ?_V3)
  VectorHdl(?V4, ?_V4)
  VectorHdl(?V5, ?_V5)
  VectorHdl(?V6, ?_V6)
  VectorHdl(?V7, ?_V7)
  VectorHdl(?V8, ?_V8)
  VectorHdl(?V9, ?_V9)
  VectorHdl(?V10, ?_V10)

  Input()
EndIf

End 0

DataSection
  V1:
  Data.i 1,2,3
  _V1:
  V2:
  Data.i 0,1,2,3
  _V2:
  V3:
  Data.i 1,0,3,4
  _V3:
  V4:
  Data.i 1,2,0
  _V4:
  V5:
  Data.i 0,0,0
  _V5:
  V6:
  Data.i 0
  _V6:
  V7:
  Data.i 1,1,1
  _V7:
  V8:
  Data.i -1,-1,-1
  _V8:
  V9:
  Data.i -1,-2,0,-3
  _V9:
  V10:
  Data.i -1
  _V10:
EndDataSection


   1 3 _5  +/ . * 4 _2 _1
3
   dotp=: +/ . *                  NB. Or defined as a verb (function)
   1 3 _5  dotp 4 _2 _1
3


public class DotProduct {

	public static void main(String[] args) {
		double[] a = {1, 3, -5};
		double[] b = {4, -2, -1};

		System.out.println(dotProd(a,b));
	}

	public static double dotProd(double[] a, double[] b){
		if(a.length != b.length){
			throw new IllegalArgumentException("The dimensions have to be equal!");
		}
		double sum = 0;
		for(int i = 0; i < a.length; i++){
			sum += a[i] * b[i];
		}
		return sum;
	}
}


use SVG;

role Lindenmayer {
    has %.rules;
    method succ {
	    self.comb.map( { %!rules{$^c} // $c } ).join but Lindenmayer(%!rules)
    }
}

my $dragon = "FX" but Lindenmayer( { X => 'X+YF+', Y => '-FX-Y' } );

$dragon++ xx ^15;

my @points = 215, 350;

for $dragon.comb {
    state ($x, $y) = @points[0,1];
    state $d = 2 + 0i;
    if /'F'/ { @points.append: ($x += $d.re).round(.1), ($y += $d.im).round(.1) }
    elsif /< + - >/ { $d *= "{$_}1i" }
}

say SVG.serialize(
    svg => [
        :600width, :450height, :style<stroke:rgb(0,0,255)>,
        :rect[:width<100%>, :height<100%>, :fill<white>],
        :polyline[ :points(@points.join: ','), :fill<white> ],
    ],
);


#lang racket/base
(require racket/match racket/string)

(define (linear-combination->string es)
  (let inr ((es es) (i 1) (rv ""))
    (match* (es rv)
      [((list) "") "0"]
      [((list) rv) rv]
      [((list (? zero?) t ...) rv)
       (inr t (add1 i) rv)]
      [((list n t ...) rv)
       (define ±n
         (match* (n rv)
           ;; zero is handled above
           [(1 "") ""]
           [(1 _) "+"]
           [(-1 _) "-"]
           [((? positive? n) (not "")) (format "+~a*" n)]
           [(n _) (format "~a*" n)]))
       (inr t (add1 i) (string-append rv ±n "e("(number->string i)")"))])))

(for-each
 (compose displayln linear-combination->string)
 '((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)))


function dot_product(ary1, ary2) {
    if (ary1.length != ary2.length)
        throw "can't find dot product: arrays have different lengths";
    var dotprod = 0;
    for (var i = 0; i < ary1.length; i++)
        dotprod += ary1[i] * ary2[i];
    return dotprod;
}

print(dot_product([1,3,-5],[4,-2,-1])); // ==> 3
print(dot_product([1,3,-5],[4,-2,-1,0])); // ==> exception


def dot(x; y):
  reduce range(0;x|length) as $i (0; . + x[$i] * y[$i]);


DIM angle AS Double
DIM x  AS Double, y AS Double
DECLARE SUB PaintCanvas

CREATE form AS QForm
    Width  = 800
    Height = 600
    CREATE canvas AS QCanvas
        Height = form.ClientHeight
        Width  = form.ClientWidth
        OnPaint = PaintCanvas
    END CREATE
END CREATE

SUB turn (degrees AS Double)
    angle = angle + degrees*3.14159265/180
END SUB

SUB forward (length AS Double)
    x2 = x + cos(angle)*length
    y2 = y + sin(angle)*length
    canvas.Line(x, y, x2, y2, &Haaffff)
    x = x2: y = y2
END SUB

SUB dragon (length AS Double, split AS Integer, d AS Double)
    IF split=0 THEN
        forward length
    ELSE
        turn d*45
        dragon length/1.4142136, split-1, 1
        turn -d*90
        dragon length/1.4142136, split-1, -1
        turn d*45
    END IF
END SUB

SUB PaintCanvas
    canvas.FillRect(0, 0, canvas.Width, canvas.Height, &H102800)
    x = 220: y = 220: angle = 0
    dragon 384, 12, 1
END SUB

form.ShowModal


/*REXX program creates & draws an ASCII  Dragon Curve (or Harter-Heighway dragon curve).*/
d.= 1;   d.L= -d.;    @.= ' ';    x= 0;    x2= x;   y= 0;   y2= y;    z= d.;    @.x.y= "∙"
plot_pts = '123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZΘ' /*plot chars*/
loX= 0;     hiX= 0;     loY= 0;   hiY= 0         /*assign various constants & variables.*/
parse arg # p c .                                /*#:  number of iterations; P=init dir.*/
if #=='' | #==","  then #= 11                    /*Not specified?  Then use the default.*/
if p=='' | p==","  then p= 'north';     upper p  /* "      "         "   "   "     "    */
if c==''           then c= plot_pts              /* "      "         "   "   "     "    */
if length(c)==2    then c= x2c(c)                /*was a  hexadecimal  code specified?  */
if length(c)==3    then c= d2c(c)                /* "  "    decimal      "      "       */
p= translate( left(p, 1), 0123, 'NESW')          /*get the orientation for dragon curve.*/
$=                                               /*initialize the dragon curve to a null*/
    do #                                         /*create the start of a dragon curve.  */
    $= $'R'reverse( translate($, "RL", 'LR') )   /*append the rest of dragon curve.     */
    end   /*#*/                                  /* [↑]  append char, flip, and reverse.*/

  do j=1  for length($);     _= substr($, j, 1)  /*get next cardinal direction for curve*/
  p= (p + d._) // 4                              /*move dragon curve in a new direction.*/
  if p< 0  then p= p + 4                         /*Negative?  Then use a new direction. */
  if p==0  then do;  y= y + 1;  y2= y + 1;  end  /*curve is going  east  cartologically.*/
  if p==1  then do;  x= x + 1;  x2= x + 1;  end  /*  "    "       south         "       */
  if p==2  then do;  y= y - 1;  y2= y - 1;  end  /*  "    "        west         "       */
  if p==3  then do;  x= x - 1;  x2= x - 1;  end  /*  "    "       north         "       */
  if j>2**z  then z= z + 1                       /*identify a part of curve being built.*/
  != substr(c, z, 1)                             /*choose plot point character (glyph). */
  if !==' '  then != right(c, 1)                 /*Plot point a blank?  Then use a glyph*/
  @.x.y= !;            @.x2.y2= !                /*draw part of the  dragon curve.      */
  loX= min(loX,x,x2);  hiX= max(hiX,x,x2); x= x2 /*define the min & max  X  graph limits*/
  loY= min(loY,y,y2);  hiY= max(hiY,y,y2); y= y2 /*   "    "   "  "  "   Y    "     "   */
  end   /*j*/                                    /* [↑]  process all of  $  char string.*/
              do r=loX  to hiX;     a=           /*nullify the line that will be drawn. */
                do c=loY  to hiY;  a= a || @.r.c /*create a line (row) of curve points. */
                end   /*c*/                      /* [↑] append a single column of a row.*/
              if a\==''  then say strip(a, "T")  /*display a line (row) of curve points.*/
              end      /*r*/                     /*stick a fork in it,  we're all done. */


/*REXX program displays a   finite liner combination   in an   infinite vector basis.   */
@.= .;           @.1  =    '  1,  2,  3     '    /*define a specific test case for build*/
                 @.2  =    '  0,  1,  2,  3 '    /*   "   "     "      "    "   "    "  */
                 @.3  =    '  1,  0,  3,  4 '    /*   "   "     "      "    "   "    "  */
                 @.4  =    '  1,  2,  0     '    /*   "   "     "      "    "   "    "  */
                 @.5  =    '  0,  0,  0     '    /*   "   "     "      "    "   "    "  */
                 @.6  =       0                  /*   "   "     "      "    "   "    "  */
                 @.7  =    '  1,  1,  1     '    /*   "   "     "      "    "   "    "  */
                 @.8  =    ' -1, -1, -1     '    /*   "   "     "      "    "   "    "  */
                 @.9  =    ' -1, -2,  0, -3 '    /*   "   "     "      "    "   "    "  */
                 @.10 =      -1                  /*   "   "     "      "    "   "    "  */
  do j=1  while  @.j\==.;        n= 0            /*process each vector; zero element cnt*/
  y= space( translate(@.j, ,',') )               /*elide commas and superfluous blanks. */
  $=                                             /*nullify  output  (liner combination).*/
       do k=1  for words(y);     #= word(y, k)   /* ◄───── process each of the elements.*/
       if #=0  then iterate;     a= abs(# / 1)   /*if the value is zero, then ignore it.*/
       if #<0  then s= '- '                      /*define the sign:   minus (-).        */
               else s= '+ '                      /*   "    "    "     plus  (+).        */
       n= n + 1                                  /*bump the number of elements in vector*/
       if n==1  then s= strip(s)                 /*if the 1st element used, remove blank*/
       if a\==1    then s= s  ||  a'*'           /*if multiplier is unity, then ignore #*/
       $= $  s'e('k")"                           /*construct a liner combination element*/
       end   /*k*/
  $= strip( strip($), 'L', "+")                  /*strip leading plus sign (1st element)*/
  if $==''  then $= 0                            /*handle special case of no elements.  */
  say right( space(@.j), 20)  ' ──► '   strip($) /*align the output for presentation.   */
  end       /*j*/                                /*stick a fork in it,  we're all done. */


/* Dot product, in Jsish */
function dot_product(ary1, ary2) {
    if (ary1.length != ary2.length) throw "can't find dot product: arrays have different lengths";
    var dotprod = 0;
    for (var i = 0; i < ary1.length; i++) dotprod += ary1[i] * ary2[i];
    return dotprod;
}

;dot_product([1,3,-5],[4,-2,-1]);
;//dot_product([1,3,-5],[4,-2,-1,0]);

/*
=!EXPECTSTART!=
dot_product([1,3,-5],[4,-2,-1]) ==> 3
dot_product([1,3,-5],[4,-2,-1,0]) ==>
PASS!: err = can't find dot product: arrays have different lengths
=!EXPECTEND!=
*/


Point = Struct.new(:x, :y)
Line = Struct.new(:start, :stop)

Shoes.app(:width => 800, :height => 600, :resizable => false) do

  def split_segments(n)
    dir = 1
    @segments = @segments.inject([]) do |new, l|
      a, b, c, d = l.start.x, l.start.y, l.stop.x, l.stop.y

      mid_x = a + (c-a)/2.0 - (d-b)/2.0*dir
      mid_y = b + (d-b)/2.0 + (c-a)/2.0*dir
      mid_p = Point.new(mid_x, mid_y)

      dir *= -1
      new << Line.new(l.start, mid_p)
      new << Line.new(mid_p, l.stop)
    end
  end

  @segments = [Line.new(Point.new(200,200), Point.new(600,200))]
  15.times do |n|
    info "calculating frame #{n}"
    split_segments(n)
  end

  stack do
    @segments.each do |l|
      line l.start.x, l.start.y, l.stop.x, l.stop.y
    end
  end
end


# Project : Display a linear combination

scalars = [[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=1 to len(scalars)
    str = ""
    for m=1 to len(scalars[n])
        scalar = scalars[n] [m]
        if scalar != "0"
           if scalar = 1
              str = str + "+e" + m
           elseif  scalar = -1
              str = str + "" + "-e" + m
           else
              if scalar > 0
                 str = str + char(43) + scalar + "*e" + m
              else
                 str = str + "" + scalar + "*e" + m
              ok
           ok
        ok
    next
    if str = ""
       str = "0"
    ok
    if left(str, 1) = "+"
       str = right(str, len(str)-1)
    ok
    see str + nl
next


def linearCombo(c)
    sb = ""
    c.each_with_index { |n, i|
        if n == 0 then
            next
        end
        if n < 0 then
            if sb.length == 0 then
                op = "-"
            else
                op = " - "
            end
        elsif n > 0 then
            if sb.length > 0 then
                op = " + "
            else
                op = ""
            end
        else
            op = ""
        end
        av = n.abs()
        if av != 1 then
            coeff = "%d*" % [av]
        else
            coeff = ""
        end
        sb = sb + "%s%se(%d)" % [op, coeff, i + 1]
    }
    if sb.length == 0 then
        return "0"
    end
    return sb
end

def main
    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 do
        print "%-15s  ->  %s\n" % [c, linearCombo(c)]
    end
end

main()


:sq_mul
    %c %i
    ( ) !c
    len [
        !i
        $i get rot $i get rot * $c swap 0 put !c
    ] for
    $c
;

:sq_sum
    0 swap
    len [
        get rot + swap
    ] for
    swap
;

( 1 3 -5 ) ( 4 -2 -1 )
sq_mul
sq_sum
pstack

" " input


fun dot(v1: Array<Double>, v2: Array<Double>) =
    v1.zip(v2).map { it.first * it.second }.reduce { a, b -> a + b }

fun main(args: Array<String>) {
    dot(arrayOf(1.0, 3.0, -5.0), arrayOf(4.0, -2.0, -1.0)).let { println(it) }
}


graphic #g, 600,600
RL$    = "R"
loc    = 90
pass   = 0

[loop]
#g "cls ; home ; north ; down ; fill black"
for i =1 to len(RL$)
  v = 255 * i /len(RL$)
  #g "color "; v; " 120 "; 255 -v
  #g "go "; loc
  if mid$(RL$,i,1) ="R" then #g "turn 90" else #g "turn -90"
next i

#g "color 255 120 0"
#g "go "; loc
LR$ =""
for i =len( RL$) to 1 step -1
  if mid$( RL$, i, 1) ="R" then LR$ =LR$ +"L" else LR$ =LR$ +"R"
next i

RL$  = RL$ + "R" + LR$
loc  = loc / 1.35
pass = pass + 1
render #g
input xxx
cls

if pass < 16 then goto [loop]
end


use ggez::{
    conf::{WindowMode, WindowSetup},
    error::GameResult,
    event,
    graphics::{clear, draw, present, Color, MeshBuilder},
    nalgebra::Point2,
    Context,
};
use std::time::Duration;

// L-System to create the sequence needed for a Dragon Curve.
// This function creates the next generation given the current one
// L-System from https://www.cs.unm.edu/~joel/PaperFoldingFractal/L-system-rules.html
//
fn l_system_next_generation(current_generation: &str) -> String {
    let f_rule = "f-h";
    let h_rule = "f+h";
    let mut next_gen = String::new();
    for char in current_generation.chars() {
        match char {
            'f' => next_gen.push_str(f_rule),
            'h' => next_gen.push_str(h_rule),
            '-' | '+' => next_gen.push(char),
            _ => panic!("Unknown char {}", char),
        }
    }
    next_gen
}

// The rest of the code is for drawing the output and is specific to using the
// ggez 2d game library: https://ggez.rs/

const WINDOW_WIDTH: f32 = 700.0;
const WINDOW_HEIGHT: f32 = 700.0;
const START_X: f32 = WINDOW_WIDTH / 6.0;
const START_Y: f32 = WINDOW_HEIGHT / 6.0;
const MAX_DEPTH: i32 = 15;
const LINE_LENGTH: f32 = 20.0;

struct MainState {
    start_gen: String,
    next_gen: String,
    line_length: f32,
    max_depth: i32,
    current_depth: i32,
}

impl MainState {
    fn new() -> GameResult<MainState> {
        let start_gen = "f";
        let next_gen = String::new();
        let line_length = LINE_LENGTH;
        let max_depth = MAX_DEPTH;
        let current_depth = 0;
        Ok(MainState {
            start_gen: start_gen.to_string(),
            next_gen,
            line_length,
            max_depth,
            current_depth,
        })
    }
}

impl event::EventHandler for MainState {
    // In each repetition of the event loop a new generation of the L-System
    // is generated and drawn, until the maximum depth is reached.
    // Each time the line length is reduced so that the overall dragon curve
    // can be seen in the window as it spirals and gets bigger.
    // The update sleeps for 0.5 seconds just so that its pogression can be watched.
    //
    fn update(&mut self, _ctx: &mut Context) -> GameResult {
        if self.current_depth < self.max_depth {
            self.next_gen = l_system_next_generation(&self.start_gen);
            self.start_gen = self.next_gen.clone();
            self.line_length -= (self.line_length / self.max_depth as f32) * 1.9;
            self.current_depth += 1;
        }
        ggez::timer::sleep(Duration::from_millis(500));
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult {
        let grey = Color::from_rgb(77, 77, 77);
        let blue = Color::from_rgb(51, 153, 255);
        let initial_point_blue = Point2::new(START_X, START_Y);
        clear(ctx, grey);
        draw_lines(
            &self.next_gen,
            ctx,
            self.line_length,
            blue,
            initial_point_blue,
        )?;
        present(ctx)?;
        Ok(())
    }
}

fn next_point(current_point: Point2<f32>, heading: f32, line_length: f32) -> Point2<f32> {
    let next_point = (
        (current_point.x + (line_length * heading.to_radians().cos().trunc() as f32)),
        (current_point.y + (line_length * heading.to_radians().sin().trunc() as f32)),
    );
    Point2::new(next_point.0, next_point.1)
}

fn draw_lines(
    instructions: &str,
    ctx: &mut Context,
    line_length: f32,
    colour: Color,
    initial_point: Point2<f32>,
) -> GameResult {
    let line_width = 2.0;
    let mut heading = 0.0;
    let turn_angle = 90.0;
    let mut start_point = initial_point;
    let mut line_builder = MeshBuilder::new();
    for char in instructions.chars() {
        let end_point = next_point(start_point, heading, line_length);
        match char {
            'f' | 'h' => {
                line_builder.line(&[start_point, end_point], line_width, colour)?;
                start_point = end_point;
            }
            '+' => heading += turn_angle,
            '-' => heading -= turn_angle,
            _ => panic!("Unknown char {}", char),
        }
    }
    let lines = line_builder.build(ctx)?;
    draw(ctx, &lines, (initial_point,))?;
    Ok(())
}

fn main() -> GameResult {
    let cb = ggez::ContextBuilder::new("dragon curve", "huw")
        .window_setup(WindowSetup::default().title("Dragon curve"))
        .window_mode(WindowMode::default().dimensions(WINDOW_WIDTH, WINDOW_HEIGHT));
    let (ctx, event_loop) = &mut cb.build()?;
    let state = &mut MainState::new()?;
    event::run(ctx, event_loop, state)
}


use std::fmt::{Display, Formatter, Result};
use std::process::exit;

struct Coefficient(usize, f64);

impl Display for Coefficient {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        let i = self.0;
        let c = self.1;

        if c == 0. {
            return Ok(());
        }

        write!(
            f,
            " {} {}e({})",
            if c < 0. {
                "-"
            } else if f.alternate() {
                " "
            } else {
                "+"
            },
            if (c.abs() - 1.).abs() < f64::EPSILON {
                "".to_string()
            } else {
                c.abs().to_string() + "*"
            },
            i + 1
        )
    }
}

fn usage() {
    println!("Usage: display-linear-combination a1 [a2 a3 ...]");
}

fn linear_combination(coefficients: &[f64]) -> String {
    let mut string = String::new();

    let mut iter = coefficients.iter().enumerate();

    // find first nonzero argument
    loop {
        match iter.next() {
            Some((_, &c)) if c == 0. => {
                continue;
            }
            Some((i, &c)) => {
                string.push_str(format!("{:#}", Coefficient(i, c)).as_str());
                break;
            }
            None => {
                string.push('0');
                return string;
            }
        }
    }

    // print subsequent arguments
    for (i, &c) in iter {
        string.push_str(format!("{}", Coefficient(i, c)).as_str());
    }

    string
}

fn main() {
    let mut coefficients = Vec::new();
    let mut args = std::env::args();

    args.next(); // drop first argument

    // parse arguments into floats
    for arg in args {
        let c = arg.parse::<f64>().unwrap_or_else(|e| {
            eprintln!("Failed to parse argument \"{}\": {}", arg, e);
            exit(-1);
        });
        coefficients.push(c);
    }

    // no arguments, print usage and exit
    if coefficients.is_empty() {
        usage();
        return;
    }

    println!("{}", linear_combination(&coefficients));
}


object LinearCombination extends App {
    val combos = Seq(Seq(1, 2, 3), Seq(0, 1, 2, 3),
      Seq(1, 0, 3, 4), Seq(1, 2, 0), Seq(0, 0, 0), Seq(0),
      Seq(1, 1, 1), Seq(-1, -1, -1), Seq(-1, -2, 0, -3), Seq(-1))

  private def linearCombo(c: Seq[Int]): String = {
    val sb = new StringBuilder
    for {i <- c.indices
         term = c(i)
         if term != 0} {
      val av = math.abs(term)
      def op = if (term < 0 && sb.isEmpty) "-"
      else if (term < 0) " - "
      else if (term > 0 && sb.isEmpty) "" else " + "

      sb.append(op).append(if (av == 1) "" else s"$av*").append("e(").append(i + 1).append(')')
    }
    if (sb.isEmpty) "0" else sb.toString
  }
    for (c <- combos) {
      println(f"${c.mkString("[", ", ", "]")}%-15s  ->  ${linearCombo(c)}%s")
    }
}


{def dotp
 {def dotp.r
  {lambda {:v1 :v2 :acc}
   {if {A.empty? :v1}
    then :acc
    else {dotp.r {A.rest :v1} {A.rest :v2}
                 {+ {* {A.first :v1} {A.first :v2}} :acc}}}}}
 {lambda {:v1 :v2}
  {if {= {A.length :v1} {A.length :v2}}
   then {dotp.r :v1 :v2 0}
   else Vectors must be of equal length}}}
-> dotp

{dotp {A.new 1 3 -5} {A.new 4 -2}}
-> Vectors must be of equal length

{dotp {A.new 1 3 -5} {A.new 4 -2 -1}}
-> 3


(defun dot-product (a b)
  (: lists foldl #'+/2 0
    (: lists zipwith #'*/2 a b)))


import javax.swing.JFrame
import java.awt.Graphics

class DragonCurve(depth: Int) extends JFrame(s"Dragon Curve (depth $depth)") {

  setBounds(100, 100, 800, 600);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  val len = 400 / Math.pow(2, depth / 2.0);
  val startingAngle = -depth * (Math.PI / 4);
  val steps = getSteps(depth).filterNot(c => c == 'X' || c == 'Y')

  def getSteps(depth: Int): Stream[Char] = {
    if (depth == 0) {
      "FX".toStream
    } else {
      getSteps(depth - 1).flatMap{
        case 'X' => "XRYFR"
        case 'Y' => "LFXLY"
        case c => c.toString
      }
    }
  }

  override def paint(g: Graphics): Unit = {
    var (x, y) = (230, 350)
    var (dx, dy) = ((Math.cos(startingAngle) * len).toInt, (Math.sin(startingAngle) * len).toInt)
    for (c <- steps) c match {
      case 'F' => {
        g.drawLine(x, y, x + dx, y + dy)
        x = x + dx
        y = y + dy
      }
      case 'L' => {
        val temp = dx
        dx = dy
        dy = -temp
      }
      case 'R' => {
        val temp = dx
        dx = -dy
        dy = temp
      }
    }
  }

}

object DragonCurve extends App {
  new DragonCurve(14).setVisible(true);
}


proc lincom {factors} {
    set exp 0
    set res ""
    foreach f $factors {
        incr exp
        if {$f == 0} {
            continue
        } elseif {$f == 1} {
            append res "+e($exp)"
        } elseif {$f == -1} {
            append res "-e($exp)"
        } elseif {$f > 0} {
            append res "+$f*e($exp)"
        } else {
            append res "$f*e($exp)"
        }
    }
    if {$res eq ""} {set res 0}
    regsub {^\+} $res {} res
    return $res
}

foreach test {
    {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}
} {
    puts [format "%10s -> %-10s" $test [lincom $test]]
}


vectorA$ = "1, 3, -5"
vectorB$ = "4, -2, -1"
print "DotProduct of ";vectorA$;" and "; vectorB$;" is ";
print DotProduct(vectorA$, vectorB$)

'arbitrary length
vectorA$ = "3, 14, 15, 9, 26"
vectorB$ = "2, 71, 18, 28, 1"
print "DotProduct of ";vectorA$;" and "; vectorB$;" is ";
print DotProduct(vectorA$, vectorB$)

end

function DotProduct(a$, b$)
    DotProduct = 0
    i = 1
    while 1
        x$=word$( a$, i, ",")
        y$=word$( b$, i, ",")
        if x$="" or y$="" then exit function
        DotProduct = DotProduct + val(x$)*val(y$)
        i = i+1
    wend
end function


; This is not strictly LLVM, as it uses the C library function "printf".
; LLVM does not provide a way to print values, so the alternative would be
; to just load the string into memory, and that would be boring.

; Additional comments have been inserted, as well as changes made from the output produced by clang such as putting more meaningful labels for the jumps

;--- The declarations for the external C functions
declare i32 @printf(i8*, ...)

$"INTEGER_FORMAT" = comdat any

@main.a = private unnamed_addr constant [3 x i32] [i32 1, i32 3, i32 -5], align 4
@main.b = private unnamed_addr constant [3 x i32] [i32 4, i32 -2, i32 -1], align 4
@"INTEGER_FORMAT" = linkonce_odr unnamed_addr constant [4 x i8] c"%d\0A\00", comdat, align 1

; Function Attrs: noinline nounwind optnone uwtable
define i32 @dot_product(i32*, i32*, i64) #0 {
  %4 = alloca i64, align 8                              ;-- allocate copy of n
  %5 = alloca i32*, align 8                             ;-- allocate copy of b
  %6 = alloca i32*, align 8                             ;-- allocate copy of a
  %7 = alloca i32, align 4                              ;-- allocate sum
  %8 = alloca i64, align 8                              ;-- allocate i
  store i64 %2, i64* %4, align 8                        ;-- store a copy of n
  store i32* %1, i32** %5, align 8                      ;-- store a copy of b
  store i32* %0, i32** %6, align 8                      ;-- store a copy of a
  store i32 0, i32* %7, align 4                         ;-- store 0 in sum
  store i64 0, i64* %8, align 8                         ;-- store 0 in i
  br label %loop

loop:
  %9 = load i64, i64* %8, align 8                       ;-- load i
  %10 = load i64, i64* %4, align 8                      ;-- load n
  %11 = icmp ult i64 %9, %10                            ;-- i < n
  br i1 %11, label %loop_body, label %exit

loop_body:
  %12 = load i32*, i32** %6, align 8                    ;-- load a
  %13 = load i64, i64* %8, align 8                      ;-- load i
  %14 = getelementptr inbounds i32, i32* %12, i64 %13   ;-- calculate a[i]
  %15 = load i32, i32* %14, align 4                     ;-- load a[i]

  %16 = load i32*, i32** %5, align 8                    ;-- load b
  %17 = load i64, i64* %8, align 8                      ;-- load i
  %18 = getelementptr inbounds i32, i32* %16, i64 %17   ;-- calculate b[i]
  %19 = load i32, i32* %18, align 4                     ;-- load b[i]

  %20 = mul nsw i32 %15, %19                            ;-- temp = a[i] * b[i]

  %21 = load i32, i32* %7, align 4                      ;-- load sum
  %22 = add nsw i32 %21, %20                            ;-- add sum and temp
  store i32 %22, i32* %7, align 4                       ;-- store sum

  %23 = load i64, i64* %8, align 8                      ;-- load i
  %24 = add i64 %23, 1                                  ;-- increment i
  store i64 %24, i64* %8, align 8                       ;-- store i
  br label %loop

exit:
  %25 = load i32, i32* %7, align 4                      ;-- load sum
  ret i32 %25                                           ;-- return sum
}

; Function Attrs: noinline nounwind optnone uwtable
define i32 @main() #0 {
  %1 = alloca [3 x i32], align 4                        ;-- allocate a
  %2 = alloca [3 x i32], align 4                        ;-- allocate b

  %3 = bitcast [3 x i32]* %1 to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* bitcast ([3 x i32]* @main.a to i8*), i64 12, i32 4, i1 false)

  %4 = bitcast [3 x i32]* %2 to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %4, i8* bitcast ([3 x i32]* @main.b to i8*), i64 12, i32 4, i1 false)

  %5 = getelementptr inbounds [3 x i32], [3 x i32]* %2, i32 0, i32 0
  %6 = getelementptr inbounds [3 x i32], [3 x i32]* %1, i32 0, i32 0
  %7 = call i32 @dot_product(i32* %6, i32* %5, i64 3)

  %8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"INTEGER_FORMAT", i32 0, i32 0), i32 %7)
  ret i32 0
}

; Function Attrs: argmemonly nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) #1

attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }


n_folds=10

folds=[];
folds=[0 1];

old_folds=[];
vectors=[];

i=[];

for i=2:n_folds+1

    curve_length=length(folds);

    vectors=folds(1:curve_length-1)-folds(curve_length);

    vectors=vectors.*exp(90/180*%i*%pi);

    new_folds=folds(curve_length)+vectors;

    j=curve_length;

    while j>1
        folds=[folds new_folds(j-1)]
        j=j-1;
    end

end

scf(0); clf();
xname("Dragon curve: "+string(n_folds)+" folds")

plot2d(real(folds),imag(folds),5);

set(gca(),"isoview","on");
set(gca(),"axes_visible",["off","off","off"]);


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

var float: angle is 0.0;
var integer: x is 220;
var integer: y is 220;

const proc: turn (in integer: degrees) is func
  begin
    angle +:= flt(degrees) * PI / 180.0
  end func;

const proc: forward (in float: length) is func
  local
    var integer: x2 is 0;
    var integer: y2 is 0;
  begin
    x2 := x + trunc(cos(angle) * length);
    y2 := y + trunc(sin(angle) * length);
    lineTo(x, y, x2, y2, black);
    x := x2;
    y := y2;
  end func;

const proc: dragon (in float: length, in integer: split, in integer: direct) is func
  begin
    if split = 0 then
      forward(length);
    else
      turn(direct * 45);
      dragon(length/1.4142136, pred(split), 1);
      turn(-direct * 90);
      dragon(length/1.4142136, pred(split), -1);
      turn(direct * 45);
    end if;
  end func;

const proc: main is func
  begin
    screen(976, 654);
    clear(curr_win, white);
    KEYBOARD := GRAPH_KEYBOARD;
    dragon(768.0, 14, 1);
    ignore(getc(KEYBOARD));
  end func;


Imports System.Text

Module Module1

    Function LinearCombo(c As List(Of Integer)) As String
        Dim sb As New StringBuilder
        For i = 0 To c.Count - 1
            Dim n = c(i)
            If n < 0 Then
                If sb.Length = 0 Then
                    sb.Append("-")
                Else
                    sb.Append(" - ")
                End If
            ElseIf n > 0 Then
                If sb.Length <> 0 Then
                    sb.Append(" + ")
                End If
            Else
                Continue For
            End If

            Dim av = Math.Abs(n)
            If av <> 1 Then
                sb.AppendFormat("{0}*", av)
            End If
            sb.AppendFormat("e({0})", i + 1)
        Next
        If sb.Length = 0 Then
            sb.Append("0")
        End If
        Return sb.ToString()
    End Function

    Sub Main()
        Dim combos = New List(Of List(Of Integer)) From {
            New List(Of Integer) From {1, 2, 3},
            New List(Of Integer) From {0, 1, 2, 3},
            New List(Of Integer) From {1, 0, 3, 4},
            New List(Of Integer) From {1, 2, 0},
            New List(Of Integer) From {0, 0, 0},
            New List(Of Integer) From {0},
            New List(Of Integer) From {1, 1, 1},
            New List(Of Integer) From {-1, -1, -1},
            New List(Of Integer) From {-1, -2, 0, -3},
            New List(Of Integer) From {-1}
        }

        For Each c In combos
            Dim arr = "[" + String.Join(", ", c) + "]"
            Console.WriteLine("{0,15} -> {1}", arr, LinearCombo(c))
        Next
    End Sub

End Module


to dotprod :a :b
  output apply "sum (map "product :a :b)
end

show dotprod [1 3 -5] [4 -2 -1]    ; 3


dot_product(A, B, Sum) :-
    dot_product(A, B, 0, Sum).

dot_product([], [], Sum, Sum).
dot_product([A| As], [B| Bs], Acc, Sum) :-
    Acc2 is Acc + A*B,
    dot_product(As, Bs, Acc2, Sum).


function dotprod(a, b)
  local ret = 0
  for i = 1, #a do
    ret = ret + a[i] * b[i]
  end
  return ret
end

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


import <Utilities/Math.sl>;
import <Utilities/Conversion.sl>;

initPoints := [[0,0],[1,0]];

f1(point(1)) :=
	let
		matrix := [[cos(45 * (pi/180)), -sin(45 * (pi/180))],
				   [sin(45 * (pi/180)), cos(45 * (pi/180))]];
	in
		head(transpose((1/sqrt(2)) * matmul(matrix, transpose([point]))));

f2(point(1)) :=
	let
		matrix := [[cos(135 * (pi/180)), -sin(135 * (pi/180))],
				   [sin(135 * (pi/180)), cos(135 * (pi/180))]];
	in
		head(transpose((1/sqrt(2)) * matmul(matrix, transpose([point])))) + initPoints[2];

matmul(X(2),Y(2))[i,j] := sum(X[i,all]*Y[all,j]);

entry(steps(0), maxX(0), maxY(0)) :=
	let
		scaleX := maxX / 1.5;
		scaleY := maxY;

		shiftX := maxX / 3.0 / 1.5;
		shiftY := maxY / 3.0;
	in
		round(run(steps, initPoints) * [scaleX, scaleY] + [shiftX, shiftY]);

run(steps(0), result(2)) :=
	let
		next := f1(result) ++ f2(result);
	in
		result when steps <= 0
	else
		run(steps - 1, next);


var rules = Hash(
    x => 'x+yF+',
    y => '-Fx-y',
)

var lsys = LSystem(
    width:  600,
    height: 600,

    xoff: -430,
    yoff: -380,

    len:   8,
    angle: 90,
    color: 'dark green',
)

lsys.execute('Fx', 11, "dragon_curve.png", rules)


import strings

fn linear_combo(c []int) string {
    mut sb := strings.new_builder(128)
    for i, n in c {
        if n == 0 {
            continue
        }
        mut op := ''
        match true {
        	n < 0 && sb.len == 0 {
            	op = "-"
			}
        	n < 0{
            	op = " - "
			}
        	n > 0 && sb.len == 0 {
            	op = ""
			}
        	else{
            	op = " + "
			}
        }
        mut av := n
        if av < 0 {
            av = -av
        }
        mut coeff := "$av*"
        if av == 1 {
            coeff = ""
        }
        sb.write_string("$op${coeff}e(${i+1})")
    }
    if sb.len == 0 {
        return "0"
    } else {
        return sb.str()
    }
}

fn main() {
    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 {
        println("${c:-15}  ->  ${linear_combo(c)}")
    }
}


Module dot_product {
      A=(1,3,-5)
      B=(4,-2,-1)
      Function Dot(a, b) {
            if len(a)<>len(b) Then Error "not same length"
            if len(a)=0 then Error "empty vectors"
            Let a1=each(a), b1=each(b), sum=0
            While a1, b1 {sum+=array(a1)*array(b1)}
            =sum
      }
      Print Dot(A, B)
      Print Dot((1,3,-5), (4,-2,-1))
}
Module dot_product


levels = 16
level = 0
step = 1
>
  draw(level)
  level += step
  ? level>levels
    step = -1
    level += step*2
  .
  ? level=0, step = 1
  #.delay(1)
<

draw(level)=
  mx,my = #.scrsize()
  fs = #.min(mx,my)/2
  r = fs/2^((level-1)/2)
  x = mx/2+fs*#.sqrt(2)/2
  y = my/2+fs/4
  a = #.pi/4*(level-2)
  #.scroff()
  #.scrclear()
  #.drawline(x,y,x,y)
  ss = 2^level-1
  > i, 0..ss
    ? #.and(#.and(i,-i)*2,i)
      a += #.pi/2
    !
      a -= #.pi/2
    .
    x += r*#.cos(a)
    y += r*#.sin(a)
    #.drawcolor(#.hsv2rgb(i/(ss+1)*360,1,1):3)
    #.drawline(x,y)
  <
  #.scr()
.


fcn linearCombination(coeffs){
   [1..].zipWith(fcn(n,c){ if(c==0) "" else "%s*e(%s)".fmt(c,n) },coeffs)
      .filter().concat("+").replace("+-","-").replace("1*","")
   or 0
}


:- module dot_product.
:- interface.

:- import_module io.
:- pred main(io::di, io::uo) is det.

:- implementation.
:- import_module int, list.

main(!IO) :-
    io.write_int([1, 3, -5] `dot_product` [4, -2, -1], !IO),
    io.nl(!IO).

:- func dot_product(list(int), list(int)) = int.

dot_product(As, Bs) =
    list.foldl_corresponding((func(A, B, Acc) = Acc + A * B), As, Bs, 0).


<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
 "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:l="http://www.w3.org/1999/xlink"
     width="400" height="400">
  <style type="text/css"><![CDATA[
    line { stroke: black; stroke-width: .05; }
    circle { fill: black; }
  ]]></style>

<defs>

  <g id="marks">
    <circle cx="0" cy="0" r=".03"/>
    <circle cx="1" cy="0" r=".03"/>
  </g>

  <g id="l0">
    <line x1="0" y1="0" x2="1" y2="0"/>
    <!-- useful for studying the transformation stages:
         <line x1="0.1" y1="0" x2="0.9" y2="0.1"/> -->
  </g>

  <!-- These are identical except for the id and href. -->
  <g id="l1"> <use l:href="#l0" transform="matrix( .5 .5  -.5  .5  0 0)"/>
              <use l:href="#l0" transform="matrix(-.5 .5  -.5 -.5  1 0)"/>
              <use l:href="#marks"/></g>
  <g id="l2"> <use l:href="#l1" transform="matrix( .5 .5  -.5  .5  0 0)"/>
              <use l:href="#l1" transform="matrix(-.5 .5  -.5 -.5  1 0)"/>
              <use l:href="#marks"/></g>
  <g id="l3"> <use l:href="#l2" transform="matrix( .5 .5  -.5  .5  0 0)"/>
              <use l:href="#l2" transform="matrix(-.5 .5  -.5 -.5  1 0)"/>
              <use l:href="#marks"/></g>
  <g id="l4"> <use l:href="#l3" transform="matrix( .5 .5  -.5  .5  0 0)"/>
              <use l:href="#l3" transform="matrix(-.5 .5  -.5 -.5  1 0)"/>
              <use l:href="#marks"/></g>
  <g id="l5"> <use l:href="#l4" transform="matrix( .5 .5  -.5  .5  0 0)"/>
              <use l:href="#l4" transform="matrix(-.5 .5  -.5 -.5  1 0)"/>
              <use l:href="#marks"/></g>
  <g id="l6"> <use l:href="#l5" transform="matrix( .5 .5  -.5  .5  0 0)"/>
              <use l:href="#l5" transform="matrix(-.5 .5  -.5 -.5  1 0)"/>
              <use l:href="#marks"/></g>
  <g id="l7"> <use l:href="#l6" transform="matrix( .5 .5  -.5  .5  0 0)"/>
              <use l:href="#l6" transform="matrix(-.5 .5  -.5 -.5  1 0)"/>
              <use l:href="#marks"/></g>
  <g id="l8"> <use l:href="#l7" transform="matrix( .5 .5  -.5  .5  0 0)"/>
              <use l:href="#l7" transform="matrix(-.5 .5  -.5 -.5  1 0)"/>
              <use l:href="#marks"/></g>
  <g id="l9"> <use l:href="#l8" transform="matrix( .5 .5  -.5  .5  0 0)"/>
              <use l:href="#l8" transform="matrix(-.5 .5  -.5 -.5  1 0)"/>
              <use l:href="#marks"/></g>
</defs>

<g transform="translate(100, 200) scale(200)">
  <use l:href="#marks"/>
  <use l:href="#l9"/>
</g>

</svg>


С/П	*	ИП0	+	П0	С/П	БП	00


MODULE DotProduct;
FROM RealStr IMPORT RealToStr;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;

TYPE Vector =
    RECORD
        x,y,z : REAL
    END;

PROCEDURE DotProduct(u,v : Vector) : REAL;
BEGIN
    RETURN u.x*v.x + u.y*v.y + u.z*v.z
END DotProduct;

VAR
    buf : ARRAY[0..63] OF CHAR;
    dp : REAL;
BEGIN
    dp := DotProduct(Vector{1.0,3.0,-5.0},Vector{4.0,-2.0,-1.0});
    RealToStr(dp, buf);
    WriteString(buf);
    WriteLn;

    ReadChar
END DotProduct.


DOTPROD(A,B)
 ;Returns the dot product of two vectors. Vectors are assumed to be stored as caret-delimited strings of numbers.
 ;If the vectors are not of equal length, a null string is returned.
 QUIT:$LENGTH(A,"^")'=$LENGTH(B,"^") ""
 NEW I,SUM
 SET SUM=0
 FOR I=1:1:$LENGTH(A,"^") SET SUM=SUM+($PIECE(A,"^",I)*$PIECE(B,"^",I))
 KILL I
 QUIT SUM


package require Tk

set pi [expr acos(-1)]
set r2 [expr sqrt(2)]

proc turn {degrees} {
    global a pi
    set a [expr {$a + $degrees*$pi/180}]
}
proc forward {len} {
    global a coords
    lassign [lrange $coords end-1 end] x y
    lappend coords [expr {$x + cos($a)*$len}] [expr {$y + sin($a)*$len}]
}
proc dragon {len split {d 1}} {
    global r2 coords
    if {$split == 0} {
	forward $len
	return
    }

    # This next part is only necessary to allow the illustration of progress
    if {$split == 10 && [llength $::coords]>2} {
	.c coords dragon $::coords
	update
    }

    incr split -1
    set sublen [expr {$len/$r2}]
    turn [expr {$d*45}]
    dragon $sublen $split 1
    turn [expr {$d*-90}]
    dragon $sublen $split -1
    turn [expr {$d*45}]
}

set coords {150 180}
set a 0.0
pack [canvas .c -width 700 -height 500]
.c create line {0 0 0 0} -tag dragon
dragon 400 17
.c coords dragon $coords


using System;
using System.Console;
using Nemerle.Collections.NCollectionsExtensions;

module DotProduct
{
    DotProduct(x : array[int], y : array[int]) : int
    {
        $[(a * b)|(a, b) in ZipLazy(x, y)].FoldLeft(0, _+_);
    }

    Main() : void
    {
        def arr1 = array[1, 3, -5]; def arr2 = array[4, -2, -1];
        WriteLine(DotProduct(arr1, arr2));
    }
}


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

whatsTheVectorVictor = [[double 1.0, 3.0, -5.0], [double 4.0, -2.0, -1.0]]
dotProduct = Rexx dotProduct(whatsTheVectorVictor)
say dotProduct.format(null, 2)

return

method dotProduct(vec1 = double[], vec2 = double[]) public constant returns double signals IllegalArgumentException
  if vec1.length \= vec2.length then signal IllegalArgumentException('Vectors must be the same length')

  scalarProduct = double 0.0
  loop e_ = 0 to vec1.length - 1
    scalarProduct = vec1[e_] * vec2[e_] + scalarProduct
    end e_

  return scalarProduct

method dotProduct(vecs = double[,]) public constant returns double signals IllegalArgumentException
  return dotProduct(vecs[0], vecs[1])


(define (dot-product x y)
  (apply + (map * x y)))

(println (dot-product '(1 3 -5) '(4 -2 -1)))


\input tikz.tex
\usetikzlibrary{lindenmayersystems}

\pgfdeclarelindenmayersystem{Dragon curve}{
    \symbol{S}{\pgflsystemdrawforward}
    \rule{F -> F+S}
    \rule{S -> F-S}
}
\tikzpicture
\draw
    [lindenmayer system={Dragon curve, step=10pt, axiom=F, order=8}]
    lindenmayer system;
\endtikzpicture
\bye


\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{lindenmayersystems}
\pgfdeclarelindenmayersystem{Dragon curve}{
    \symbol{S}{\pgflsystemdrawforward}
    \rule{F -> -F++S-}
    \rule{S -> +F--S+}
}
\foreach \i in {1,...,8} {
    \hbox{
        order=\i
        \hspace{.5em}
        \begin{tikzpicture}[baseline=0pt]
            \draw
            [lindenmayer system={Dragon curve, step=10pt,angle=45, axiom=F, order=\i}]
            lindenmayer system;
        \end{tikzpicture}
      \hspace{1em}
    }
    \vspace{.5ex}
}
\begin{document}
\end{document}


# Compile time error when a and b are differently sized arrays
# Runtime error when a and b are differently sized seqs
proc dotp[T](a,b: T): int =
  doAssert a.len == b.len
  for i in a.low..a.high:
    result += a[i] * b[i]

echo dotp([1,3,-5], [4,-2,-1])
echo dotp(@[1,2,3],@[4,5,6])


MODULE DotProduct;
IMPORT
  Out := NPCT:Console;

VAR
  x,y: ARRAY 3 OF LONGINT;

PROCEDURE DotProduct(a,b: ARRAY OF LONGINT): LONGINT;
VAR
  resp, i: LONGINT;
BEGIN
  ASSERT(LEN(a) = LEN(b));
  resp := 0;
  FOR i := 0 TO LEN(x) - 1 DO
    INC(resp,x[i]*y[i])
  END;
  RETURN resp
END DotProduct;

BEGIN
  x[0] := 1;y[0] := 4;
  x[1] := 3;y[1] := -2;
  x[2] := -5;y[2] := -1;
  Out.Int(DotProduct(x,y),0);Out.Ln
END DotProduct.


bundle Default {
  class DotProduct {
    function : Main(args : String[]) ~ Nil {
      DotProduct([1, 3, -5], [4, -2, -1])->PrintLine();
    }

    function : DotProduct(array_a : Int[], array_b : Int[]) ~ Int {
      if(array_a = Nil) {
        return 0;
      };

      if(array_b = Nil) {
        return 0;
      };

      if(array_a->Size() <> array_b->Size()) {
        return 0;
      };

      val := 0;
      for(x := 0; x < array_a->Size(); x += 1;) {
        val += (array_a[x] * array_b[x]);
      };

      return val;
    }
  }
}


Define dragon = (iter, xform)
Prgm
  Local a,b
  If iter > 0 Then
    dragon(iter-1, xform*[[.5,.5,0][–.5,.5,0][0,0,1]])
    dragon(iter-1, xform*[[–.5,.5,0][–.5,–.5,1][0,0,1]])
  Else
    xform*[0;0;1]→a
    xform*[0;1;1]→b
    PxlLine floor(a[1,1]), floor(a[2,1]), floor(b[1,1]), floor(b[2,1])
  EndIf
EndPrgm

FnOff
PlotsOff
ClrDraw
dragon(7, [[75,0,26] [0,75,47] [0,0,1]])


#import <stdio.h>
#import <stdint.h>
#import <stdlib.h>
#import <string.h>
#import <Foundation/Foundation.h>

// this class exists to return a result between two
// vectors: if vectors have different "size", valid
// must be NO
@interface VResult : NSObject
{
 @private
  double value;
  BOOL valid;
}
+(instancetype)new: (double)v isValid: (BOOL)y;
-(instancetype)init: (double)v isValid: (BOOL)y;
-(BOOL)isValid;
-(double)value;
@end

@implementation VResult
+(instancetype)new: (double)v isValid: (BOOL)y
{
  return [[self alloc] init: v isValid: y];
}
-(instancetype)init: (double)v isValid: (BOOL)y
{
  if ((self == [super init])) {
    value = v;
    valid = y;
  }
  return self;
}
-(BOOL)isValid { return valid; }
-(double)value { return value; }
@end

@interface RCVector : NSObject
{
 @private
  double *vec;
  uint32_t size;
}
+(instancetype)newWithArray: (double *)v ofLength: (uint32_t)l;
-(instancetype)initWithArray: (double *)v ofLength: (uint32_t)l;
-(VResult *)dotProductWith: (RCVector *)v;
-(uint32_t)size;
-(double *)array;
-(void)free;
@end

@implementation RCVector
+(instancetype)newWithArray: (double *)v ofLength: (uint32_t)l
{
  return [[self alloc] initWithArray: v ofLength: l];
}
-(instancetype)initWithArray: (double *)v ofLength: (uint32_t)l
{
  if ((self = [super init])) {
    size = l;
    vec = malloc(sizeof(double) * l);
    if ( vec == NULL )
      return nil;
    memcpy(vec, v, sizeof(double)*l);
  }
  return self;
}
-(void)dealloc
{
  free(vec);
}
-(uint32_t)size { return size; }
-(double *)array { return vec; }
-(VResult *)dotProductWith: (RCVector *)v
{
  double r = 0.0;
  uint32_t i, s;
  double *v1;
  if ( [self size] != [v size] ) return [VResult new: r isValid: NO];
  s = [self size];
  v1 = [v array];
  for(i = 0; i < s; i++) {
    r += vec[i] * v1[i];
  }
  return [VResult new: r isValid: YES];
}
@end

double val1[] = { 1, 3, -5 };
double val2[] = { 4,-2, -1 };

int main()
{
  @autoreleasepool {
    RCVector *v1 = [RCVector newWithArray: val1 ofLength: sizeof(val1)/sizeof(double)];
    RCVector *v2 = [RCVector newWithArray: val2 ofLength: sizeof(val1)/sizeof(double)];
    VResult *r = [v1 dotProductWith: v2];
    if ( [r isValid] ) {
      printf("%lf\n", [r value]);
    } else {
      fprintf(stderr, "length of vectors differ\n");
    }
  }
  return 0;
}


Option Explicit
Const Pi As Double = 3.14159265358979
Dim angle As Double
Dim nDepth As Integer
Dim nColor As Long

Private Sub Form_Load()
    nColor = vbBlack
    nDepth = 12
    DragonCurve
End Sub

Sub DragonProc(size As Double, ByVal split As Integer, d As Integer)
    If split = 0 Then
     xForm.Line -Step(-Cos(angle) * size, Sin(angle) * size), nColor
    Else
        angle = angle + d * Pi / 4
        Call DragonProc(size / Sqr(2), split - 1, 1)
        angle = angle - d * Pi / 2
        Call DragonProc(size / Sqr(2), split - 1, -1)
        angle = angle + d * Pi / 4
    End If
End Sub

Sub DragonCurve()
    Const xcoefi = 0.74
    Const xcoefl = 0.59
    xForm.PSet (xForm.Width * xcoefi, xForm.Height / 3), nColor
    Call DragonProc(xForm.Width * xcoefl, nDepth, 1)
End Sub


Option Explicit On
Imports System.Math

Public Class DragonCurve
    Dim nDepth As Integer = 12
    Dim angle As Double
    Dim MouseX, MouseY As Integer
    Dim CurrentX, CurrentY As Integer
    Dim nColor As Color = Color.Black

    Private Sub DragonCurve_Click(sender As Object, e As EventArgs) Handles Me.Click
        SubDragonCurve()
    End Sub

    Sub DrawClear()
        Me.CreateGraphics.Clear(Color.White)
    End Sub

    Sub DrawMove(ByVal X As Double, ByVal Y As Double)
        CurrentX = X
        CurrentY = Y
    End Sub

    Sub DrawLine(ByVal X As Double, ByVal Y As Double)
        Dim MyGraph As Graphics = Me.CreateGraphics
        Dim PenColor As Pen = New Pen(nColor)
        Dim NextX, NextY As Long
        NextX = CurrentX + X
        NextY = CurrentY + Y
        MyGraph.DrawLine(PenColor, CurrentX, CurrentY, NextX, NextY)
        CurrentX = NextX
        CurrentY = NextY
    End Sub

    Sub DragonProc(size As Double, ByVal split As Integer, d As Integer)
        If split = 0 Then
            DrawLine(-Cos(angle) * size, Sin(angle) * size)
        Else
            angle = angle + d * PI / 4
            DragonProc(size / Sqrt(2), split - 1, 1)
            angle = angle - d * PI / 2
            DragonProc(size / Sqrt(2), split - 1, -1)
            angle = angle + d * PI / 4
        End If
    End Sub

    Sub SubDragonCurve()
        Const xcoefi = 0.74, xcoefl = 0.59
        DrawClear()
        DrawMove(Me.Width * xcoefi, Me.Height / 3)
        DragonProc(Me.Width * xcoefl, nDepth, 1)
    End Sub

End Class


a = [1, 3, -5]
b = [4, -2, -1] % or [4; -2; -1] and avoid transposition with '
disp( a * b' )  % ' means transpose


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

class Game {
   static init() {
        Window.title = "Dragon curve"
        Window.resize(800, 600)
        Canvas.resize(800, 600)
        var iter = 14
        var turns = getSequence(iter)
        var startingAngle = -iter * Num.pi / 4
        var side = 400 / 2.pow(iter/2)
        dragon(turns, startingAngle, side)
    }

    static getSequence(iterations) {
        var turnSequence = []
        for (i in 0...iterations) {
            var copy = []
            copy.addAll(turnSequence)
            if (copy.count > 1) copy = copy[-1..0]
            turnSequence.add(1)
            copy.each { |i| turnSequence.add(-i) }
        }
        return turnSequence
    }

    static dragon(turns, startingAngle, side) {
        var col = Color.blue
        var angle = startingAngle
        var x1 = 230
        var y1 = 350
        var x2 = x1 + (angle.cos * side).truncate
        var y2 = y1 + (angle.sin * side).truncate
        Canvas.line(x1, y1, x2, y2, col)
        x1 = x2
        y1 = y2
        for (turn in turns) {
            angle = angle + turn*Num.pi/2
            x2 = x1 + (angle.cos * side).truncate
            y2 = y1 + (angle.sin * side).truncate
            Canvas.line(x1, y1, x2, y2, col)
            x1 = x2
            y1 = y2
        }
    }

    static update() {}

    static draw(alpha) {}
}


(define (dot-product a b)
  (apply + (map * a b)))

(print (dot-product '(1 3 -5) '(4 -2 -1)))
; ==> 3


declare
  fun {DotProduct Xs Ys}
     {Length Xs} = {Length Ys} %% assert
     {List.foldL {List.zip Xs Ys Number.'*'} Number.'+' 0}
  end
in
  {Show {DotProduct [1 3 ~5] [4 ~2 ~1]}}


        .model  tiny
        .code
        .486
        org     100h            ;assume ax=0, bx=0, sp=-2
start:  mov     al, 13h         ;(ah=0) set 320x200 video graphics mode
        int     10h
        push    0A000h
        pop     es
        mov     si, 8000h       ;color

        mov     cx, 75*256+100  ;coordinates of initial horizontal line segment
        mov     dx, 75*256+164  ;use power of 2 for length

        call    dragon
        mov     ah, 0           ;wait for keystroke
        int     16h
        mov     ax, 0003h       ;restore normal text mode
        int     10h
        ret

dragon: cmp     sp, -100        ;at maximum recursion depth?
        jne     drag30          ;skip if not
        mov     bl, dh          ;draw at max depth to get solid image
        imul    di, bx, 320     ;(bh=0) plot point at X=dl, Y=dh
        mov     bl, dl
        add     di, bx
        mov     ax, si          ;color
        shr     ax, 13
        or      al, 8           ;use bright colors 8..F
        stosb                   ;es:[di++]:= al
        inc     si
        ret
drag30:
        push    cx              ;preserve points P and Q
        push    dx

        xchg    ax, dx          ;DX:= Q(0)-P(0);
        sub     al, cl
        sub     ah, ch          ;DY:= Q(1)-P(1);

        mov     dx, ax          ;new point
        sub     dl, ah          ;R(0):= P(0) + (DX-DY)/2
        jns     drag40
         inc    dl
drag40: sar     dl, 1           ;dl:= (al-ah)/2 + cl
        add     dl, cl

        add     dh, al          ;R(1):= P(1) + (DX+DY)/2;
        jns     drag45
         inc    dh
drag45: sar     dh, 1           ;dh:= (al+ah)/2 + ch
        add     dh, ch

        call    dragon          ;Dragon(P, R);
        pop     cx              ;get Q
        push    cx
        call    dragon          ;Dragon(Q, R);

        pop     dx              ;restore points
        pop     cx
        ret
        end     start


sub dotprod
{
        my($vec_a, $vec_b) = @_;
        die "they must have the same size\n" unless @$vec_a == @$vec_b;
        my $sum = 0;
        $sum += $vec_a->[$_] * $vec_b->[$_] for 0..$#$vec_a;
        return $sum;
}

my @vec_a = (1,3,-5);
my @vec_b = (4,-2,-1);

print dotprod(\@vec_a,\@vec_b), "\n"; # 3


Dragon3 {
  Angle 4
  Axiom XF
  X=XF+Y
  Y=XF-Y
  }


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

proc Dragon(D, P, Q);           \Draw a colorful dragon curve
int  D, P, Q;                   \recursive depth, coordinates of line segment
int  R(2),                      \coordinates of generated new point
     DX, DY, C;                 \deltas, color
[C:= [0];                       \color is a local, static-like variable
D:= D+1;                        \depth of recursion increases
if D >= 13 then                 \draw lines at maximum depth to get solid image
    [Move(P(0), P(1));  Line(Q(0), Q(1), C(0)>>9+4!8);  C(0):= C(0)+1;  return];
DX:= Q(0)-P(0);  DY:= Q(1)-P(1);
R(0):= P(0) + (DX-DY)/2;        \new point
R(1):= P(1) + (DX+DY)/2;
Dragon(D, P, R);                \draw two segments that include the new point
Dragon(D, Q, R);
];

int X, Y, P(2), Q(2);
[SetVid($101);                  \set 640x480 video graphics mode
X:= 32;  Y:= 32;                \coordinates of initial horizontal line segment
P(0):= X;  P(1):= Y;
Q(0):= X+64;  Q(1):= Y;         \(power of two length works best for integers)
Dragon(0, P, Q);                \draw its dragon curve
X:= ChIn(1);                    \wait for keystroke
SetVid(3);                      \restore normal text mode
]


w = 390 : h = int(w * 11 / 16)
open window w, h
level = 18 : insize = 247
x = 92 : y = 94

iters = 2^level
qiter = 510/iters
SQ = sqrt(2) : QPI = pi/4

rotation = 0 : iter = 0 : rq = 1.0
dim rqs(level)

color 0,0,0
clear window
dragon()

sub dragon()
	if level<=0 then
		yn = sin(rotation)*insize + y
		xn = cos(rotation)*insize + x
		if iter*2<iters then
			color 0,iter*qiter,255-iter*qiter
		else
			color qiter*iter-255,(iters-iter)*qiter,0
		end if
		line x,y,xn,yn
		iter = iter + 1
		x = xn : y = yn
		return
	end if
	insize = insize/SQ
	rotation = rotation + rq*QPI
	level = level - 1
	rqs(level) = rq : rq = 1
	dragon()
	rotation = rotation - rqs(level)*QPI*2
	rq = -1
	dragon()
	rq = rqs(level)
	rotation = rotation + rq*QPI
	level = level + 1
	insize = insize*SQ
	return
end sub


def sq_mul
    0 tolist var c
    len for
        var i
        i get rot i get rot * c swap 0 put var c
    endfor
    c
enddef

def sq_sum
    0 swap
    len for
        get rot + swap
    endfor
    swap
enddef

1 3 -5 3 tolist
4 -2 -1 3 tolist
sq_mul
sq_sum
pstack


<?php
function dot_product($v1, $v2) {
  if (count($v1) != count($v2))
    throw new Exception('Arrays have different lengths');
  return array_sum(array_map('bcmul', $v1, $v2));
}

echo dot_product(array(1, 3, -5), array(4, -2, -1)), "\n";
?>


println(0'|<?xml version='1.0' encoding='utf-8' standalone='no'?>|"\n"
   0'|<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'|"\n"
   0'|'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>|"\n"
   0'|<svg width='100%' height='100%' version='1.1'|"\n"
   0'|xmlns='http://www.w3.org/2000/svg'>|);

order:=13.0; # akin to number of recursion steps
d_size:=1000.0; # size in pixels
pi:=(1.0).pi;
turn_angle:=pi/2; # turn angle of each segment, 90 degrees for the canonical dragon

angle:=pi - (order * (pi/4)); # starting angle
len:=(d_size/1.5) / (2.0).sqrt().pow(order); # size of each segment
x:=d_size*5/6; y:=d_size*1/3; # starting point

foreach i in ([0 .. (2.0).pow(order-1)]){
   # find which side to turn based on the iteration
   angle += i.bitAnd(-i).shiftLeft(1).bitAnd(i) and -turn_angle or turn_angle;

   dx:=x + len * angle.sin(); dy:=y - len * angle.cos();
   println("<line x1='",x,"' y1='",y,"' x2='",dx,"' y2='",dy,
           "' style='stroke:rgb(0,0,0);stroke-width:1'/>");
   x=dx; y=dy;
}
println("</svg>");


10 LET level=15: LET insize=120
20 LET x=80: LET y=70
30 LET iters=2^level
40 LET qiter=256/iters
50 LET sq=SQR (2): LET qpi=PI/4
60 LET rotation=0: LET iter=0: LET rq=1
70 DIM r(level)
75 GO SUB 80: STOP
80 REM Dragon
90 IF level>1 THEN GO TO 200
100 LET yn=SIN (rotation)*insize+y
110 LET xn=COS (rotation)*insize+x
120 PLOT x,y: DRAW xn-x,yn-y
130 LET iter=iter+1
140 LET x=xn: LET y=yn
150 RETURN
200 LET insize=insize/sq
210 LET rotation=rotation+rq*qpi
220 LET level=level-1
230 LET r(level)=rq: LET rq=1
240 GO SUB 80
250 LET rotation=rotation-r(level)*qpi*2
260 LET rq=-1
270 GO SUB 80
280 LET rq=r(level)
290 LET rotation=rotation+rq*qpi
300 LET level=level+1
310 LET insize=insize*sq
320 RETURN


go =>
  L1 = [1, 3, -5],
  L2 = [4, -2, -1],

  println(dot_product=dot_product(L1,L2)),
  catch(println(dot_product([1,2,3,4],[1,2,3])),E, println(E)),
  nl.

dot_product(L1,L2) = _, L1.length != L2.length  =>
  throw($dot_product_not_same_length(L1,L2)).
dot_product(L1,L2) = sum([L1[I]*L2[I] : I in 1..L1.length]).


(de dotProduct (A B)
   (sum * A B) )

(dotProduct (1 3 -5) (4 -2 -1))


get (n);
begin;
   declare (A(n), B(n)) float;
   declare dot_product float;

   get list (A);
   get list (B);
   dot_product = sum(a*b);
   put (dot_product);
end;


To run:
Start up.
Make an example vector and another example vector.
Compute a dot product of the example vector and the other example vector.
Destroy the example vector. Destroy the other example vector.
Convert the dot product to a string.
Write the string on the console.
Wait for the escape key.
Shut down.

An element is a thing with a number.

A vector is some elements.

To add a number to a vector:
Allocate memory for an element.
Put the number into the element's number.
Append the element to the vector.

To multiply a vector by another vector:
If the vector's count is not the other vector's count, exit.
Get an element from the vector.
Get another element from the other vector.
Loop.
If the element is nil, exit.
Multiply the element's number by the other element's number.
Put the element's next into the element.
Put the other element's next into the other element.
Repeat.

A sum is a number.

To find a sum of a vector:
Get an element from the vector.
Loop.
If the element is nil, exit.
Add the element's number to the sum.
Put the element's next into the element.
Repeat.

A product is a number.

To compute a dot product of a vector and another vector:
If the vector's count is not the other vector's count, exit.
Multiply the vector by the other vector.
Find a sum of the vector.
Put the sum into the dot product.

To make an example vector and another example vector:
Add 1 to the example vector.
Add 3 to the example vector.
Add -5 to the example vector.
Add 4 to the other example vector.
Add -2 to the other example vector.
Add -1 to the other example vector.


/dotproduct{
/x exch def
/y exch def
/sum 0 def
/i 0 def
x length y length eq %Check if both arrays have the same length
{
x length{
/sum x i get y i get mul sum add def
/i i 1 add def
}repeat
sum ==
}
{
-1 ==
}ifelse
}def


function dotproduct( $a, $b) {
    $a | foreach -Begin {$i = $res = 0} -Process { $res += $_*$b[$i++] } -End{$res}
}
dotproduct (1..2) (1..2)
dotproduct (1..10) (11..20)


dot_product(L1, L2, N) :-
	maplist(mult, L1, L2, P),
	sumlist(P, N).

mult(A,B,C) :-
	C is A*B.


Procedure dotProduct(Array a(1),Array b(1))
  Protected i, sum, length = ArraySize(a())

  If ArraySize(a()) = ArraySize(b())
    For i = 0 To length
      sum + a(i) * b(i)
    Next
  EndIf

  ProcedureReturn sum
EndProcedure

If OpenConsole()
  Dim a(2)
  Dim b(2)

  a(0) = 1 : a(1) = 3 : a(2) = -5
  b(0) = 4 : b(1) = -2 : b(2) = -1

  PrintN(Str(dotProduct(a(),b())))

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


def dotp(a,b):
    assert len(a) == len(b), 'Vector sizes must match'
    return sum(aterm * bterm for aterm,bterm in zip(a, b))

if __name__ == '__main__':
    a, b = [1, 3, -5], [4, -2, -1]
    assert dotp(a,b) == 3


[ 0 unrot witheach
    [ over i^ peek *
      rot + swap ]
  drop ]             is .prod ( [ [ --> n )

 ' [ 1 3 -5 ] ' [ 4 -2 -1 ] .prod echo


x <- c(1, 3, -5)
y <- c(4, -2, -1)

sum(x*y)  # compute products, then do the sum
x %*% y   # inner product

# loop implementation
dotp <- function(x, y) {
	n <- length(x)
	if(length(y) != n) stop("invalid argument")
	s <- 0
	for(i in 1:n) s <- s + x[i]*y[i]
	s
}

dotp(x, y)


#lang racket
(define (dot-product l r) (for/sum ([x l] [y r]) (* x y)))

(dot-product '(1 3 -5) '(4 -2 -1))

;; dot-product works on sequences such as vectors:
(dot-product #(1 2 3) #(4 5 6))


import List;

public int dotProduct(list[int] L, list[int] M){
	result = 0;
	if(size(L) == size(M)) {
		while(size(L) >= 1) {
		    result += (head(L) * head(M));
		    L = tail(L);
		    M = tail(M);
	        }
	        return result;
	}
	else {
		throw "vector sizes must match";
	}
}


rebol []

a: [1 3 -5]
b: [4 -2 -1]

dot-product: function [v1 v2] [sum] [
    if (length? v1) != (length? v2) [
        make error! "error: vector sizes must match"
    ]
    sum: 0
    repeat i length? v1 [
        sum: sum + ((pick v1 i) * (pick v2 i))
    ]
]

dot-product a b


/*REXX program  computes  the   dot product   of  two equal size vectors  (of any size).*/
                     vectorA =  '  1   3  -5  '  /*populate vector  A  with some numbers*/
                     vectorB =  '  4  -2  -1  '  /*    "       "    B    "    "     "   */
say  'vector A = '   vectorA                     /*display the elements in the vector A.*/
say  'vector B = '   vectorB                     /*   "     "     "      "  "    "    B.*/
p=.Prod(vectorA, vectorB)                        /*invoke function & compute dot product*/
say                                              /*display a blank line for readability.*/
say  'dot product = '   p                        /*display the dot product to terminal. */
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
.Prod:  procedure;  parse arg A,B                /*this function compute the dot product*/
        $=0                                      /*initialize the sum to  0 (zero).     */
                    do j=1  for words(A)         /*multiply each number in the vectors. */
                    $=$+word(A,j) * word(B,j)    /*  ··· and add the product to the sum.*/
                    end   /*j*/
        return $                                 /*return the sum to function's invoker.*/


aVector = [2, 3, 5]
bVector = [4, 2, 1]
sum = 0
see dotProduct(aVector, bVector)

func dotProduct cVector, dVector
     for n = 1 to len(aVector)
         sum = sum + cVector[n] * dVector[n]
     next
     return sum


irb(main):001:0> require 'matrix'
=> true
irb(main):002:0> Vector[1, 3, -5].inner_product Vector[4, -2, -1]
=> 3


v1$ = "1, 3, -5"
v2$ = "4, -2, -1"

print "DotProduct of ";v1$;" and "; v2$;" is ";dotProduct(v1$,v2$)
end

function dotProduct(a$, b$)
    while word$(a$,i + 1,",") <> ""
       i = i + 1
       v1$=word$(a$,i,",")
       v2$=word$(b$,i,",")
       dotProduct = dotProduct + val(v1$) * val(v2$)
    wend
end function


// alternatively, fn dot_product(a: &Vec<u32>, b: &Vec<u32>)
// but using slices is more general and rustic
fn dot_product(a: &[i32], b: &[i32]) -> Option<i32> {
    if a.len() != b.len() { return None }
    Some(
        a.iter()
            .zip( b.iter() )
            .fold(0, |sum, (el_a, el_b)| sum + el_a*el_b)
    )
}

fn main() {
    let v1 = vec![1, 3, -5];
    let v2 = vec![4, -2, -1];

    println!("{}", dot_product(&v1, &v2).unwrap());
}


class Dot[T](v1: Seq[T])(implicit n: Numeric[T]) {
  import n._ // import * operator
  def dot(v2: Seq[T]) = {
    require(v1.size == v2.size)
    (v1 zip v2).map{ Function.tupled(_ * _)}.sum
  }
}

object Main extends App {
  implicit def toDot[T: Numeric](v1: Seq[T]) = new Dot(v1)

  val v1 = List(1, 3, -5)
  val v2 = List(4, -2, -1)
  println(v1 dot v2)
}


(define (dot-product a b)
  (apply + (map * a b)))

(display (dot-product '(1 3 -5) '(4 -2 -1)))
(newline)


$ include "seed7_05.s7i";

$ syntax expr: .().dot.() is  -> 6;  # priority of dot operator

const func integer: (in array integer: a) dot (in array integer: b) is func
  result
    var integer: sum is 0;
  local
    var integer: index is 0;
  begin
    if length(a) <> length(b) then
      raise RANGE_ERROR;
    else
      for index range 1 to length(a) do
        sum +:= a[index] * b[index];
      end for;
    end if;
  end func;

const proc: main is func
  begin
    writeln([](1, 3, -5) dot [](4, -2, -1));
  end func;


[email protected](Vector traits) <dot> [email protected](Vector traits)
"Dot-product."
[
  (0 below: (v size min: w size)) inject: 0 into:
    [| :sum :index | sum + ((v at: index) * (w at: index))]
].


Array extend
[
  * anotherArray [
       |acc| acc := 0.
       self with: anotherArray collect: [ :a :b |
          acc := acc + ( a * b )
       ].
       ^acc
  ]
]

( #(1 3 -5) * #(4 -2 -1 ) ) printNl.


        define("dotp(a,b)sum,i")        :(dotp_end)
dotp    i = 1; sum = 0
loop    sum = sum + (a<i> * b<i>)
        i = i + 1 ?a<i> :s(loop)
        dotp = sum      :(return)
dotp_end

        a = array(3); a<1> = 1; a<2> = 3; a<3> = -5;
        b = array(3); b<1> = 4; b<2> = -2; b<3> = -1;
        output = dotp(a,b)
end


with Spark_IO;
--# inherit Spark_IO;
--# main_program;
procedure Dot_Product_Main
--# global in out Spark_IO.Outputs;
--# derives Spark_IO.Outputs from *;
is
   Limit : constant := 1000;
   type V_Elem is range -Limit .. Limit;
   V_Size : constant := 100;
   type V_Index is range 1 .. V_Size;
   type Vector is array(V_Index range <>) of V_Elem;

   type V_Prod is range -(Limit**2)*V_Size .. (Limit**2)*V_Size;
   --# assert V_Prod'Base is Integer;

   subtype Index3 is V_Index range 1 .. 3;
   subtype Vector3 is Vector(Index3);
   Vect1 : constant Vector3 := Vector3'(1, 3, -5);
   Vect2 : constant Vector3 := Vector3'(4, -2, -1);

   function Dot_Product(V1, V2 : Vector) return V_Prod
   --# pre  V1'First = V2'First
   --#  and V1'Last  = V2'Last;
   is
      Sum : V_Prod := 0;
   begin
      for I in V_Index range V1'Range
      --# assert Sum in -(Limit**2)*V_Prod(I-1) .. (Limit**2)*V_Prod(I-1);
      loop
         Sum := Sum + V_Prod(V1(I)) * V_Prod(V2(I));
      end loop;
      return Sum;
   end Dot_Product;

begin
   Spark_IO.Put_Integer(File  => Spark_IO.Standard_Output,
                        Item  => Integer(Dot_Product(Vect1, Vect2)),
                        Width => 6,
                        Base  => 10);
end Dot_Product_Main;


SELECT i, k, SUM(A.N*B.N) AS N
        FROM A INNER JOIN B ON A.j=B.j
        GROUP BY i, k


matrix a=1,3,-5
matrix b=4,-2,-1
matrix c=a*b'
di el("c",1,1)


func dot(v1: [Double], v2: [Double]) -> Double {
  return reduce(lazy(zip(v1, v2)).map(*), 0, +)
}

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


package require math::linearalgebra

set a {1 3 -5}
set b {4 -2 -1}
set dotp [::math::linearalgebra::dotproduct $a $b]
proc pp vec {return \[[join $vec ,]\]}
puts "[pp $a] \u2219 [pp $b] = $dotp"


#import int

dot = sum:-0+ product*p

#cast %z

test = dot(<1,3,-5>,<4,-2,-1>)


Private Function dot_product(x As Variant, y As Variant) As Double
    dot_product = WorksheetFunction.SumProduct(x, y)
End Function

Public Sub main()
    Debug.Print dot_product([{1,3,-5}], [{4,-2,-1}])
End Sub


WScript.Echo DotProduct("1,3,-5","4,-2,-1")

Function DotProduct(vector1,vector2)
	arrv1 = Split(vector1,",")
	arrv2 = Split(vector2,",")
	If UBound(arrv1) <> UBound(arrv2) Then
		WScript.Echo "The vectors are not of the same length."
		Exit Function
	End If
	DotProduct = 0
	For i = 0 To UBound(arrv1)
		DotProduct = DotProduct + (arrv1(i) * arrv2(i))
	Next
End Function


Option Explicit

Function DotProduct(a() As Long, b() As Long) As Long
Dim l As Long, u As Long, i As Long
  Debug.Assert DotProduct = 0 'return value automatically initialized with 0
  l = LBound(a())
  If l = LBound(b()) Then
    u = UBound(a())
    If u = UBound(b()) Then
      For i = l To u
        DotProduct = DotProduct + a(i) * b(i)
      Next i
    Exit Function
    End If
  End If
  Err.Raise vbObjectError + 123, , "invalid input"
End Function

Sub Main()
Dim a() As Long, b() As Long, x As Long
  ReDim a(2)
  a(0) = 1
  a(1) = 3
  a(2) = -5
  ReDim b(2)
  b(0) = 4
  b(1) = -2
  b(2) = -1
  x = DotProduct(a(), b())
  Debug.Assert x = 3
  ReDim Preserve a(3)
  a(3) = 10
  ReDim Preserve b(3)
  b(3) = 2
  x = DotProduct(a(), b())
  Debug.Assert x = 23
  ReDim Preserve a(4)
  a(4) = 10
  On Error Resume Next
  x = DotProduct(a(), b())
  Debug.Assert Err.Number = vbObjectError + 123
  Debug.Assert Err.Description = "invalid input"
End Sub


Module Module1

    Function DotProduct(a As Decimal(), b As Decimal()) As Decimal
        Return a.Zip(b, Function(x, y) x * y).Sum()
    End Function

    Sub Main()
        Console.WriteLine(DotProduct({1, 3, -5}, {4, -2, -1}))
        Console.ReadLine()
    End Sub

End Module


fn dot(x []int, y []int) ?int {
    if x.len != y.len {
        return error("incompatible lengths")
    }
	mut r := 0
    for i, xi in x {
        r += xi * y[i]
    }
    return r
}

fn main() {
    d := dot([1, 3, -5], [4, -2, -1])?

    println(d)
}


def (dot_product x y)
  (sum+map (*) x y)


class Vector {
    construct new(a) {
        if (a.type != List || a.count == 0 || !a.all { |i| i is Num }) {
            Fiber.abort("Argument must be a non-empty list of numbers.")
        }
        _a = a
    }

    a { _a }
    length { _a.count }

    dot(other) {
        if (other.type != Vector || length != other.length) {
            Fiber.abort("Argument must be a Vector of the same length.")
        }
        var sum = 0
        for (i in 0...length) sum = sum + _a[i] * other.a[i]
        return sum
    }

    toString { _a.toString }
}

var v1 = Vector.new([1, 3, -5])
var v2 = Vector.new([4, -2, -1])

System.print("The dot product of %(v1) and %(v2) is %(v1.dot(v2)).")


format PE64 console
entry start

    include 'win64a.inc'

section '.text' code readable executable

    start:
        stdcall dotProduct, vA, vB
        invoke printf, msg_num, rax

        stdcall dotProduct, vA, vC
        invoke printf, msg_num, rax

        invoke ExitProcess, 0

    proc dotProduct vectorA, vectorB
        mov rax, [rcx]
        cmp rax, [rdx]
        je .calculate

        invoke printf, msg_sizeMismatch
        mov rax, 0
        ret

        .calculate:
        mov r8, rcx
        add r8, 8
        mov r9, rdx
        add r9, 8
        mov rcx, rax
        mov rax, 0
        mov rdx, 0

        .next:
            mov rbx, [r9]
            imul rbx, [r8]
            add rax, rbx
            add r8, 8
            add r9, 8
            loop .next

        ret
    endp

section '.data' data readable

    msg_num db "%d", 0x0D, 0x0A, 0
    msg_sizeMismatch db "Size mismatch; can't calculate.", 0x0D, 0x0A, 0

    struc Vector [symbols] {
        common
        .length dq (.end - .symbols) / 8
        .symbols dq symbols
        .end:
    }

    vA Vector 1, 3, -5
    vB Vector 4, -2, -1
    vC Vector 7, 2, 9, 0

section '.idata' import data readable writeable

    library kernel32, 'KERNEL32.DLL',\
            msvcrt, 'MSVCRT.DLL'

    include 'api/kernel32.inc'

    import  msvcrt,\
            printf, 'printf'


include c:\cxpl\codes;

func DotProd(U, V, L);
int U, V, L;
int S, I;
[S:= 0;
for I:= 0 to L-1 do S:= S + U(I)*V(I);
return S;
];

[IntOut(0, DotProd([1, 3, -5], [4, -2, -1], 3));
CrLf(0);
]


sub sq_mul(a(), b(), c())
	local n, i

	n = arraysize(a(), 1)

	for i = 1 to n
		c(i) = a(i) * b(i)
	next i
end sub

sub sq_sum(a())
	local n, i, r

	n = arraysize(a(), 1)

	for i = 1 to n
		r = r + a(i)
	next i
	return r
end sub

dim a(3), b(3), c(3)

a(1) = 1 : a(2) = 3 : a(3) = -5
b(1) = 4 : b(2) = -2 : b(3) = -1
sq_mul(a(), b(), c())

print sq_sum(c())


const std = @import("std");
const Vector = std.meta.Vector;

pub fn main() !void {
    const a: Vector(3, i32) = [_]i32{1, 3, -5};
    const b: Vector(3, i32) = [_]i32{4, -2, -1};
    var dot: i32 = @reduce(.Add, a*b);

    try std.io.getStdOut().writer().print("{d}\n", .{dot});
}


10 DIM a(3): LET a(1)=1: LET a(2)=3: LET a(3)=-5
20 DIM b(3): LET b(1)=4: LET b(2)=-2: LET b(3)=-1
30 LET sum=0
40 FOR i=1 TO 3: LET sum=sum+a(i)*b(i): NEXT i
50 PRINT sum


F sentenceType(s)
   I s.empty
      R ‘’

   [Char] types
   L(c) s
      I c == ‘?’
         types.append(Char(‘Q’))
      E I c == ‘!’
         types.append(Char(‘E’))
      E I c == ‘.’
         types.append(Char(‘S’))

   I s.last !C ‘?!.’
      types.append(Char(‘N’))

   R types.join(‘|’)

V s = ‘hi there, how are you today? I'd like to present to you the washing machine 9001. You have been nominated to win one of these! Just make sure you don't break it’
print(sentenceType(s))


BEGIN # determuine the type of a sentence by looking at the final punctuation  #
    CHAR exclamation = "E"; # classification codes... #
    CHAR question    = "Q";
    CHAR serious     = "S";
    CHAR neutral     = "N";
    # returns the type(s) of the sentence(s) in s - exclamation, question,     #
    #                     serious or neutral; if there are multiple sentences  #
    #                     the types are separated by |                         #
    PROC classify = ( STRING s )STRING:
         BEGIN
            STRING result := "";
            BOOL pending neutral := FALSE;
            FOR s pos FROM LWB s TO UPB s DO
                IF   pending neutral := FALSE;
                     CHAR c = s[ s pos ];
                     c = "?"
                THEN result +:= question    + "|"
                ELIF c = "!"
                THEN result +:= exclamation + "|"
                ELIF c = "."
                THEN result +:= serious     + "|"
                ELSE pending neutral := TRUE
                FI
            OD;
            IF   pending neutral
            THEN result +:= neutral + "|"
            FI;
            # if s was empty, then return an empty string, otherwise remove the final separator #
            IF result = "" THEN "" ELSE result[ LWB result : UPB result - 1 ] FI
         END # classify # ;
    # task test case #
    print( ( classify( "hi there, how are you today? I'd like to present to you the washing machine 9001. "
                     + "You have been nominated to win one of these! Just make sure you don't break it"
                     )
           , newline
           )
         )
END


Sentence := "hi there, how are you today? I'd like to present to you the washing machine 9001. You have been nominated to win one of these! Just make sure you don't break it"
Msgbox, % SentenceType(Sentence)

SentenceType(Sentence) {
	Sentence := Trim(Sentence)
	Loop, Parse, Sentence, .?!
	{
		N := (!E && !Q && !S)
		, S := (InStr(SubStr(Sentence, InStr(Sentence, A_LoopField)+StrLen(A_LoopField), 3), "."))
		, Q := (InStr(SubStr(Sentence, InStr(Sentence, A_LoopField)+StrLen(A_LoopField), 3), "?"))
		, E := (InStr(SubStr(Sentence, InStr(Sentence, A_LoopField)+StrLen(A_LoopField), 3), "!"))
		, type .= (E) ? ("E|") : ((Q) ? ("Q|") : ((S) ? ("S|") : "N|"))
		, D := SubStr(Sentence, InStr(Sentence, A_LoopField)+StrLen(A_LoopField), 3)
	}
	return (D = SubStr(Sentence, 1, 3)) ? RTrim(RTrim(type, "|"), "N|") : RTrim(type, "|")
}


# syntax: GAWK -f DETERMINE_SENTENCE_TYPE.AWK
BEGIN {
    str = "hi there, how are you today? I'd like to present to you the washing machine 9001. You have been nominated to win one of these! Just make sure you don't break it"
    main(str)
    main("Exclamation! Question? Serious. Neutral")
    exit(0)
}
function main(str,  c) {
    while (length(str) > 0) {
      c = substr(str,1,1)
      sentence = sentence c
      if (c == "!") {
        prn("E")
      }
      else if (c == ".") {
        prn("S")
      }
      else if (c == "?") {
        prn("Q")
      }
      str = substr(str,2)
    }
    prn("N")
    print("")
}
function prn(type) {
    gsub(/^ +/,"",sentence)
    printf("%s %s\n",type,sentence)
    sentence = ""
}


% This iterator takes a string and yields one of 'E', 'Q',
% 'S' or 'N' for every sentence found.
% Because sentences are separated by punctuation, only the
% last one can be 'N'.

sentence_types = iter (s: string) yields (char)
    own punct: string := "!?."  % relevant character classes
    own space: string := " \t\n"
    own types: string := "EQS"  % sentence type characters

    prev_punct: bool := false   % whether the previous character was punctuation
    last_punct: int := 0        % index of last punctuation character encountered
    sentence: bool := true      % whether there are words since the last punctuation

    for c: char in string$chars(s) do
        pu: int := string$indexc(c, punct)
        sp: int := string$indexc(c, space)
        if pu ~= 0 then
            prev_punct := true
            last_punct := pu
        elseif sp ~= 0 then
            if prev_punct then
                % a space after punctuation means a sentence has ended here
                yield(types[last_punct])
                sentence := false
            end
            prev_punct := false
            sentence := false
        else
            sentence := true
        end
    end

    % handle the last sentence
    if prev_punct then yield(types[last_punct])
    elseif sentence then yield('N')
    end
end sentence_types

% Test
start_up = proc ()
    po: stream := stream$primary_output()
    test: string :=
        "hi there, how are you today? I'd like to " ||
        "present to you the washing machine 9001. You " ||
        "have been nominated to win one of these! Just " ||
        "make sure you don't break it"

    % print the type of each sentence
    for c: char in sentence_types(test) do
        stream$putc(po, c)
    end
end start_up


const SentenceTypes: {
	["?"]:"Q",
	["."]:"S",
	["!"]:"E"
}

fn DetermineSentenceType(Char)
	return SentenceTypes[Char]||"N"
cls

fn GetSentences(Text)
	var Sentences: [],
		Index: 0,
		Length: #Text
	loop i:0;i<Length;i+:1 do
		var Char: string.subs(Text,i,1)
		var Type: DetermineSentenceType(Char)
		if Type != "N" || i==Length-1 then
			log(string.sub(Text,Index,i+1)+" ("+Type+")")
			Index:i+2;
		cls
	cls
cls

GetSentences("hi there, how are you today? I'd like to present to you the washing machine 9001. You have been nominated to win one of these! Just make sure you don't break it")


USING: combinators io kernel regexp sequences sets splitting
wrap.strings ;

! courtesy of https://www.infoplease.com/common-abbreviations

CONSTANT: common-abbreviations {
    "A.B." "abbr." "Acad." "A.D." "alt." "A.M." "Assn."
    "at. no." "at. wt." "Aug." "Ave." "b." "B.A." "B.C." "b.p."
    "B.S." "c." "Capt." "cent." "co." "Col." "Comdr." "Corp."
    "Cpl." "d." "D.C." "Dec." "dept." "dist." "div." "Dr." "ed."
    "est." "et al." "Feb." "fl." "gal." "Gen." "Gov." "grad."
    "Hon." "i.e." "in." "inc." "Inst." "Jan." "Jr." "lat."
    "Lib." "long." "Lt." "Ltd." "M.D." "Mr." "Mrs." "mt." "mts."
    "Mus." "no." "Nov." "Oct." "Op." "pl." "pop." "pseud." "pt."
    "pub." "Rev." "rev." "R.N." "Sept." "Ser." "Sgt." "Sr."
    "St." "uninc." "Univ." "U.S." "vol." "vs." "wt."
}

: sentence-enders ( str -- newstr )
    R/ \)/ "" re-replace
    " " split harvest
    unclip-last swap
    [ common-abbreviations member? ] reject
    [ last ".!?" member? ] filter
    swap suffix ;

: serious? ( str -- ? ) last CHAR: . = ;
: neutral? ( str -- ? ) last ".!?" member? not ;
: mixed? ( str -- ? ) "?!" intersect length 2 = ;
: exclamation? ( str -- ? ) last CHAR: ! = ;
: question? ( str -- ? ) last CHAR: ? = ;

: type ( str -- newstr )
    {
        { [ dup serious? ] [ drop "S" ] }
        { [ dup neutral? ] [ drop "N" ] }
        { [ dup mixed? ] [ drop "EQ" ] }
        { [ dup exclamation? ] [ drop "E" ] }
        { [ dup question? ] [ drop "Q" ] }
        [ drop "UNKNOWN" ]
    } cond ;

: sentences ( str -- newstr )
    sentence-enders [ type ] map "|" join ;

: show ( str -- )
    dup sentences " -> " glue 60 wrap-string print ;

"Hi there, how are you today? I'd like to present to you the washing machine 9001. You have been nominated to win one of these! Just make sure you don't break it" show
nl
"(There was nary a mouse stirring.) But the cats were going
bonkers!" show
nl
"\"Why is the car so slow?\" she said." show
nl
"Hello, Mr. Anderson!" show
nl
"Are you sure?!?! How can you know?" show


function sentype( byref s as string ) as string
    'determines the sentence type of the first sentence in the string
    'returns "E" for an exclamation, "Q" for a question, "S" for serious
    'and "N" for neutral.
    'modifies the string to remove the first sentence
    for i as uinteger = 1 to len(s)
        if mid(s, i, 1) = "!" then
            s=right(s,len(s)-i)
            return "E"
        end if
        if mid(s, i, 1) = "." then
            s=right(s,len(s)-i)
            return "S"
        end if
        if mid(s, i, 1) = "?" then
            s=right(s,len(s)-i)
            return "Q"
        end if
    next i
    'if we get to the end without encountering punctuation, this
    'must be a neutral sentence, which can only happen as the last one
    s=""
    return "N"
end function

dim as string spam = "hi there, how are you today? I'd like to present to you the washing machine 9001. You have been nominated to win one of these! Just make sure you don't break it"

while len(spam)>0
    print sentype(spam)
wend


package main

import (
    "fmt"
    "strings"
)

func sentenceType(s string) string {
    if len(s) == 0 {
        return ""
    }
    var types []string
    for _, c := range s {
        if c == '?' {
            types = append(types, "Q")
        } else if c == '!' {
            types = append(types, "E")
        } else if c == '.' {
            types = append(types, "S")
        }
    }
    if strings.IndexByte("?!.", s[len(s)-1]) == -1 {
        types = append(types, "N")
    }
    return strings.Join(types, "|")
}

func main() {
    s := "hi there, how are you today? I'd like to present to you the washing machine 9001. You have been nominated to win one of these! Just make sure you don't break it"
    fmt.Println(sentenceType(s))
}


# Input: a string
# Output: a stream of sentence type indicators
def sentenceTypes:
  def trim: sub("^ +";"") | sub(" +$";"");
  def parse:
    capture("(?<s>[^?!.]*)(?<p>[?!.])(?<remainder>.*)" )
    // {p:"", remainder:""};
  def encode:
    if   . == "?" then "Q"
    elif . == "!" then "E"
    elif . == "." then "S"
    else "N"
    end;
  trim
  | select(length>0)
  | parse
  | (.p | encode), (.remainder | sentenceTypes);

def s: "hi there, how are you today? I'd like to present to you the washing machine 9001. You have been nominated to win one of these! Just make sure you don't break it";

s | sentenceTypes


const text = """
Hi there, how are you today? I'd like to present to you the washing machine 9001.
You have been nominated to win one of these! Just make sure you don't break it"""

haspunctotype(s) = '.' in s ? "S" : '!' in s ? "E" : '?' in s ? "Q" : "N"

text = replace(text, "\n" => " ")
parsed = strip.(split(text, r"(?:(?:(?<=[\?\!\.])(?:))|(?:(?:)(?=[\?\!\.])))"))
isodd(length(parsed)) && push!(parsed, "")  # if ends without pnctuation
for i in 1:2:length(parsed)-1
    println(rpad(parsed[i] * parsed[i + 1], 52),  " ==> ", haspunctotype(parsed[i + 1]))
end


text = "hi there, how are you today? I'd like to present to you the washing machine 9001. You have been nominated to win one of these! Just make sure you don't break it"
p2t = { [""]="N", ["."]="S", ["!"]="E", ["?"]="Q" }
for s, p in text:gmatch("%s*([^%!%?%.]+)([%!%?%.]?)") do
  print(s..p..":  "..p2t[p])
end


use strict;
use warnings;
use feature 'say';
use Lingua::Sentence;

my $para1 = <<'EOP';
hi there, how are you today? I'd like to present to you the washing machine
9001. You have been nominated to win one of these! Just make sure you don't
break it
EOP

my $para2 = <<'EOP';
Just because there are punctuation characters like "?", "!" or especially "."
present, it doesn't necessarily mean you have reached the end of a sentence,
does it Mr. Magoo? The syntax highlighting here for Perl isn't bad at all.
EOP

my $splitter = Lingua::Sentence->new("en");
for my $text ($para1, $para2) {
  for my $s (split /\n/, $splitter->split( $text =~ s/\n//gr ) {
    print "$s| ";
    if    ($s =~ /!$/)  { say 'E' }
    elsif ($s =~ /\?$/) { say 'Q' }
    elsif ($s =~ /\.$/) { say 'S' }
    else                { say 'N' }
  }
}


with javascript_semantics
constant s = `hi there, how are you today? I'd like to present
to you the washing machine 9001. You have been nominated to win
one of these! Just make sure you don't break it`
sequence t = split_any(trim(s),"?!."),
         u = substitute_all(s,t,repeat("|",length(t))),
         v = substitute_all(u,{"|?","|!","|.","|"},"QESN"),
         w = join(v,'|')
?w


import re

txt = """
Hi there, how are you today? I'd like to present to you the washing machine 9001.
You have been nominated to win one of these! Just make sure you don't break it"""

def haspunctotype(s):
    return 'S' if '.' in s else 'E' if '!' in s else 'Q' if '?' in s else 'N'

txt = re.sub('\n', '', txt)
pars = [s.strip() for s in re.split("(?:(?:(?<=[\?\!\.])(?:))|(?:(?:)(?=[\?\!\.])))", txt)]
if len(pars) % 2:
    pars.append('')  # if ends without punctuation
for i in range(0, len(pars)-1, 2):
    print((pars[i] + pars[i + 1]).ljust(54), "==>", haspunctotype(pars[i + 1]))


use Lingua::EN::Sentence;

my $paragraph = q:to/PARAGRAPH/;
hi there, how are you today? I'd like to present to you the washing machine
9001. You have been nominated to win one of these! Just make sure you don't
break it

Just because there are punctuation characters like "?", "!" or especially "."
present, it doesn't necessarily mean you have reached the end of a sentence,
does it Mr. Magoo? The syntax highlighting here for Raku isn't the best.
PARAGRAPH

say join "\n\n", $paragraph.&get_sentences.map: {
    /(<:punct>)$/;
    $_ ~ ' | ' ~ do
    given $0 {
        when '!' { 'E' };
        when '?' { 'Q' };
        when '.' { 'S' };
        default  { 'N' };
    }
}


fn sentence_type(s string) string {
    if s.len == 0 {
        return ""
    }
    mut types := []string{}
    for c in s.split('') {
        if c == '?' {
            types << "Q"
        } else if c == '!' {
            types << "E"
        } else if c == '.' {
            types << "S"
        }
    }
    if s[s.len-1..s.len].index_any('?!.') == -1 {
        types << "N"
    }
    return types.join("|")
}

fn main() {
    s := "hi there, how are you today? I'd like to present to you the washing machine 9001. You have been nominated to win one of these! Just make sure you don't break it"
    println(sentence_type(s))
}


var sentenceType = Fn.new { |s|
    if (s.count == 0) return ""
    var types = []
    for (c in s) {
        if (c == "?") {
            types.add("Q")
        } else if (c == "!") {
            types.add("E")
        } else if (c == ".") {
            types.add("S")
        }
    }
    if (!"?!.".contains(s[-1])) types.add("N")
    return types.join("|")
}

var s = "hi there, how are you today? I'd like to present to you the washing machine 9001. You have been nominated to win one of these! Just make sure you don't break it"
System.print(sentenceType.call(s))


include xpllib; \for StrLen
int  Sentence, N, Len;
char Str;
[Sentence:= ["hi there, how are you today?",
             "I'd like to present to you the washing machine 9001.",
             "You have been nominated to win one of these!",
             "Just make sure you don't break it"];
for N:= 0 to 3 do
    [Str:= Sentence(N);
    Len:= StrLen(Str);
    case Str(Len-1) of
      ^!: ChOut(0, ^E);
      ^?: ChOut(0, ^Q);
      ^.: ChOut(0, ^S)
    other ChOut(0, ^N);
    if N < 3 then ChOut(0, ^|);
    ];
]


F mdroot(n)
   V count = 0
   V mdr = n
   L mdr > 9
      V m = mdr
      V digits_mul = 1
      L m != 0
         digits_mul *= m % 10
         m = m I/ 10
      mdr = digits_mul
      count++
   R (count, mdr)

print(‘Number: (MP, MDR)’)
print(‘======  =========’)
L(n) (123321, 7739, 893, 899998)
   print(‘#6: ’.format(n), end' ‘’)
   print(mdroot(n))

[[Int]] table
table.resize(10)
V n = 0
L min(table.map(row -> row.len)) < 5
   table[mdroot(n)[1]].append(n)
   n++

print(‘’)
print(‘MP: [n0..n4]’)
print(‘==  ========’)
L(val) table
   print(‘#2: ’.format(L.index), end' ‘’)
   print(val[0.<5])


with Ada.Text_IO, Generic_Root;   use Generic_Root;

procedure Multiplicative_Root is

   procedure Compute is new Compute_Root("*"); -- "*" for multiplicative roots

   package TIO renames Ada.Text_IO;
   package NIO is new TIO.Integer_IO(Number);

   procedure Print_Numbers(Target_Root: Number; How_Many: Natural) is
      Current: Number := 0;
      Root, Pers: Number;
   begin
       for I in 1 .. How_Many loop
	  loop
	     Compute(Current, Root, Pers);
	     exit when Root = Target_Root;
	     Current := Current + 1;
	  end loop;
	  NIO.Put(Current, Width => 6);
	  if I < How_Many then
	     TIO.Put(",");
	  end if;
	  Current := Current + 1;
       end loop;
   end Print_Numbers;

   Inputs: Number_Array := (123321, 7739, 893, 899998);
   Root, Pers: Number;
begin
   TIO.Put_Line("  Number   MDR    MP");
   for I in Inputs'Range loop
       Compute(Inputs(I), Root, Pers);
       NIO.Put(Inputs(I), Width => 8);
       NIO.Put(Root, Width => 6);
       NIO.Put(Pers, Width => 6);
       TIO.New_Line;
   end loop;
   TIO.New_Line;

   TIO.Put_Line(" MDR    first_five_numbers_with_that_MDR");
   for I in 0 .. 9 loop
      TIO.Put("  " & Integer'Image(I) & "  ");
      Print_Numbers(Target_Root => Number(I), How_Many => 5);
      TIO.New_Line;
   end loop;
end Multiplicative_Root;