function dotProduct() {
  var len = arguments[0] && arguments[0].length;
  var argsLen = arguments.length;
  var i, j = len;
  var prod, sum = 0;

  // If no arguments supplied, return undefined
  if (!len) {
    return;
  }

  // If all vectors not same length, return undefined
  i = argsLen;
  while (i--) {

    if (arguments[i].length != len) {
      return;  // return undefined
    }
  }

  // Sum terms
  while (j--) {
    i = argsLen;
    prod = 1;

    while (i--) {
      prod *= arguments[i][j];
    }
    sum += prod;
  }
  return sum;
}

function crossProduct(a, b) {

  // Check lengths
  if (a.length != 3 || b.length != 3) {
     return;
  }

  return [a[1]*b[2] - a[2]*b[1],
          a[2]*b[0] - a[0]*b[2],
          a[0]*b[1] - a[1]*b[0]];

}

function scalarTripleProduct(a, b, c) {
  return dotProduct(a, crossProduct(b, c));
}

function vectorTripleProduct(a, b, c) {
  return crossProduct(a, crossProduct(b, c));
}

// Run tests
(function () {
  var a = [3, 4, 5];
  var b = [4, 3, 5];
  var c = [-5, -12, -13];

  alert(
    'A . B: ' + dotProduct(a, b) +
    '\n' +
    'A x B: ' + crossProduct(a, b) +
    '\n' +
    'A . (B x C): ' + scalarTripleProduct(a, b, c) +
    '\n' +
    'A x (B x C): ' + vectorTripleProduct(a, b, c)
  );
}());


# these examples, respectively, refer to integer, float, boolean, and string objects
example1 = 3
example2 = 3.0
example3 = True
example4 = "hello"

# example1 now refers to a string object.
example1 = "goodbye"


#lang racket

;; define a variable and initialize it
(define foo 0)
;; increment it
(set! foo (add1 foo))

;; Racket is lexically scoped, which makes local variables work:
(define (bar)
  (define foo 100)
  (set! foo (add1 foo))
  foo)
(bar) ; -> 101

;; and it also makes it possible to have variables with a global value
;; that are accessible only in a specific local lexical scope:
(define baz
  (let () ; used to create a new scope
    (define foo 0)
    (define (bar)
      (set! foo (add1 foo))
      foo)
    bar)) ; this is the value that gets bound to `baz'
(list (baz) (baz) (baz)) ; -> '(1 2 3)

;; define a new type, and initialize a variable with an instance
(struct pos (x y))
(define p (pos 1 2))
(list (pos-x p) (pos-y p)) ; -> '(1 2)

;; for a mutable reference, a struct (or some specific fields in a
;; struct) can be declared mutable
(struct mpos (x y) #:mutable)
(define mp (mpos 1 2))
(set-mpos-x! mp 11)
(set-mpos-y! mp 22)
(list (mpos-x mp) (mpos-y mp)) ; -> '(11 22)

;; but for just a mutable value, we have boxes as a builtin type
(define b (box 10))
(set-box! b (add1 (unbox b)))
(unbox b) ; -> 11

;; (Racket has many more related features: static typing in typed
;; racket, structs that are extensions of other structs,
;; pattern-matching on structs, classes, and much more)


package main

import (
    "fmt"
    "math"
)

func max(a, b uint64) uint64 {
    if a > b {
        return a
    }
    return b
}

func min(a, b uint64) uint64 {
    if a < b {
        return a
    }
    return b
}

func ndigits(x uint64) (n int) {
    for ; x > 0; x /= 10 {
        n++
    }
    return
}

func dtally(x uint64) (t uint64) {
    for ; x > 0; x /= 10 {
        t += 1 << (x % 10 * 6)
    }
    return
}

var tens [20]uint64

func init() {
    tens[0] = 1
    for i := 1; i < 20; i++ {
        tens[i] = tens[i-1] * 10
    }
}

func fangs(x uint64) (f []uint64) {
    nd := ndigits(x)
    if nd&1 == 1 {
        return
    }
    nd /= 2
    lo := max(tens[nd-1], (x+tens[nd]-2)/(tens[nd]-1))
    hi := min(x/lo, uint64(math.Sqrt(float64(x))))
    t := dtally(x)
    for a := lo; a <= hi; a++ {
        b := x / a
        if a*b == x &&
            (a%10 > 0 || b%10 > 0) &&
            t == dtally(a)+dtally(b) {
            f = append(f, a)
        }
    }
    return
}

func showFangs(x uint64, f []uint64) {
    fmt.Print(x)
    if len(f) > 1 {
        fmt.Println()
    }
    for _, a := range f {
        fmt.Println(" =", a, "×", x/a)
    }
}

func main() {
    for x, n := uint64(1), 0; n < 26; x++ {
        if f := fangs(x); len(f) > 0 {
            n++
            fmt.Printf("%2d: ", n)
            showFangs(x, f)
        }
    }
    fmt.Println()
    for _, x := range []uint64{16758243290880, 24959017348650, 14593825548650} {
        if f := fangs(x); len(f) > 0 {
            showFangs(x, f)
        } else {
            fmt.Println(x, "is not vampiric")
        }
    }
}


def dot_product(a; b):
  reduce range(0;a|length) as $i (0; . + (a[$i] * b[$i]) );

# for 3d vectors
def cross_product(a;b):
  [ a[1]*b[2] - a[2]*b[1], a[2]*b[0] - a[0]*b[2], a[0]*b[1]-a[1]*b[0] ];

def scalar_triple_product(a;b;c):
  dot_product(a; cross_product(b; c));

def vector_triple_product(a;b;c):
  cross_product(a; cross_product(b; c));

def main:
  [3, 4, 5] as $a
  | [4, 3, 5] as $b
  | [-5, -12, -13] as $c
  | "a . b = \(dot_product($a; $b))",
    "a x b = [\( cross_product($a; $b) | map(tostring) | join (", ") )]" ,
    "a . (b x c) = \( scalar_triple_product ($a; $b; $c)) )",
    "a x (b x c) = [\( vector_triple_product($a; $b; $c)|map(tostring)|join (", ") )]" ;


using LinearAlgebra

const a = [3, 4, 5]
const b = [4, 3, 5]
const c = [-5, -12, -13]

println("Test Vectors:")
@show a b c

println("\nVector Products:")
@show a ⋅ b
@show a × b
@show a ⋅ (b × c)
@show a × (b × c)


// version 1.1.2

class Vector3D(val x: Double, val y: Double, val z: Double) {
    infix fun dot(v: Vector3D) = x * v.x + y * v.y + z * v.z

    infix fun cross(v: Vector3D) =
        Vector3D(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x)

    fun scalarTriple(v: Vector3D, w: Vector3D) = this dot (v cross w)

    fun vectorTriple(v: Vector3D, w: Vector3D) = this cross (v cross w)

    override fun toString() = "($x, $y, $z)"
}

fun main(args: Array<String>) {
    val a = Vector3D(3.0, 4.0, 5.0)
    val b = Vector3D(4.0, 3.0, 5.0)
    val c = Vector3D(-5.0, -12.0, -13.0)
    println("a = $a")
    println("b = $b")
    println("c = $c")
    println()
    println("a . b     = ${a dot b}")
    println("a x b     = ${a cross b}")
    println("a . b x c = ${a.scalarTriple(b, c)}")
    println("a x b x c = ${a.vectorTriple(b, c)}")
}


my @y = <A B C D>; # Array of strings 'A', 'B', 'C', and 'D'
say @y[2]; # the @-sigil requires the container to implement the role Positional
@y[1,2] = 'x','y'; # that's where subscripts and many other things come from
say @y; # OUTPUT«[A x y D]␤» # we start to count at 0 btw.

my $x = @y; # $x is now a reference for the array @y

say $x[1]; # prints 'x' followed by a newline character

my Int $with-type-check; # type checks are enforced by the compiler

my Int:D $defined-i = 10; # definedness can also be asked for and default values are required in that case

my Int:D $after-midnight where * > 24 = 25; # SQL is fun and so is Raku

my \bad = 'good'; # if you don't like sigils
say bad; # you don't have to use them
say "this is quite bad"; # but then string interpolation
say "this is quite {bad}" # becomes more wordy


aa = 10                                /*assigns chars    10  ───►  AA  */
bb = ''                                /*assigns a null value ───►  BB  */
cc = 2*10                              /*assigns chars    20  ───►  CC  */
dd = 'Adam'                            /*assigns chars Adam   ───►  DD  */
ee = "Adam"                            /*same as above        ───►  EE  */
ff = 10.                               /*assigns chars   10.  ───►  FF  */
gg = '10.'                             /*same as above        ───►  GG  */
hh = "+10"                             /*assigns chars  +10   ───►  hh  */
ii = 1e1                               /*assigns chars  1e1   ───►  ii  */
jj = +.1e+2                            /*assigns chars  .1e+2 ───►  jj  */


import Data.List (sort)
import Control.Arrow ((&&&))

-- VAMPIRE NUMBERS ------------------------------------------------------------
vampires :: [Int]
vampires = filter (not . null . fangs) [1 ..]

fangs :: Int -> [(Int, Int)]
fangs n
  | odd w = []
  | otherwise = ((,) <*> quot n) <$> filter isfang (integerFactors n)
  where
    ndigit :: Int -> Int
    ndigit 0 = 0
    ndigit n = 1 + ndigit (quot n 10)
    w = ndigit n
    xmin = 10 ^ (quot w 2 - 1)
    xmax = xmin * 10
    isfang x =
      x > xmin &&
      x < y &&
      y < xmax && -- same length
      (quot x 10 /= 0 || quot y 10 /= 0) && -- not zero-ended
      sort (show n) == sort (show x ++ show y)
      where
        y = quot n x

-- FACTORS --------------------------------------------------------------------
integerFactors :: Int -> [Int]
integerFactors n
  | n < 1 = []
  | otherwise =
    lows ++
    (quot n <$>
     (if intSquared == n -- A perfect square,
        then tail -- and cofactor of square root would be redundant.
        else id)
       (reverse lows))
  where
    (intSquared, lows) =
      (^ 2) &&& (filter ((0 ==) . rem n) . enumFromTo 1) $
      floor (sqrt $ fromIntegral n)

-- TEST -----------------------------------------------------------------------
main :: IO [()]
main =
  mapM
    (print . ((,) <*>) fangs)
    (take 25 vampires ++ [16758243290880, 24959017348650, 14593825548650])


#!/bin/ksh

# Vector products
#	# dot product (a scalar quantity) A • B = a1b1 + a2b2 + a3b3  + ...
#	# cross product (a vector quantity) A x B = (a2b3 - a3b2, a3b1 - a1b3, a1b2 - a2b1)
#	# scalar triple product (a scalar quantity) A • (B x C)
#	# vector triple product (a vector quantity) A x (B x C)

#	# Variables:
#
typeset -a A=(  3    4    5 )
typeset -a B=(  4    3    5 )
typeset -a C=( -5  -12  -13 )

#	# Functions:
#

#	# Function _dotprod(vec1, vec2) - Return the (scalar) dot product of 2 vectors
#
function _dotprod {
	typeset _vec1 ; nameref _vec1="$1"	# Input vector 1
	typeset _vec2 ; nameref _vec2="$2"	# Input vector 2
	typeset _i ; typeset -si _i
	typeset _dotp ; integer _dotp=0

	for ((_i=0; _i<${#_vec1[*]}; _i++)); do
		(( _dotp+=(_vec1[_i] * _vec2[_i]) ))
	done
	echo ${_dotp}
}

#	# Function _crossprod(vec1, vec2, vec) - Return the (vector) cross product of 2 vectors
#
function _crossprod {
	typeset _vec1 ; nameref _vec1="$1"	# Input vector 1
	typeset _vec2 ; nameref _vec2="$2"	# Input vector 2
	typeset _vec3 ; nameref _vec3="$3"	# Output vector

	_vec3+=( $(( _vec1[1]*_vec2[2] - _vec1[2]*_vec2[1] )) )
	_vec3+=( $(( _vec1[2]*_vec2[0] - _vec1[0]*_vec2[2] )) )
	_vec3+=( $(( _vec1[0]*_vec2[1] - _vec1[1]*_vec2[0] )) )
}

#	# Function _scal3prod(vec1, vec2, vec3) - Return the (scalar) scalar triple product of 3 vectors
#
function _scal3prod {
	typeset _vec1 ; nameref _vec1="$1"	# Input vector 1
	typeset _vec2 ; nameref _vec2="$2"	# Input vector 2
	typeset _vec3 ; nameref _vec3="$3"	# Input vector 3
	typeset _vect ; typeset -a _vect	# temp vector

	_crossprod _vec2 _vec3 _vect		# (B x C)
	echo $(_dotprod _vec1 _vect)		# A • (B x C)

}

#	# Function _vect3prod(vec1, vec2, vec3, vec) - Return the (vector) vector triple product of 3 vectors
#
function _vect3prod {
	typeset _vec1 ; nameref _vec1="$1"	# Input vector 1
	typeset _vec2 ; nameref _vec2="$2"	# Input vector 2
	typeset _vec3 ; nameref _vec3="$3"	# Input vector 3
	typeset _vec4 ; nameref _vec4="$4"	# Output vector
	typeset _vect ; typeset -a _vect	# temp vector

	_crossprod _vec2 _vec3 _vect		# (B x C)
	_crossprod _vec1 _vect _vec4		# A x (B x C)
}

 ######
# main #
 ######

print "The dot product A • B = $(_dotprod A B)"

typeset -a arr
_crossprod A B arr
print "The cross product A x B = ( ${arr[@]} )"

print "The scalar triple product A • (B x C) = $(_scal3prod A B C)"

typeset -m crossprod=arr ; typeset -a arr
_vect3prod A B C arr
print "The vector triple product A x (B x C) = ( ${arr[@]} )"


{def dotProduct
 {lambda {:a :b}
  {+ {* {A.get 0 :a} {A.get 0 :b}}
     {* {A.get 1 :a} {A.get 1 :b}}
     {* {A.get 2 :a} {A.get 2 :b}}}}}
-> dotProduct

{def crossProduct
 {lambda {:a :b}
  {A.new {- {* {A.get 1 :a} {A.get 2 :b}}
            {* {A.get 2 :a} {A.get 1 :b}}}
         {- {* {A.get 2 :a} {A.get 0 :b}}
            {* {A.get 0 :a} {A.get 2 :b}}}
         {- {* {A.get 0 :a} {A.get 1 :b}}
            {* {A.get 1 :a} {A.get 0 :b}}} }}}
-> crossProduct

{def A {A.new 3 4 5}}      -> A = [3,4,5]
{def B {A.new 4 3 5}}      -> B = [4,3,5]
{def C {A.new -5 -12 -13}} -> C = [4,3,5]

A.B     : {dotProduct {A} {B}}                      -> 49
AxB     : {crossProduct {A} {B}}                    -> [5,5,-7]
A.(BxC) : {dotProduct {A} {crossProduct {B} {C}}}   -> 6
Ax(BxC) : {crossProduct {A} {crossProduct {B} {C}}} -> [-267,204,-3]


$a_global_var = 5
class Demo
  @@a_class_var = 6
  A_CONSTANT = 8
  def initialize
    @an_instance_var = 7
  end
  def incr(a_local_var)
    @an_instance_var += a_local_var
  end
end


$ include "seed7_05.s7i";

var integer: foo is 5;   # foo is global

const proc: aFunc is func
  local
    var integer: bar is 10;   # bar is local to aFunc
  begin
    writeln("foo + bar = " <& foo + bar);
  end func;

const proc: main is func
  begin
    aFunc;
  end func;


procedure main()
    write("First 25 vampire numbers and their fangs:")
    every fangs := vampire(n := seq())\25 do write(right(n,20),":",fangs)
    write("\nOther numbers:")
    every n := 16758243290880 | 24959017348650 | 14593825548650 do
        write(right(n,20),": ",vampire(n)|"toothless")
end

procedure vampire(n)
    ns := string(n)
    if *ns % 2 = 1 then fail
    every (fangs := "") ||:= " "||fangCheck(n, *ns/2, f1 := 2 to integer(sqrt(n)), n/f1)
    if *fangs > 0 then return fangs
end

procedure fangCheck(n, n2, f1, f2)
    if f1*f2 ~= n then fail
    if n2 ~= *(f1|f2) then fail
    if (f1|f2) % 10 ~= 0 then
         if csort(f1||f2) == csort(n) then return "("||f1||","||f2||")"
end

procedure csort(s)  # Adapted from csort(s) in Icon IPL
    every (s1 := "", c := !cset(s)) do every find(c, s) do s1 ||:= c
    return s1
end


    print "Vector products of 3-D vectors"

    print "Dot   product of 3,4,5 and 4,3,5 is "
    print DotProduct(   "3,4,5", "4,3,5")
    print "Cross product of 3,4,5 and 4,3,5 is "
    print CrossProduct$( "3,4,5", "4,3,5")
    print "Scalar triple product of 3,4,5,    4,3,5    -5, -12, -13 is "
    print ScalarTripleProduct( "3,4,5", "4,3,5", "-5, -12, -13")
    print "Vector triple product of 3,4,5,    4,3,5    -5, -12, -13 is "
    print VectorTripleProduct$( "3,4,5", "4,3,5", "-5, -12, -13")

    end

    function DotProduct( i$, j$)
        ix =val( word$( i$, 1, ","))
        iy =val( word$( i$, 2, ","))
        iz =val( word$( i$, 3, ","))
        jx =val( word$( j$, 1, ","))
        jy =val( word$( j$, 2, ","))
        jz =val( word$( j$, 3, ","))
        DotProduct = ix *jx +iy *jy + iz *jz
    end function

    function CrossProduct$( i$, j$)
        ix =val( word$( i$, 1, ","))
        iy =val( word$( i$, 2, ","))
        iz =val( word$( i$, 3, ","))
        jx =val( word$( j$, 1, ","))
        jy =val( word$( j$, 2, ","))
        jz =val( word$( j$, 3, ","))
        cpx =iy *jz -iz *jy
        cpy =iz *jx -ix *jz
        cpz =ix *jy -iy *jx
        CrossProduct$ =str$( cpx); ","; str$( cpy); ","; str$( cpz)
    end function

    function ScalarTripleProduct( i$, j$, k$))
        ScalarTripleProduct =DotProduct( i$, CrossProduct$( j$, k$))
    end function

    function VectorTripleProduct$( i$, j$, k$))
        VectorTripleProduct$ =CrossProduct$( i$, CrossProduct$( j$, k$))
    end function
 END SUB


set a 0        > Useless intialization - All lowercase variables have an initial value of 0
set b 66       > Simple variable assignment - ''b'' is now the ASCII value of 66, or the character 'B'
[c=0] set c 5  > Conditional variable assignment - If ''c'' is 0, then set ''c'' to 5
set ? 6        > A "goto" command; Setting the ''?'' variable defines the line of code to be executed next
set z 1        > This line of code will never be executed, because the previous skipped it
set c 10       > Line #5 skipped to here
set d A        > Assigning a variable to another variable - ''d'' is now ASCII 65, or the character 'A'
set b !        > The ''!'' deals with I/O. Setting a variable to it receives an input character and assigns it to the variable
set ! a        > Setting the exclamation point to a variable outputs that variable
set e (d+1)    > Combiners are defined inside round brackets - () - and have an addition and a subtraction function
set f (e-1)    > Variable ''e'' was assigned to ''d'' + 1 (65 + 1 = 66, character B), and ''f'' was assigned to ''e'' - 1 (66 - 1 = 65, character A)


        define('foo(x,y)a,b,c') :(foo_end)
foo     a = 1; b = 2; c = 3
        foo = a * ( x * x ) + b * y + c :(return)
foo_end


// variable declaration
var table, chair;

// assignment
var table = 10, chair = -10;

// multiple assignment to the same value
table = chair = 0;

// multiple assignment to an array
(
var table, chair;
#table, chair = [10, -10];
#table ... chair = [10, -10, 2, 3]; // with ellipsis: now chair is [-10, 2, 3]
)

// the letters a-z are predeclared in the interpreter for interactive programming
a = 10; x = a - 8;

// variables are type-neutral and mutable: reassign to different objects
a = 10; a = [1, 2, 3]; a = nil;

// immutable variables (only in class definitions)
const z = 42;

// lexical scope
// the closures g and h refer to different values of their c
(
f = {
	var c = 0;
	{ c = c + 1 }
};
g = f.value;
h = f.value;
c = 100; // this doesn't change it.
)

// dynamic scope: environments
f = { ~table = ~table + 1 };
Environment.use { ~table = 100; f.value }; // 101.
Environment.use { ~table = -1; f.value }; // 0.

// there is a default environment
~table = 7;
f.value;

// lexical scope in environments:
(
Environment.use {
	~table = 100;
	f = { ~table = ~table + 1 }.inEnvir;
};
)
f.value; // 101.

// because objects keep reference to other objects, references are not needed:
// objects can take the role of variables. But there is a Ref object, that just holds a value

a = Ref([1, 2, 3]); // a reference to an array, can also be written as a quote `[1, 2, 3];
f = { |x| x.value = x.value.squared }; // a function that operates on a ref
f.(a); // `[ 1, 4, 9 ]

// proxy objects serve as delegators in environments. This can be called line by line:
ProxySpace.push;
~z // returns a NodeProxy
~z.play; // play a silent sound
~z = ~x + ~y; // make it the sum of two silent sounds
~x = { PinkNoise.ar(0.1) }; // … which now are noise,
~y = { SinOsc.ar(440, 0, 0.1) }; // and a sine tone


Filter=: (#~`)(`:6)
odd =: 2&|
even =: [email protected]:odd
factors =: [: ([: /:~ [: */"1 ([: x: [) ^"1 [: > [: , [: { [: <@:[email protected]>: ])/ __ q: ]
digits =: 10&(#.inv)
tally =: # : [:
half =: -: : [:
even_number_of_digits =: [email protected]:[email protected]:digits
same_digits =: [email protected]:[ -:&(/:~) ,&digits/@:]
assert 1 -: 1234 same_digits 23 14
assert 0 -: 1234 same_digits 23 140
half_the_digits =: ([email protected]:[email protected]:[email protected]:[ = [email protected]:digits&>@:]) # ]
factors_with_half_the_digits =: half_the_digits factors
large =: (> <[email protected]:%:)~ # ]
candidates =: large factors_with_half_the_digits
one_trailing_zero_permitted =: (0 < [: tally 0 -.~ 10&|)"1 Filter
pairs =: (% ,. ]) [email protected]:candidates
fangs =: (same_digits"0 1 # ]) pairs

   A=:(0 2 [email protected]:-: $)&>Filter<@fangs"0]1000+i.1e4
   B=:(0 2 [email protected]:-: $)&>Filter<@fangs"0]100000+i.25501
   (,: */@:{.&.>)A,B
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┐
│21 60│15 93│35 41│30 51│21 87│27 81│80 86│201 510│260 401│210 501│204 516│150 705│135 801│158 701│152 761│161 725│167 701│141 840│201 600│231 534│281 443│152 824│231 543│246 510│251 500│
│     │     │     │     │     │     │     │       │       │       │       │       │       │       │       │       │       │       │       │       │       │       │       │204 615│       │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┤
│1260 │1395 │1435 │1530 │1827 │2187 │6880 │102510 │104260 │105210 │105264 │105750 │108135 │110758 │115672 │116725 │117067 │118440 │120600 │123354 │124483 │125248 │125433 │125460 │125500 │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┘

   <@fangs"0[] 16758243290880 24959017348650 14593825548650
┌───────────────┬───────────────┬──┐
│2817360 5948208│4230765 5899410│  │
│2751840 6089832│4129587 6043950│  │
│2123856 7890480│4125870 6049395│  │
│1982736 8452080│2949705 8461530│  │
│               │2947050 8469153│  │
└───────────────┴───────────────┴──┘

   fangs f.  NB. <laugh>
((10&(#.^:_1)@:[ -:&(/:~) ,&(10&(#.^:_1))/@:])"0 1 # ]) ((% ,. ]) (#~ (0 < [: # :[: 0 -.~ 10&|)"1)@:(((> <[email protected]:%:)~ # ]) (((-: :[:@:(# :[:)@:(10&(#.^:_1))@:[ = # :[:@:(10&(#.^:_1))&>@:]) # ]) ([: ([: /:~ [: */"1 ([: x: [) ^"1 [: > [: , [: { [: <@:[email protected]>: ])/ __ q: ]))))


Vector = {}
function Vector.new( _x, _y, _z )
    return { x=_x, y=_y, z=_z }
end

function Vector.dot( A, B )
    return A.x*B.x + A.y*B.y + A.z*B.z
end

function Vector.cross( A, B )
    return { x = A.y*B.z - A.z*B.y,
             y = A.z*B.x - A.x*B.z,
             z = A.x*B.y - A.y*B.x }
end

function Vector.scalar_triple( A, B, C )
    return Vector.dot( A, Vector.cross( B, C ) )
end

function Vector.vector_triple( A, B, C )
    return Vector.cross( A, Vector.cross( B, C ) )
end

A = Vector.new( 3, 4, 5 )
B = Vector.new( 4, 3, 5 )
C = Vector.new( -5, -12, -13 )

print( Vector.dot( A, B ) )

r = Vector.cross(A, B )
print( r.x, r.y, r.z )

print( Vector.scalar_triple( A, B, C ) )

r = Vector.vector_triple( A, B, C )
print( r.x, r.y, r.z )


import Foundation

// All variables declared outside of a struct/class/etc are global

// Swift is a typed language
// Swift can infer the type of variables
var str = "Hello, playground" // String
let letStr:String = "This is a constant"

// However, all variables must be initialized
// Intialize variable of type String to nil
var str1:String! // str1 is nil

// Assign value to str1
str1 = "foo bar" // str1 is foo bar

// Swift also has optional types
// Declare optional with type of String
var optionalString = Optional<String>("foo bar") // (Some "foo bar")

println(optionalString) // Optional("foo bar")

// Optionals can also be declared with the shorthand ?
var optionalString1:String? = "foo bar"

// ! can be used to force unwrap but will throw a runtime error if trying to unwrap a nil value
println(optionalString1!)

optionalString1 = nil // Is now nil
// println(optionalString1!) would now throw a runtime error

// Optional chaining can be used to gracefully fail if there is a nil value
if let value = optionalString1?.lowercaseString {
    // Is never executed
} else {
    println("optionalString1 is nil")
}

// Swift also has type aliasing
typealias MyNewType = String // MyNewType is an alias of String
var myNewTypeString = MyNewType("foo bar")

// Swift also has special types Any and AnyObject
// Any can hold any type
// AnyObject can hold any object type
let myAnyObjectString:AnyObject = "foo bar"

// Downcast myAnyObjectString to String
if let myString = myAnyObjectString as? String {
    println(myString) // foo bar
} else {
    println("myString is not a string")
}

// Swift treats functions as first-class
// Declare a variable with a type of a function that takes no args
// and returns Void
var myFunc:(() -> Void)
func showScopes() {
    // Variable is scoped to function
    let myFunctionVariable = "foo bar function"

    // Nested functions inherit variables declared in enclosing scope
    func nestFunc() {
        println(myFunctionVariable)
    }
    nestFunc()
}

myFunc = showScopes // myFunc is now showScopes
myFunc() // foo bar function


namespace eval foo {
    # Define a procedure with two formal arguments; they are local variables
    proc bar {callerVarName argumentVar} {
        ### Associate some non-local variables with the procedure
        global globalVar;      # Variable in global namespace
        variable namespaceVar; # Variable in local (::foo) namespace
        # Access to variable in caller's context; may be local or global
        upvar 1 callerVarName callerVar

        ### Reading a variable uses the same syntax in all cases
        puts "caller's var has $callerVar"
        # But global and namespace vars can be accessed by using qualified names
        puts "global var has $globalVar which is $::globalVar"

        ### Writing a variable has no special syntax
        ### but [set] is by far the most common command for writing
        set namespaceVar $globalVar
        incr globalVar

        ### Destroying a variable is done like this
        unset argumentVar
    }
}


import java.util.Arrays;
import java.util.HashSet;

public class VampireNumbers{
    private static int numDigits(long num){
        return Long.toString(Math.abs(num)).length();
    }

    private static boolean fangCheck(long orig, long fang1, long fang2){
        if(Long.toString(fang1).endsWith("0") && Long.toString(fang2).endsWith("0")) return false;

        int origLen = numDigits(orig);
        if(numDigits(fang1) != origLen / 2 || numDigits(fang2) != origLen / 2) return false;

        byte[] origBytes = Long.toString(orig).getBytes();
        byte[] fangBytes = (Long.toString(fang1) + Long.toString(fang2)).getBytes();
        Arrays.sort(origBytes);
        Arrays.sort(fangBytes);
        return Arrays.equals(origBytes, fangBytes);
    }

    public static void main(String[] args){
        HashSet<Long> vamps = new HashSet<Long>();
        for(long i = 10; vamps.size() <= 25; i++ ){
            if((numDigits(i) % 2) != 0) {i = i * 10 - 1; continue;}
            for(long fang1 = 2; fang1 <= Math.sqrt(i) + 1; fang1++){
                if(i % fang1 == 0){
                    long fang2 = i / fang1;
                    if(fangCheck(i, fang1, fang2) && fang1 <= fang2){
                        vamps.add(i);
                        System.out.println(i + ": [" + fang1 + ", " + fang2 +"]");
                    }
                }
            }
        }
        Long[] nums = {16758243290880L, 24959017348650L, 14593825548650L};
        for(Long i : nums){
            for(long fang1 = 2; fang1 <= Math.sqrt(i) + 1; fang1++){
                if(i % fang1 == 0){
                    long fang2 = i / fang1;
                    if(fangCheck(i, fang1, fang2) && fang1 <= fang2){
                        System.out.println(i + ": [" + fang1 + ", " + fang2 +"]");
                    }
                }
            }
        }
    }
}


Module checkit {
            class Vector {
                  \\ by default are double
                  a,b,c
                  Property ToString$ {
                        Value {
                            link parent a,b,c to a,b,c
                             value$=format$("({0}, {1}, {2})",a,b,c)
                        }
                  }
                  Operator "==" {
                        read n
                        push .a==n.a and .b==n.b and .c==n.c
                  }
                  Operator Unary {
                        .a-! : .b-! : .c-!
                  }
                  Operator "+"  {
                        Read v2
                        For this, v2 {
                              .a+=..a :.b+=..b:.c+=..c:
                        }
                  }
                  Function Mul(r)  {
                        vv=this
                        for vv {
                              .a*=r:.b*=r:.c*=r
                        }
                        =vv
                  }
                  Function Dot(v2)  {
                        def double sum
                        for  this, v2 {
                            sum=.a*..a+.b*..b+.c*..c
                        }
                        =sum
                  }
                  Operator "*" {
                        Read v2
                        For This, v2 {
                              Push .b*..c-.c*..b
                              Push .c*..a-.a*..c
                              .c<=.a*..b-.b*..a
                              Read .b, .a
                        }
                  }
                  class:
                  module Vector {
                        if match("NNN") then {
                              Read .a,.b,.c
                        }
                  }
            }
            A=Vector(3,4,5)
            B=Vector(4,3,5)
            C=Vector(-5,-12,-13)
            Print "A=";A.toString$
            Print "B=";B.toString$
            Print "C=";C.toString$
            Print "A dot B="; A.dot(B)
            AxB=A*B
            Print "A x B="; AxB.toString$
            Print "A dot (B x C)=";A.dot(B*C)
            AxBxC=A*(B*C)
            Print "A x (B x C)=";AxBxC.toString$
            Def ToString$(a)=a.toString$
            Print "A x (B x C)=";ToString$(A*(B*C))
}
Checkit


with(LinearAlgebra):
A := Vector([3,4,5]):
B := Vector([4,3,5]):
C := Vector([-5,-12,-13]):
>>>A.B;
49
>>>CrossProduct(A,B);
Vector([5, 5, -7])
>>>A.(CrossProduct(B,C));
6
>>>CrossProduct(A,CrossProduct(B,C));
Vector([-267, 204, -3])


$$ MODE TUSCRIPT,{}
var1=1, var2="b"
PRINT "var1=",var1
PRINT "var2=",var2

basket=*
DATA apples
DATA bananas
DATA cherry

LOOP n,letter="a'b'c",fruit=basket
var=CONCAT (letter,n)
SET @var=VALUE(fruit)
PRINT var,"=",@var
ENDLOOP


@(cases)
hey @a
how are you
@(or)
hey @b
long time no see
@(end)


' Initialization
A = 15                 ' global variable

Proc _Initialize(24)

_Initialize Param (1)
  Local (1)            ' [email protected] now holds 24
  [email protected] = 23              ' local variable
Return

' Assignment
A = 15                 ' global variable

Proc _Assign(24)

_Assign Param (1)
  Local (1)            ' [email protected] now holds 24
  [email protected] = 5               ' reassignment of parameter [email protected]
  [email protected] = 23              ' local variable
Return


#!/bin/sh
# The unix shell uses typeless variables
apples=6
# pears=5+4           # Some shells cannot perform addition this way
pears = `expr 5+4`    # We use the external expr to perform the calculation
myfavourite="raspberries"


def count(s): reduce s as $x (0; .+1);

# To take advantage of gojq's arbitrary-precision integer arithmetic:
def power($b): . as $in | reduce range(0;$b) as $i (1; . * $in);

# Output: a possibly empty array of pairs
def factor_pairs:
  . as $n
  | ($n / (10 | power($n|tostring|length / 2) - 1)) as $first
  | [range($first|floor; 1 + ($n | sqrt)) | select(($n % .) == 0) | [., $n / .] ] ;

# Output: a stream
def vampire_factors:
  def es: tostring|explode;
  . as $n
  | tostring as $s
  | ($s|length) as $nlen
  | if ($nlen % 2) == 1 then []
    else ($nlen / 2 ) as $half
    | [factor_pairs[]
       | select(. as [$a, $b]
           | ($a|tostring|length) == $half and ($b|tostring|length) == $half
             and count($a, $b | select(.%10 == 0)) != 2
             and ((($a|es) + ($b|es)) | sort) == ($n|es|sort) ) ]
    end ;

def task1($n):
  limit($n; range(1; infinite)
    | . as $i
    | vampire_factors
    | select(length>0)
    | "\($i):\t\(.)" );

def task2:
  16758243290880, 24959017348650, 14593825548650
  | vampire_factors as $vf
  | if $vf|length == 0
    then "\(.) is not a vampire number!"
    else "\(.):\t\($vf)"
    end;

task1(25),
"",
task2


function divisors{T<:Integer}(n::T)
    !isprime(n) || return [one(T), n]
    d = [one(T)]
    for (k, v) in factor(n)
        e = T[k^i for i in 1:v]
        append!(d, vec([i*j for i in d, j in e]))
    end
    sort(d)
end

function vampirefangs{T<:Integer}(n::T)
    fangs = T[]
    isvampire = false
    vdcnt = ndigits(n)
    fdcnt = vdcnt>>1
    iseven(vdcnt) || return (isvampire, fangs)
    !isprime(n) || return (isvampire, fangs)
    vdigs = sort(digits(n))
    d = divisors(n)
    len = length(d)
    len = iseven(len) ? len>>1 : len>>1 + 1
    for f in d[1:len]
        ndigits(f) == fdcnt || continue
        g = div(n, f)
        f%10!=0 || g%10!=0 || continue
        sort([digits(f), digits(g)]) == vdigs || continue
        isvampire = true
        append!(fangs, [f, g])
    end
    if isvampire
        fangs = reshape(fangs, (2,length(fangs)>>1))'
    end
    return (isvampire, fangs)
end


// version 1.1

data class Fangs(val fang1: Long = 0L, val fang2: Long = 0L)

fun pow10(n: Int): Long = when {
    n < 0 -> throw IllegalArgumentException("Can't be negative")
    else -> {
        var pow = 1L
        for (i in 1..n) pow *= 10L
        pow
    }
}

fun countDigits(n: Long): Int = when {
    n < 0L -> throw IllegalArgumentException("Can't be negative")
    n == 0L -> 1
    else -> {
        var count = 0
        var nn = n
        while (nn > 0L) {
            count++
            nn /= 10L
        }
        count
    }
}

fun hasTrailingZero(n: Long): Boolean = when {
    n < 0L -> throw IllegalArgumentException("Can't be negative")
    else -> n % 10L == 0L
}

fun sortedString(s: String): String {
    val ca = s.toCharArray()
    ca.sort()
    return String(ca)
}

fun isVampiric(n: Long, fl: MutableList<Fangs>): Boolean {
    if (n < 0L) return false
    val len = countDigits(n)
    if (len % 2L == 1L) return false
    val hlen = len / 2
    val first = pow10(hlen - 1)
    val last = 10L * first
    var j: Long
    var cd: Int
    val ss = sortedString(n.toString())
    for (i in first until last) {
        if (n % i != 0L) continue
        j = n / i
        if (j < i) return fl.size > 0
        cd = countDigits(j)
        if (cd > hlen) continue
        if (cd < hlen) return fl.size > 0
        if (ss != sortedString(i.toString() + j.toString())) continue
        if (!(hasTrailingZero(i) && hasTrailingZero(j))) {
            fl.add(Fangs(i, j))
        }
    }
    return fl.size > 0
}

fun showFangs(fangsList: MutableList<Fangs>): String {
    var s = ""
    for ((fang1, fang2) in fangsList) {
        s += " = $fang1 x $fang2"
    }
    return s
}

fun main(args: Array<String>) {
    println("The first 25 vampire numbers and their fangs are:")
    var count = 0
    var n: Long = 0
    val fl = mutableListOf<Fangs>()
    while (true) {
        if (isVampiric(n, fl)) {
            count++
            println("${"%2d".format(count)} : $n\t${showFangs(fl)}")
            fl.clear()
            if (count == 25) break
        }
        n++
    }
    println()
    val va = longArrayOf(16758243290880L, 24959017348650L, 14593825548650L)
    for (v in va) {
        if (isVampiric(v, fl)) {
            println("$v\t${showFangs(fl)}")
            fl.clear()
        } else {
            println("$v\t = not vampiric")
        }
    }
}


%    Create a named function/subroutine/method to compute the dot product of two vectors.
        dot(a,b)
%    Create a function to compute the cross product of two vectors.
        cross(a,b)
%    Optionally create a function to compute the scalar triple product of three vectors.
        dot(a,cross(b,c))
%    Optionally create a function to compute the vector triple product of three vectors.
        cross(a,cross(b,c))
%    Compute and display: a • b
        cross(a,b)
%    Compute and display: a x b
        cross(a,b)
%    Compute and display: a • b x c, the scaler triple product.
        dot(a,cross(b,c))
%    Compute and display: a x b x c, the vector triple product.
        cross(a,cross(b,c))


:- module vector_product.
:- interface.

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

:- implementation.
:- import_module int, list, string.

main(!IO) :-
    A = vector3d(3, 4, 5),
    B = vector3d(4, 3, 5),
    C = vector3d(-5, -12, -13),
    io.format("A . B = %d\n", [i(A `dot_product` B)], !IO),
    io.format("A x B = %s\n", [s(to_string(A `cross_product` B))], !IO),
    io.format("A . (B x C) = %d\n", [i(scalar_triple_product(A, B, C))], !IO),
    io.format("A x (B x C) = %s\n", [s(to_string(vector_triple_product(A, B, C)))], !IO).

:- type vector3d ---> vector3d(int, int, int).

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

dot_product(vector3d(A1, A2, A3), vector3d(B1, B2, B3)) =
    A1 * B1 + A2 * B2 + A3 * B3.

:- func cross_product(vector3d, vector3d) = vector3d.

cross_product(vector3d(A1, A2, A3), vector3d(B1, B2, B3)) =
    vector3d(A2 * B3 - A3 * B2, A3 * B1 - A1 * B3, A1 * B2 - A2 * B1).

:- func scalar_triple_product(vector3d, vector3d, vector3d) = int.

scalar_triple_product(A, B, C) = A `dot_product` (B `cross_product` C).

:- func vector_triple_product(vector3d, vector3d, vector3d) = vector3d.

vector_triple_product(A, B, C) = A `cross_product` (B `cross_product` C).

:- func to_string(vector3d) = string.

to_string(vector3d(X, Y, Z)) =
    string.format("(%d, %d, %d)", [i(X), i(Y), i(Z)]).


# variable declaration
#
# declare [type] [name]
# 	-or-
# decl [type] [name]
decl int test

# initialization / assignment
#
# the set statement can be used to init variables and
# assign values to them
set test 10

# datatypes
#
# ursa currently has 10 built-in types, but
# more may be added in the future.
#     boolean
#     double
#     file
#     function
#     int
#     iodevice
#     port
#     serverport
#     string
#     task
#
# also, java classes may be used as data types
# cygnus/x ursa

# scope
#
# there is a global variable space, and functions
# have their own scope. control statements (for,
# if, try, while) don't have their own scope yet,
# but this will be implemented in the near future

# referencing
#
# variables are referenced by their name
decl port p
out p endl console


Dim variable As datatype
Dim var1,var2,... As datatype


ClearAll[VampireQ]
VampireQ[num_Integer] := Module[{poss, divs},
  divs = Select[Divisors[num], # <= Sqrt[num] &];
  poss = {#, num/#} & /@ divs;
  If[Length[poss] > 0,
   poss = Select[poss, Mod[#, 10] =!= {0, 0} &];
   If[Length[poss] > 0,
    poss = Select[poss, Length[IntegerDigits[First[#]]] == Length[IntegerDigits[Last[#]]] &];
    If[Length[poss] > 0,
     poss = Select[poss, Sort[IntegerDigits[num]] == Sort[Join @@ (IntegerDigits /@ #)] &];
     If[Length[poss] > 0
      ,
      Sow[{num, poss}];
      True
      ,
      False
     ]
    ,
    False
    ]
   ,
   False
   ]
  ,
  False
 ]
]


import algorithm, math, sequtils, strformat, strutils, sugar

const Pow10 = collect(newSeq, for n in 0..18: 10 ^ n)

template isOdd(n: int): bool = (n and 1) != 0

proc fangs(n: Positive): seq[(int, int)] =
  ## Return the list fo fangs of "n" (empty if "n" is not vampiric).
  let nDigits = sorted($n)
  if nDigits.len.isOdd: return @[]
  let fangLen = nDigits.len div 2
  let inf = Pow10[fangLen - 1]
  let sup = inf * 10 - 1
  for d in inf..sup:
    if n mod d != 0: continue
    let q = n div d
    if q < d: return
    let dDigits = $d
    let qDigits = $q
    if qDigits.len > fangLen: continue
    if qDigits.len < fangLen: return
    if nDigits != sorted(dDigits & qDigits): continue
    if dDigits[^1] != '0' or qDigits[^1] != '0':
      # Finally, "n" is vampiric. Add the fangs to the result.
      result.add (d, q)

echo "First 25 vampire numbers with their fangs:"
var count = 0
var n = 10
var limit = 100
while count != 25:
  let fangList = n.fangs
  if fangList.len != 0:
    inc count
    echo &"{count:2}: {n:>6} = ", fangList.mapIt(&"{it[0]:3} × {it[1]:3}").join(" = ")
  inc n
  if n == limit:
    n *= 10
    limit *= 10

echo()
for n in [16_758_243_290_880, 24_959_017_348_650, 14_593_825_548_650]:
  let fangList = n.fangs
  if fangList.len == 0:
    echo &"{n} is not vampiric."
  else:
    echo &"{n} = ", fangList.mapIt(&"{it[0]} × {it[1]}").join(" = ")


vectorA = [3, 4, 5]
vectorB = [4, 3, 5]
vectorC = [-5, -12, -13]

dotProduct = function(x, y)
    return x[0]*y[0] + x[1]*y[1] + x[2]*y[2]
end function

crossProduct = function(x, y)
    return [x[1]*y[2] - x[2]*y[1], x[2]*y[0] - x[0]*y[2], x[0]*y[1] - x[1]*y[0]]
end function

print "Dot Product = " + dotProduct(vectorA, vectorB)
print "Cross Product = " + crossProduct(vectorA, vectorB)
print "Scalar Triple Product = " + dotProduct(vectorA, crossProduct(vectorB,vectorC))
print "Vector Triple Product = " + crossProduct(vectorA, crossProduct(vectorB,vectorC))


ПП	54	С/П	ПП	66	С/П
ИП0	ИП3	ИП6	П3	->	П0	->	П6
ИП1	ИП4	ИП7	П4	->	П1	->	П7
ИП2	ИП5	ИП8	П5	->	П2	->	П8
ПП	66
ИП6	ИП7	ИП8	П2	->	П1	->	П0
ИП9	ИПA	ИПB	П5	->	П4	->	П3
ПП	54	С/П	ПП	66	С/П
ИП0	ИП3	*	ИП1	ИП4	*	+	ИП2	ИП5	*	+	В/О
ИП1	ИП5	*	ИП2	ИП4	*	-	П9
ИП2	ИП3	*	ИП0	ИП5	*	-	ПA
ИП0	ИП4	*	ИП1	ИП3	*	-	ПB	В/О


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

PROCEDURE WriteReal(r : REAL);
VAR buf : ARRAY[0..31] OF CHAR;
BEGIN
    RealToStr(r, buf);
    WriteString(buf)
END WriteReal;

TYPE Vector = RECORD
    a,b,c : REAL;
END;

PROCEDURE Dot(u,v : Vector) : REAL;
BEGIN
    RETURN u.a * v.a
         + u.b * v.b
         + u.c * v.c
END Dot;

PROCEDURE Cross(u,v : Vector) : Vector;
BEGIN
    RETURN Vector{
        u.b*v.c - u.c*v.b,
        u.c*v.a - u.a*v.c,
        u.a*v.b - u.b*v.a
    }
END Cross;

PROCEDURE ScalarTriple(u,v,w : Vector) : REAL;
BEGIN
    RETURN Dot(u, Cross(v, w))
END ScalarTriple;

PROCEDURE VectorTriple(u,v,w : Vector) : Vector;
BEGIN
    RETURN Cross(u, Cross(v, w))
END VectorTriple;

PROCEDURE WriteVector(v : Vector);
BEGIN
    WriteString("<");
    WriteReal(v.a);
    WriteString(", ");
    WriteReal(v.b);
    WriteString(", ");
    WriteReal(v.c);
    WriteString(">")
END WriteVector;

VAR a,b,c : Vector;
BEGIN
    a := Vector{3.0, 4.0, 5.0};
    b := Vector{4.0, 3.0, 5.0};
    c := Vector{-5.0, -12.0, -13.0};

    WriteVector(a);
    WriteString(" dot ");
    WriteVector(b);
    WriteString(" = ");
    WriteReal(Dot(a,b));
    WriteLn;

    WriteVector(a);
    WriteString(" cross ");
    WriteVector(b);
    WriteString(" = ");
    WriteVector(Cross(a,b));
    WriteLn;

    WriteVector(a);
    WriteString(" cross (");
    WriteVector(b);
    WriteString(" cross ");
    WriteVector(c);
    WriteString(") = ");
    WriteVector(VectorTriple(a,b,c));
    WriteLn;

    ReadChar
END VectorProducts.


name := 'Bob'
age := 20
large_number := i64(9999999999)


let example t => io.writeln io.stdout t;


var a           // declares the variable 'a' with the default value of 'null'
a = 1           // initializes 'a'
a = "a"         // assigns a different value to 'a'
var b = 2       // declares and initializes 'b' at the same time
b = true        // assigns a different value to 'b'
var c = [3, 4]  // 'c' is assigned a List which is a reference type
c = false       // 'c' is reassigned a Bool which is a value type

var d = 1       // declaration at top level
{
    var d = 2   // declaration within a nested scope, hides top level 'd'
    var e = 3   // not visible outside its scope i.e this block
}
System.print(d) // prints the value of the top level 'd'
System.print(e) // compiler error : Variable is used but not defined


There are only three variable types: 32-bit signed integers (in the
32-bit version), IEEE-754 64-bit reals, and characters which are actually
32-bit addresses of (or pointers to) strings. When a 'char' variable is
subscripted, it accesses a single byte. All variable names must be
declared before they are used, for example:

int  I, J, K;
real X, Y, Array(10);
char String(80);

Variables (as well as all declared names, such as for procedures) must
start with a capital letter or underline. Names may contain digits or
underlines and be any length, but only the first 16 characters are
significant. Names are case-insensitive by default, unless the /c switch
is used when compiling.

Variables are usually assigned values like this: X:= 3.14, but the first
declared variables in a procedure can have argument values passed into
them. Variables other than arguments are only initialized by explicit
assignments in the body of the code.

Local variables are encapsulated in the procedures that declare them and
are not visible (are out of scope) outside those procedures. Procedures
can be (statically) nested several levels deep. The deepest procedure can
"see" all variables declared in the procedures in which it is nested. If
two variables are declared with identical names, the most local one is
used.


#!/usr/bin/perl
use warnings;
use strict;
use feature qw(say);

sub fangs {
    my $vampire = shift;
    my $length  = length 0 + $vampire;
    return if $length % 2;
    my $fang_length = $length / 2;
    my $from        = '1' . '0' x ($fang_length - 1);
    my $to          = '9' x $fang_length;
    my $sorted      = join q(), sort split //, $vampire;
    my @fangs;
    for my $f1 ($from .. 1 + sqrt $vampire) {
        next if $vampire % $f1;
        my $f2 = $vampire / $f1;
        next if $sorted ne join q(), sort split //, $f1 . $f2;
        next if 2 == grep '0' eq substr($_, -1 , 1), $f1, $f2; # Needed for the 26th number.
        push @fangs, [$f1, $f2];
    }
    return @fangs;
}

my $count = 0;
my $i     = 9;
while ($count < 25) {
    $i++;
    my @f = fangs($i);
    $count++, say join ' ', "$count. $i:", map "[@$_]", @f if @f;
}

say join ' ', $_, map "[@$_]", fangs($_) for 16758243290880, 24959017348650, 14593825548650;


using System.Console;

module VectorProducts3d
{
    Dot(x : int * int * int, y : int * int * int) : int
    {
        def (x1, x2, x3) = x;
        def (y1, y2, y3) = y;
        (x1 * y1) + (x2 * y2) + (x3 * y3)
    }

    Cross(x : int * int * int, y : int * int * int) : int * int * int
    {
        def (x1, x2, x3) = x;
        def (y1, y2, y3) = y;
        ((x2 * y3 - x3 * y2), (x3 * y1 - x1 * y3), (x1 * y2 - x2 * y1))
    }

    ScalarTriple(a : int * int * int, b : int * int * int, c : int * int * int) : int
    {
        Dot(a, Cross(b, c))
    }

    VectorTriple(a : int * int * int, b : int * int * int, c : int * int * int) : int * int * int
    {
        Cross(a, Cross(b, c))
    }

    Main() : void
    {
        def a = (3, 4, 5); def b = (4, 3, 5); def c = (-5, -12, -13);
        WriteLine(Dot(a, b)); WriteLine(Cross(a, b));
        WriteLine(ScalarTriple(a, b, c));
        WriteLine(VectorTriple(a, b, c));
    }
}


func printv(a[d] : float) -> int {
    prints("[" + a[0] + ", " + a[1] + ", " + a[2] + "]\n");
    0
}

func dot(a[d1] : float, b[d2] : float) -> float {
    a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
}

func cross(a[d1] : float, b[d2] : float) -> [_] : float {
    [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ] : float
}

func scalar_triple(a[d1] : float, b[d2] : float, c[d3] : float) -> float {
    dot(a, cross(b, c))
}

func vector_triple(a[d1] : float, b[d2] : float, c[d3] : float) -> [_] : float {
    cross(a, cross(b, c))
}

func main() -> int {
    var a = [ 3.0, 4.0, 5.0 ] : float;
    var b = [ 4.0, 3.0, 5.0 ] : float;
    var c = [ -5.0, -12.0, -13.0 ] : float;

    printv(a);
    printv(b);
    printv(c);
    printf(dot(a, b));
    printv(cross(a, b));
    printf(scalar_triple(a, b, c));
    printv(vector_triple(a, b, c));
    0
}


<xsl:variable name="foo" select="XPath expression" />
<xsl:if test="$foo = 4">... </xsl:if>     <!-- prepend '$' to reference a variable or parameter-->


UserRam equ &C000

ld a,&50       ;load hexadecimal 50 into A
ld (UserRam),a ;initialize UserRam with a value of &50

ld a,&40       ;load hexadecimal 40 into A
ld (UserRam),a ;assign UserRam a new value of &40


var v;  // global to the class that encloses this file
class C{ var v }  // global to class C, each instance gets a new v
class C{fcn f{var v=123;}} // v can only be seen by f, initialized when C is
class C{fcn init{var [const] v=5;}} // init is part of the constructor,
   so vars are promoted yo class scope. This allows const vars to be created at
   construction time
var v=123; v="hoho"; //not typed
class C{var v} // C.v OK, but just v is not found
class C{var[const]v=4} // C.v=3 illegal (compile or run time, depending)
class C{var[mixin]v=4} // the compiler treats v as an int for type checking
class C{var[proxy]v=f; fcn f{println("my name is ",self.fcn.name)} }
   v acts like a property to run f so C.v is the same as C.f()
class C{reg r}         // C.r is compile time error
r:=5;  // := syntax is same as "reg r=5", convenience


program: variables
# The concept of variables is completely alien in zoea:
# there is no support for variables and no way of defining or using them.
# Instead programs are described by giving examples of input and output values.


with javascript_semantics
requires("1.0.2") -- (for in)
function vampire(atom v)
    sequence res = {}
    if v>=0 then
        string vs = sprintf("%d",v)
        if mod(length(vs),2)=0 then -- even length
            vs = sort(vs)
            for i=power(10,length(vs)/2-1) to floor(sqrt(v)) do
                if remainder(v,i)=0 then
                    integer i2 = v/i
                    string si = sprintf("%d",i),
                           s2 = sprintf("%d",i2)
                    if (si[$]!='0' or s2[$]!='0')
                    and sort(si&s2)=vs then
                        res = append(res,{i,i2})
                    end if
                end if
            end for
        end if
    end if
    return res
end function

integer found = 0
atom i = 0
sequence res
puts(1,"The first 26 vampire numbers and their fangs:\n")
while found<26 do
    res = vampire(i)
    if length(res) then
        found += 1
        printf(1,"%d: %d: %v\n",{found,i,res})
    end if
    i += 1
end while
puts(1,"\n")

for i in {16758243290880,24959017348650,14593825548650} do
    res = vampire(i)
    printf(1,"%d: %s\n",{i,iff(res={}?"not a vampire number":sprint(res))})
end for


import strformat, strutils

type Vector3 = array[1..3, float]

proc `$`(a: Vector3): string =
  result = "("
  for x in a:
    result.addSep(", ", 1)
    result.add &"{x}"
  result.add ')'

proc cross(a, b: Vector3): Vector3 =
  result = [a[2]*b[3] - a[3]*b[2], a[3]*b[1] - a[1]*b[3], a[1]*b[2] - a[2]*b[1]]

proc dot(a, b: Vector3): float =
  for i in a.low..a.high:
    result += a[i] * b[i]

proc scalarTriple(a, b, c: Vector3): float = a.dot(b.cross(c))

proc vectorTriple(a, b, c: Vector3): Vector3 = a.cross(b.cross(c))

let
  a = [3.0, 4.0, 5.0]
  b = [4.0, 3.0, 5.0]
  c = [-5.0, -12.0, -13.0]

echo &"a ⨯ b = {a.cross(b)}"
echo &"a . b = {a.dot(b)}"
echo &"a . (b ⨯ c) = {scalarTriple(a, b, c)}"
echo &"a ⨯ (b ⨯ c) = {vectorTriple(a, b, c)}"


bundle Default {
  class VectorProduct {
    function : Main(args : String[]) ~ Nil {
      a := Vector3D->New(3.0, 4.0, 5.0);
      b := Vector3D->New(4.0, 3.0, 5.0);
      c := Vector3D->New(-5.0, -12.0, -13.0);

      a->Dot(b)->Print();
      a->Cross(b)->Print();
      a->ScaleTrip(b, c)->Print();
      a->VectorTrip(b, c)->Print();
    }
  }

  class Vector3D {
    @a : Float;
    @b : Float;
    @c : Float;

    New(a : Float, b : Float, c : Float) {
      @a := a;
      @b := b;
      @c := c;
    }

    method :  GetA() ~ Float {
      return @a;
    }

    method : GetB() ~ Float {
      return @b;
    }

    method : GetC() ~ Float {
      return @c;
    }

    method : public : Dot(vec : Vector3D) ~ Float {
      return @a * vec->GetA() + @b * vec->GetB() + @c * vec->GetC();
    }

    method : public : Cross(vec : Vector3D) ~ Vector3D {
      newA := @b * vec->GetC() - @c * vec->GetB();
      newB := @c * vec->GetA() - @a * vec->GetC();
      newC := @a * vec->GetB() - @b * vec->GetA();

      return Vector3D->New(newA, newB, newC);
    }

    method : public : ScaleTrip(vec_b: Vector3D, vec_c : Vector3D) ~ Float {
      return Dot(vec_b->Cross(vec_c));
    }

    method : public : Print() ~ Nil {
      IO.Console->Print('<')->Print(@a)->Print(" ,")
        ->Print(@b)->Print(", ")->Print(@c)->PrintLine('>');
    }

    method : public : VectorTrip(vec_b: Vector3D, vec_c : Vector3D) ~ Vector3D {
      return Cross(vec_b->Cross(vec_c));
    }
  }
}


EnableExplicit
DisableDebugger

Macro CheckVamp(CheckNum)
  c=0 : i=CheckNum : Print(~"\nCheck number: "+Str(i)+~"\n")
  Gosub VampireLoop : If c=0 : Print(Str(i)+" is not vampiric.") : EndIf : PrintN("")
EndMacro

Procedure.i Factor(number.i,counter.i)
  If number>0 And number>=counter*counter And number%counter=0
      ProcedureReturn counter
  EndIf
  ProcedureReturn 0
EndProcedure

Procedure.b IsVampire(f1.i,f2.i)
  Define a.s=Str(f1*f2),
         b.s=Str(f1),
         c.s=Str(f2),
         d.s=b+c,
         i.i
  If Len(a)=Len(d) And Len(b)=Len(c)
    While Len(a)
      i=FindString(d,Left(a,1))
      If i
        a=Mid(a,2)
        d=RemoveString(d,Mid(d,i,1),#PB_String_NoCase,i,1)
      Else
        ProcedureReturn #False
      EndIf
    Wend
    ProcedureReturn Bool(Len(d)=0)
  EndIf
  ProcedureReturn #False
EndProcedure

OpenConsole("Vampire number")
Define i.i,
       j.i,
       m.i,
       c.i=0

PrintN("The first 25 Vampire numbers...")
While c<25 : i+1 : Gosub VampireLoop : Wend
PrintN("")
CheckVamp(16758243290880) : CheckVamp(24959017348650) : CheckVamp(14593825548650)
Input()
End

VampireLoop:
  For j=1 To Int(Sqr(i))
    If Factor(i,j)>0
      m=i/j
    Else
      Continue
    EndIf
    If IsVampire(m,j)
      c+1
      PrintN(RSet(Str(c),3," ")+". "+RSet(Str(i),10," ")+": ["+Str(j)+", "+Str(m)+"]")
    EndIf
  Next
Return


*        Validate ISIN             08/03/2019
VALISIN  CSECT
         USING  VALISIN,R13        base register
         B      72(R15)            skip savearea
         DC     17F'0'             savearea
         SAVE   (14,12)            save previous context
         ST     R13,4(R15)         link backward
         ST     R15,8(R13)         link forward
         LR     R13,R15            set addressability
         LA     R7,1               j=1
       DO WHILE=(C,R7,LE,=A(NN))   do j=1 to hbound(tt)
         LR     R1,R7              j
         SLA    R1,4               ~
         LA     R4,TT-16(R1)       @tt(j)
         MVC    CC,0(R4)           cc=tt(j)
         MVC    C,=CL28' '         c=' '
         MVC    R,=CL28' '         r=' '
         MVI    ERR,X'00'          err=false
         MVC    LCC,=F'0'          lcc=0
         LA     R1,L'CC            i=length(cc)
LENTRIA  LA     R5,CC-1            @cc
         AR     R5,R1              +i
         CLI    0(R5),C' '         if cc[i]=' '
         BE     LENTRIB            then iterate loop
         ST     R1,LCC             lcc=lentrim(cc)
         B      LENTRIC            leave loop
LENTRIB  BCT    R1,LENTRIA         i--; if i<>0 then loop
LENTRIC  L      R4,LCC             lcc
       IF    CH,R4,EQ,=H'12' THEN  if lcc=12 then
         MVC    LC,=F'0'           lc=0
         MVC    WW,=CL28' '        ww=''
         LA     R10,WW             @ww
         LA     R6,1               i=1
       DO WHILE=(C,R6,LE,LCC)      do i=1 to lcc
         LA     R4,CC-1            @cc
         AR     R4,R6              +i
         MVC    CI(1),0(R4)        ci=substr(cc,i,1)
         LA     R2,BASE36          @base36
         LA     R3,L'BASE36        length(base36)
         BAL    R14,INDEX          r0=index(base36,ci)
       IF   LTR,R0,NZ,R0 THEN      if p<>0 then
         LR     R1,R0                ip
         BCTR   R1,0                 -1
         XDECO  R1,XDEC              str(ip-1)
         MVC    0(2,R10),XDEC+10     ww=ww||str(p-1)
       ELSE     ,                  else
         MVI    ERR,X'FF'            err=true
       ENDIF    ,                  endif
         LA     R10,2(R10)           @ww+=2
         LA     R6,1(R6)             i++
       ENDDO    ,                  enddo i
         MVC    C,=CL28' '         c=''
         LA     R8,WW              @ww
         LA     R9,C               @c
         LA     R10,0              length(c)
         LA     R6,1               i=1
       DO WHILE=(C,R6,LE,=A(L'WW)) do i=1 to length(ww)
       IF   CLI,0(R8),NE,C' ' THEN   if ww[i]<>' ' then
         MVC    0(1,R9),0(R8)          c=ww[i]
         LA     R9,1(R9)               @c++
         LA     R10,1(R10)             length(c)++
       ENDIF    ,                    endif
         LA     R8,1(R8)             @ww++
         LA     R6,1(R6)             i++
       ENDDO    ,                  enddo i
         ST     R10,LC             lc=length(c)
         LA     R6,1               i=1
       DO WHILE=(CH,R6,LE,=H'2')   do i=1 to 2
         LA     R4,CC-1              @cc
         AR     R4,R6                +i
         MVC    CI(1),0(R4)          ci=substr(cc,i,1)
         LA     R2,ALPHA             @alpha
         LA     R3,L'ALPHA           length(alpha)
         BAL    R14,INDEX            r0=index(alpha,ci)
       IF   LTR,R0,Z,R0 THEN         if index(alpha,ci)=0 then
         MVI    ERR,X'FF'              err=true
       ENDIF    ,                    endif
         LA     R6,1(R6)             i++
       ENDDO    ,                  enddo i
         SR     R8,R8              i1=0
         SR     R9,R9              i2=0
       IF   CLI,ERR,EQ,X'00' THEN  if not err then
         SR     R0,R0              0
         L      R6,LC              i=lc
         MVC    R,=CL28' '         r=''
         LA     R10,C              @c
         LA     R11,R-1            @r
         A      R11,LC             @[email protected]+length(strip((c))
       DO WHILE=(CH,R6,GE,=H'1')    do i=lc to 1 step -1
         MVC    0(1,R11),0(R10)      r[k]=c[i]
         BCTR   R11,0                @r--
         LA     R10,1(R10)           @c++
         BCTR   R6,0                 i--
       ENDDO    ,                  enddo i
         LA     R6,1               i=1
       DO WHILE=(C,R6,LE,LC)       do i=1 to lc step 2
         LA     R4,R-1               @r
         AR     R4,R6                +i
         MVC    CI(1),0(R4)          ci=substr(r,i,1)
         MVC    XDEC,=CL12' '        ~
         MVC    XDEC(L'CI),CI        ci
         XDECI  R2,XDEC              int(ci)
         AR     R8,R2                i1=i1+int(ci)
         LA     R6,2(R6)             i+=2
       ENDDO    ,                  enddo i
         LA     R6,2               i=2
       DO WHILE=(C,R6,LE,LC)       do i=2 to lc step 2
         LA     R4,R-1               @r
         AR     R4,R6                +i
         MVC    CI(1),0(R4)          ci=substr(r,i,1)
         MVC    XDEC,=CL12' '        ~
         MVC    XDEC(L'CI),CI        ci
         XDECI  R10,XDEC             int(ci)
         SLA    R10,1                ii=int(ci)*2
       IF CH,R10,GE,=H'10' THEN       if ii>=10 then
         SH     R10,=H'9'              ii=ii-9
       ENDIF     ,                   endif
         AR     R9,R10               i2=i2+ii
         LA     R6,2(R6)             i++
       ENDDO    ,                  enddo i
         LR     R2,R8              i1
         AR     R2,R9              +i2
         XDECO  R2,XDEC               s=str(i1+i2)
       IF CLI,XDEC+11,EQ,C'0' THEN if substr(s,length(s),1)='0' then
         MVC    MSG,=CL6'OK'         msg='ok'
       ELSE     ,                  else
         MVC    MSG,=CL6'?err1'      msg='?1'
       ENDIF    ,                  endif
       ELSE     ,                  else
         MVC    MSG,=CL6'?err2'      msg='?2'
       ENDIF    ,                  endif
       ELSE     ,                  else
         MVC    MSG,=CL6'?err3'      msg='?3'
       ENDIF    ,                  endif
         XDECO  R7,XDEC            edit j
         MVC    PG(2),XDEC+10      j
         MVC    PG+3(16),CC        cc
         MVC    PG+20(6),MSG       msg
         XPRNT  PG,L'PG            print buffer
         LA     R7,1(R7)           j++
       ENDDO    ,                  enddo j
         L      R13,4(0,R13)       restore previous savearea pointer
         RETURN (14,12),RC=0       restore registers from calling sav
MVCX     MVC    0(0,R4),0(R5)      pattern svc
INDEX    SR     R0,R0              index(r2,ci) r3=len
         LA     R1,1               k=1
SINDEXA  CR     R1,R3              do k=1 to length(ca)
         BH     SINDEXC              ~
         CLC    0(1,R2),CI           if ca[k]=ci
         BNE    SINDEXB              then iterate loop
         LR     R0,R1                ii=k
         B      SINDEXC              exit loop
SINDEXB  LA     R2,1(R2)             @ca++
         LA     R1,1(R1)             k++
         B      SINDEXA            enddo
SINDEXC  BR     R14                end index
NN       EQU    (BASE36-TT)/16     number of items
TT       DC     CL16'US0378331005',CL16'US0373831005'
         DC     CL16'U50378331005',CL16'US03378331005'
         DC     CL16'AU0000XVGZA3',CL16'AU0000VXGZA3'
         DC     CL16'FR0000988040'
BASE36   DC     CL36'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
ALPHA    DC     CL26'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
ERR      DS     X                  error
LCC      DS     F                  length of cc
LC       DS     F                  length of c
CI       DS     CL1
CC       DS     CL16               current element of tt
C        DS     CL28
R        DS     CL28
WW       DS     CL28
MSG      DS     CL6                message
PG       DC     CL80' '            buffer
XDEC     DS     CL12               temp for xdeco and xdeci
         REGEQU
         END    VALISIN


procedure ISIN is
   -- Luhn_Test copied from other Task
   function Luhn_Test (Number: String) return Boolean is
      Sum  : Natural := 0;
      Odd  : Boolean := True;
      Digit: Natural range 0 .. 9;
   begin
      for p in reverse Number'Range loop
         Digit := Integer'Value (Number (p..p));
         if Odd then
            Sum := Sum + Digit;
         else
            Sum := Sum + (Digit*2 mod 10) + (Digit / 5);
         end if;
         Odd := not Odd;
      end loop;
      return (Sum mod 10) = 0;
   end Luhn_Test;

   subtype Decimal   is Character range '0' .. '9';
   subtype Letter    is Character range 'A' .. 'Z';
   subtype ISIN_Type is String(1..12);

   -- converts a string of decimals and letters into a string of decimals
   function To_Digits(S: String) return String is
      -- Character'Pos('A')-Offset=10, Character'Pos('B')-Offset=11, ...
      Offset: constant Integer := Character'Pos('A')-10;

      Invalid_Character: exception;
   begin
      if S = "" then
         return "";
      elsif S(S'First) = ' ' then -- skip blanks
         return To_Digits(S(S'First+1 .. S'Last));
      elsif S(S'First) in Decimal then
         return S(S'First) & To_Digits(S(S'First+1 .. S'Last));
      elsif S(S'First) in Letter then
         return To_Digits(Integer'Image(Character'Pos(S(S'First))-Offset))
           & To_Digits(S(S'First+1 .. S'Last));
      else
         raise Invalid_Character;
      end if;
   end To_Digits;

   function Is_Valid_ISIN(S: ISIN_Type) return Boolean is
      Number : String := To_Digits(S);
   begin
      return S(S'First)   in Letter  and
             S(S'First+1) in Letter  and
             S(S'Last)    in Decimal and
             Luhn_Test(Number);
   end Is_Valid_ISIN;

   Test_Cases : constant Array(1..6) of ISIN_Type :=
      ("US0378331005",
       "US0373831005",
       "U50378331005",
       -- excluded by type with fixed length
       -- "US03378331005",
       "AU0000XVGZA3",
       "AU0000VXGZA3",
       "FR0000988040");
begin
   for I in Test_Cases'Range loop
      Ada.Text_IO.Put_Line(Test_Cases(I) & ":" &
        Boolean'Image(Is_Valid_ISIN(Test_Cases(I))));
   end loop;
   -- using wrong length will result in an exception:
   Ada.Text_IO.Put("US03378331005:");
   Ada.Text_IO.Put_Line(Boolean'Image(Is_Valid_Isin("US03378331005")));
exception
   when others =>
      Ada.Text_IO.Put_Line("Exception occured");
end ISIN;


let a = (3.0, 4.0, 5.0)
let b = (4.0, 3.0, 5.0)
let c = (-5.0, -12.0, -13.0)

let string_of_vector (x,y,z) =
  Printf.sprintf "(%g, %g, %g)" x y z

let dot (a1, a2, a3) (b1, b2, b3) =
  (a1 *. b1) +. (a2 *. b2) +. (a3 *. b3)

let cross (a1, a2, a3) (b1, b2, b3) =
  (a2 *. b3 -. a3 *. b2,
   a3 *. b1 -. a1 *. b3,
   a1 *. b2 -. a2 *. b1)

let scalar_triple a b c =
  dot a (cross b c)

let vector_triple a b c =
  cross a (cross b c)

let () =
  Printf.printf "a: %s\n" (string_of_vector a);
  Printf.printf "b: %s\n" (string_of_vector b);
  Printf.printf "c: %s\n" (string_of_vector c);
  Printf.printf "a . b = %g\n" (dot a b);
  Printf.printf "a x b = %s\n" (string_of_vector (cross a b));
  Printf.printf "a . (b x c) = %g\n" (scalar_triple a b c);
  Printf.printf "a x (b x c) = %s\n" (string_of_vector (vector_triple a b c));
;;


a = [3, 4, 5];
b = [4, 3, 5];
c = [-5, -12, -13];

function r = s3prod(a, b, c)
  r = dot(a, cross(b, c));
endfunction

function r = v3prod(a, b, c)
  r = cross(a, cross(b, c));
endfunction

% 49
dot(a, b)
% or matrix-multiplication between row and column vectors
a * b'

% 5 5 -7
cross(a, b) % only for 3d-vectors

% 6
s3prod(a, b, c)

% -267 204 -3
v3prod(a, b, c)


from __future__ import division

import math
from operator import mul
from itertools import product
from functools import reduce

def fac(n):
    '''\
    return the prime factors for n
    >>> fac(600)
    [5, 5, 3, 2, 2, 2]
    >>> fac(1000)
    [5, 5, 5, 2, 2, 2]
    >>>
    '''
    step = lambda x: 1 + x*4 - (x//2)*2
    maxq = int(math.floor(math.sqrt(n)))
    d = 1
    q = n % 2 == 0 and 2 or 3
    while q <= maxq and n % q != 0:
        q = step(d)
        d += 1
    res = []
    if q <= maxq:
        res.extend(fac(n//q))
        res.extend(fac(q))
    else: res=[n]
    return res

def fact(n):
    '''\
    return the prime factors and their multiplicities for n
    >>> fact(600)
    [(2, 3), (3, 1), (5, 2)]
    >>> fact(1000)
    [(2, 3), (5, 3)]
    >>>
    '''
    res = fac(n)
    return [(c, res.count(c)) for c in set(res)]

def divisors(n):
    'Returns all the divisors of n'
    factors = fact(n)   # [(primefactor, multiplicity), ...]
    primes, maxpowers = zip(*factors)
    powerranges = (range(m+1) for m in maxpowers)
    powers = product(*powerranges)
    return (
        reduce(mul,
               (prime**power for prime, power in zip(primes, powergroup)),
               1)
        for powergroup in powers)

def vampire(n):
    fangsets = set( frozenset([d, n//d])
                    for d in divisors(n)
                    if (len(str(d)) == len(str(n))/2.
                        and sorted(str(d) + str(n//d)) == sorted(str(n))
                        and (str(d)[-1] == 0) + (str(n//d)[-1] == 0) <=1) )
    return sorted(tuple(sorted(fangs)) for fangs in fangsets)

if __name__ == '__main__':
    print('First 25 vampire numbers')
    count = n = 0
    while count <25:
        n += 1
        fangpairs = vampire(n)
        if fangpairs:
            count += 1
            print('%i: %r' % (n, fangpairs))
    print('\nSpecific checks for fangpairs')
    for n in (16758243290880, 24959017348650, 14593825548650):
        fangpairs = vampire(n)
        print('%i: %r' % (n, fangpairs))


begin
    % external procedure that returns true if ccNumber passes the Luhn test, false otherwise %
    logical procedure LuhnTest ( string(32) value ccNumber
                               ; integer    value ccLength
                               ) ; algol "LUHN" ;

    % returns true if isin is a valid ISIN, false otherwise    %
    logical procedure isIsin ( string(32) value isin ) ;
        if isin( 12 // 20 ) not = "" then false % code is too long %
        else begin
            % the first two characters must be upper-case letters %

            % returns the digit corresponding to a character of an ISIN %
            integer procedure isinDigit ( string(1) value iChar ) ;
                if      iChar >= "0" and iChar <= "9" then ( decode( iChar ) - decode( "0" ) )
                else if iChar >= "A" and iChar <= "Z" then ( decode( iChar ) - decode( "A" ) ) + 10
                else begin % invalid digit %
                    isValid := false;
                    -1
                end isinDigit ;

            integer d1, d2;
            logical isValid;
            isValid := true;
            d1      := isinDigit( isin( 0 // 1 ) );
            d2      := isinDigit( isin( 1 // 1 ) );
            if d1 < 10 or d1 > 35 or d2 < 10 or d2 > 35 then false % invalid first two characters %
            else begin
                % ok so far - conveet from base 36 to base 10 %
                string(24) base10Isin;
                integer    b10Pos;
                base10Isin := "";
                b10Pos     := 0;
                for cPos := 0 until 10 do begin
                    integer digit;
                    digit := isinDigit( isin( cPos // 1 ) );
                    if isValid then begin
                        % valid digit %
                        if digit > 9 then begin
                            base10Isin( b10Pos // 1 ) := code( ( digit div 10 ) + decode( "0" ) );
                            b10Pos                    := b10Pos + 1;
                        end if_digit_gt_9 ;
                        base10Isin( b10Pos // 1 )     := code( ( digit rem 10 ) + decode( "0" ) );
                        b10Pos                        := b10Pos + 1
                    end if_isValid
                end for_cPos ;
                % add the check digit as is %
                base10Isin( b10Pos // 1 ) := isin( 11 // 1 );
                isValid and LuhnTest( base10Isin, b10Pos + 1 )
            end
        end isIsin ;

    % task test cases %

    procedure testIsIsin ( string(32) value isin
                         ; logical    value expected
                         ) ;
    begin
        logical isValid;
        isValid := isIsin( isin );
        write( s_w := 0
             , isin
             , if isValid then " is valid" else " is invalid"
             , if isValid = expected   then "" else " NOT as expected ??"
             )
    end testIsin ;

    testIsIsin( "US0378331005",  true  );
    testIsIsin( "US0373831005",	 false );
    testIsIsin( "U50378331005",  false );
    testIsIsin( "US03378331005", false );
    testIsIsin( "AU0000XVGZA3",	 true  );
    testIsIsin( "AU0000VXGZA3",	 true  );
    testIsIsin( "FR0000988040",	 true  );
end.


use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"

on ISINTest(ISIN)
    -- Check that the input is both text and 12 characters long …
    if not ((ISIN's class is text) and ((count ISIN) is 12)) then return false
    -- … and that it has the required format.
    set ISIN to current application's class "NSMutableString"'s stringWithString:(ISIN)
    if ((ISIN's rangeOfString:("^[A-Z]{2}[0-9A-Z]{9}[0-9]$") options:(current application's NSRegularExpressionSearch) range:({0, ISIN's |length|()}))'s |length|() is 0) then return false
    -- Replace all letters with text representations of equivalent decimal numbers in the range 10 to 35.
    set letterCharacters to characters of "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    repeat with i from 1 to 26
        tell ISIN to replaceOccurrencesOfString:(item i of letterCharacters) withString:((i + 9) as text) options:(0) range:({0, its |length|()})
    end repeat

    -- Apply the Luhn test handler from the "Luhn test of credit card numbers" task.
    -- <https://www.rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#Straightforward>
    return luhnTest(ISIN as text)
end ISINTest

-- Test code:
set testResults to {}
repeat with ISIN in {"US0378331005", "US0373831005", "U50378331005", "US03378331005", "AU0000XVGZA3", "AU0000VXGZA3", "FR0000988040"}
    set end of testResults to {testNumber:ISIN's contents, valid:ISINTest(ISIN)}
end repeat
return testResults


# syntax: GAWK -f VALIDATE_INTERNATIONAL_SECURITIES_IDENTIFICATION_NUMBER.AWK
# converted from Fortran
BEGIN {
    for (i=0; i<=255; i++) { ord_arr[sprintf("%c",i)] = i } # build array[character]=ordinal_value
    n = split("US0378331005,US0373831005,U50378331005,US03378331005,AU0000XVGZA3,AU0000VXGZA3,FR0000988040",arr,",")
    for (i=1; i<=n; i++) {
      printf("%s %s\n",is_isin(arr[i]),arr[i])
    }
    exit(0)
}
function is_isin(arg,  i,j,k,s,v) {
    for (i=1; i<=12; i++) { # convert to an array of digits
      k = ord_arr[substr(arg,i,1)]
      if (k >= 48 && k <= 57) {
        if (i < 3) { return(0) }
        k -= 48
        s[++j] = k
      } else if (k >= 65 && k <= 90) {
        if (i == 12) { return(0) }
        k = k - 65 + 10
        s[++j] = int(k / 10)
        s[++j] = k % 10
      } else {
        return(0)
      }
    }
    for (i=j-1; i>=1; i-=2) { # compute checksum
      k = 2 * s[i]
      if (k > 9) { k -= 9 }
      v += k
    }
    for (i=j; i>=1; i-=2) {
      v += s[i]
    }
    return(v % 10 == 0)
}


a = .vector~new(3, 4, 5);
b = .vector~new(4, 3, 5);
c = .vector~new(-5, -12, -13);

say a~dot(b)
say a~cross(b)
say a~scalarTriple(b, c)
say a~vectorTriple(b, c)

::class vector
::method init
  expose x y z
  use arg x, y, z

::attribute x get
::attribute y get
::attribute z get

-- dot product operation
::method dot
  expose x y z
  use strict arg other

  return x * other~x + y * other~y + z * other~z

-- cross product operation
::method cross
  expose x y z
  use strict arg other

  newX = y * other~z - z * other~y
  newY = z * other~x - x * other~z
  newZ = x * other~y - y * other~x
  return self~class~new(newX, newY, newZ)

-- scalar triple product
::method scalarTriple
  use strict arg vectorB, vectorC
  return self~dot(vectorB~cross(vectorC))

-- vector triple product
::method vectorTriple
  use strict arg vectorB, vectorC
  return self~cross(vectorB~cross(vectorC))

::method string
  expose x y z
  return "<"||x", "y", "z">"


#lang racket

;; chock full of fun... including divisors
(require math/number-theory)

;; predicate to tell if n is a vampire number
(define (sub-vampire?-and-fangs n)
  (define digit-count-n (add1 (order-of-magnitude n)))
  (define (string-sort-characters s) (sort (string->list s) char<?))
  (define digits-in-order-n (string-sort-characters (number->string n)))
  (define (fangs-of-n? d e)
    (and (<= d e) ; avoid duplication
         (= (add1 (order-of-magnitude d)) (add1 (order-of-magnitude e)) (/ digit-count-n 2))
         (not (= 0 (modulo d 10) (modulo e 10)))
         (equal? digits-in-order-n
                 (string-sort-characters (string-append (number->string d) (number->string e))))))

  (let* ((fangses (for*/list ((d (in-list (divisors n))) #:when (fangs-of-n? d (/ n d)))
                    (list d (/ n d)))))
    (and (not (null? fangses)) (cons n fangses))))

(define (vampire?-and-fangs n)
  (and (odd? (order-of-magnitude n)) ; even number of digits - else not even worth looking!
       (sub-vampire?-and-fangs n)))

(displayln "First 25 vampire numbers:")
(for ((vmp (sequence-filter identity (sequence-map vampire?-and-fangs (in-naturals 1))))
      (cnt (in-range 1 (add1 25))))
  (printf "#~a ~a~%" cnt vmp))

(displayln "Test the big numbers:")
(displayln (vampire?-and-fangs 16758243290880))
(displayln (vampire?-and-fangs 24959017348650))
(displayln (vampire?-and-fangs 14593825548650))


sub is_vampire (Int $num) {
    my $digits = $num.comb.sort;
    my @fangs;
    (10**$num.sqrt.log(10).floor .. $num.sqrt.ceiling).map: -> $this {
        next if $num % $this;
        my $that = $num div $this;
        next if $this %% 10 && $that %% 10;
        @fangs.push("$this x $that") if ($this ~ $that).comb.sort eq $digits;
    }
    @fangs
}

constant @vampires = flat (3..*).map: -> $s, $e {
    (10**$s .. 10**$e).hyper.map: -> $n {
        next unless my @fangs = is_vampire($n);
        "$n: { @fangs.join(', ') }"
    }
}

say "\nFirst 25 Vampire Numbers:\n";

.say for @vampires[^25];

say "\nIndividual tests:\n";

.say for (16758243290880, 24959017348650, 14593825548650).hyper(:1batch).map: {
    "$_: " ~ (is_vampire($_).join(', ') || 'is not a vampire number.')
}


using System;
using System.Linq;
using System.Text.RegularExpressions;

namespace ValidateIsin
{
    public static class IsinValidator
    {
        public static bool IsValidIsin(string isin) =>
            IsinRegex.IsMatch(isin) && LuhnTest(Digitize(isin));

        private static readonly Regex IsinRegex =
            new Regex("^[A-Z]{2}[A-Z0-9]{9}\\d$", RegexOptions.Compiled);

        private static string Digitize(string isin) =>
            string.Join("", isin.Select(c => $"{DigitValue(c)}"));

        private static bool LuhnTest(string number) =>
            number.Reverse().Select(DigitValue).Select(Summand).Sum() % 10 == 0;

        private static int Summand(int digit, int i) =>
            digit + (i % 2) * (digit - digit / 5 * 9);

        private static int DigitValue(char c) =>
            c >= '0' && c <= '9'
                ? c - '0'
                : c - 'A' + 10;
   }

   public class Program
   {
        public static void Main()
        {
            string[] isins =
            {
                "US0378331005",
                "US0373831005",
                "U50378331005",
                "US03378331005",
                "AU0000XVGZA3",
                "AU0000VXGZA3",
                "FR0000988040"
            };

            foreach (string isin in isins) {
                string validOrNot = IsinValidator.IsValidIsin(isin) ? "valid" : "not valid";
                Console.WriteLine($"{isin} is {validOrNot}");
            }
        }
    }
}


Program VectorProduct (output);

type
  Tvector = record
    x, y, z: double
  end;

function dotProduct(a, b: Tvector): double;
begin
  dotProduct := a.x*b.x + a.y*b.y + a.z*b.z;
end;

function crossProduct(a, b: Tvector): Tvector;
begin
  crossProduct.x := a.y*b.z - a.z*b.y;
  crossProduct.y := a.z*b.x - a.x*b.z;
  crossProduct.z := a.x*b.y - a.y*b.x;
end;

function scalarTripleProduct(a, b, c: Tvector): double;
begin
  scalarTripleProduct := dotProduct(a, crossProduct(b, c));
end;

function vectorTripleProduct(a, b, c: Tvector): Tvector;
begin
  vectorTripleProduct := crossProduct(a, crossProduct(b, c));
end;

procedure printVector(a: Tvector);
begin
  writeln(a.x:15:8, a.y:15:8, a.z:15:8);
end;

var
  a: Tvector = (x: 3; y:  4; z:  5);
  b: Tvector = (x: 4; y:  3; z:  5);
  c: Tvector = (x:-5; y:-12; z:-13);

begin
  write('a: '); printVector(a);
  write('b: '); printVector(b);
  write('c: '); printVector(c);
  writeln('a . b: ', dotProduct(a,b):15:8);
  write('a x b: '); printVector(crossProduct(a,b));
  writeln('a . (b x c): ', scalarTripleProduct(a,b,c):15:8);
  write('a x (b x c): '); printVector(vectorTripleProduct(a,b,c));
end.


/*REXX program displays  N  vampire numbers,  or  verifies  if  a number is vampiric.   */
parse arg N .                                    /*obtain optional argument from the CL.*/
if N=='' | N==","  then N= 25                    /*Not specified?  Then use the default.*/
!.0= 1260;   !.1= 11453481;   !.2= 115672;   !.3= 124483;   !.4= 105264  /*lowest #, dig*/
!.5= 1395;   !.6=   126846;   !.7=   1827;   !.8= 110758;   !.9= 156289  /*   "   "   " */
L= length(N);                aN= abs(N)          /*L:  length of N;  aN:  absolute value*/
numeric digits max(9, length(aN) )               /*be able to handle ginormus numbers.  */
# = 0                                            /*#:  count of vampire numbers (so far)*/
if N>0 then do j=1260  until  # >= N             /*search until N vampire numbers found.*/
            if length(j) // 2  then do;  j= j*10 - 1;  iterate   /*bump J to even length*/
                                    end                          /* [↑]  check if odd.  */
            parse var  j  ''  -1  _              /*obtain the last decimal digit of  J. */
            if j<!._  then iterate               /*is number tenable based on last dig? */
            f= vampire(j)                        /*obtain the  fangs  of  J.            */
            if f==''  then iterate               /*Are fangs null?   Yes, not vampire.  */
            #= # + 1                             /*bump the vampire count, Vlad.        */
            say right('vampire number', 20)  right(#, L)  "is: "  right(j, 9)',  fangs=' f
            end   /*j*/                          /* [↑]  process a range of numbers.    */
       else do;  f= vampire(aN)                  /* [↓]  process a number; obtain fangs.*/
                 if f==''  then say       aN      " isn't a vampire number."
                           else say       aN      " is a vampire number, fangs="     f
            end
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
vampire: procedure; parse arg x,, $. a bot;   L= length(x)  /*get arg;  compute len of X*/
         if L//2  then return ''                            /*is L odd?   Then ¬vampire.*/
                          do k=1  for L;    _= substr(x, k, 1);         $._= $._  ||  _
                          end   /*k*/
         w= L % 2                                           /*%:   is REXX's integer  ÷ */
                          do m=0  for 10;   bot= bot || $.m
                          end   /*m*/
         top= left( reverse(bot), w)
         bot= left(bot, w)                                  /*determine limits of search*/
         inc= x // 2    +    1                              /*X is odd? INC=2. No? INC=1*/
         beg= max(bot, 10 ** (w-1)  )                       /*calculate where  to begin.*/
         if inc==2  then  if  beg//2==0   then beg= beg + 1 /*possibly adjust the begin.*/
                                                            /* [↑]  odd  BEG  if odd INC*/
                  do d=beg  to  min(top, 10**w - 1)  by inc /*use smart  BEG, END, INC. */
                  if x // d \==0          then iterate      /*X  not ÷ by D?  Then skip,*/
                  q= x % d;     if d>q    then iterate      /*is   D > Q        "    "  */
                  if length(q) \== w      then iterate      /*Len of Q ¬= W?  Then skip.*/
                  if q*d//9 \== (q+d)//9  then iterate      /*modulo 9 congruence test. */
                  parse var  q  ''  -1  _                   /*get last decimal dig. of Q*/
                  if _== 0                then if right(d, 1) == 0  then iterate
                  dq= d  ||  q
                  t= x;             do i=1  for  L;           p= pos( substr(dq, i, 1), t)
                                    if p==0  then iterate d;  t= delstr(t, p, 1)
                                    end   /*i*/
                  a= a  '['d"∙"q'] '                        /*construct formatted fangs.*/
                  end   /*d*/                               /* [↑]  ∙  is a round bullet*/
         return a                                           /*return    formatted fangs.*/


#include <string>
#include <regex>
#include <algorithm>
#include <numeric>
#include <sstream>

bool CheckFormat(const std::string& isin)
{
	std::regex isinRegEpx(R"([A-Z]{2}[A-Z0-9]{9}[0-9])");
	std::smatch match;
	return std::regex_match(isin, match, isinRegEpx);
}

std::string CodeISIN(const std::string& isin)
{
	std::string coded;
	int offset = 'A' - 10;
	for (auto ch : isin)
	{
		if (ch >= 'A' && ch <= 'Z')
		{
			std::stringstream ss;
			ss << static_cast<int>(ch) - offset;
			coded += ss.str();
		}
		else
		{
			coded.push_back(ch);
		}
	}

	return std::move(coded);
}

bool CkeckISIN(const std::string& isin)
{
	if (!CheckFormat(isin))
		return false;

	std::string coded = CodeISIN(isin);
// from http://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#C.2B.2B11
	return luhn(coded);
}

#include <iomanip>
#include <iostream>

int main()
{
	std::string isins[] = { "US0378331005", "US0373831005", "U50378331005",
							"US03378331005", "AU0000XVGZA3", "AU0000VXGZA3",
							"FR0000988040" };
	for (const auto& isin : isins)
	{
		std::cout << isin << std::boolalpha << " - " << CkeckISIN(isin) <<std::endl;
	}
	return 0;
}


Class Utils.Check [ Abstract ]
{

ClassMethod ISIN(x As %String) As %Boolean
{
	// https://en.wikipedia.org/wiki/International_Securities_Identification_Number
	IF x'?2U9UN1N QUIT 0
	SET cd=$EXTRACT(x,*), x=$EXTRACT(x,1,*-1)
	FOR i=1:1 {
		SET n=$EXTRACT(x,i) IF n="" QUIT
		IF n'=+n SET $EXTRACT(x,i)=$CASE(n,"*":36,"@":37,"#":38,:$ASCII(n)-55)
	}
	// call into luhn check, appending check digit
	QUIT ..Luhn(x_cd)
}

ClassMethod Luhn(x As %String) As %Boolean
{
	// https://www.simple-talk.com/sql/t-sql-programming/calculating-and-verifying-check-digits-in-t-sql/
	SET x=$TRANSLATE(x," "), cd=$EXTRACT(x,*)
	SET x=$REVERSE($EXTRACT(x,1,*-1)), t=0
	FOR i=1:1:$LENGTH(x) {
		SET n=$EXTRACT(x,i)
		IF i#2 SET n=n*2 IF $LENGTH(n)>1 SET n=$EXTRACT(n,1)+$EXTRACT(n,2)
		SET t=t+n
	}
	QUIT cd=((t*9)#10)
}

}


# Project : Vampire number

for p = 10 to 127000
     vampire(p)
next

func vampire(listnum)
        sum = 0
        flag = 1
        list = list(len(string(listnum)))
        total = newlist(len(list),2)
       for n = 1 to len(string(listnum))
            liststr = string(listnum)
            list[n] = liststr[n]
       next

       for perm = 1 to fact(len(list))
            numstr = substr(list2str(list), nl, "")
            num1 = number(left(numstr,len(numstr)/2))
            num2 = number(right(numstr,len(numstr)/2))
            if (listnum = num1 * num2)
                for n = 1 to len(total)
                     if (num1 = total[n][2] and num2 = total[n][1]) or
                         (num1 = total[n][1] and num2 = total[n][2])
                         flag = 0
                     ok
               next
               if flag = 1
                   sum = sum + 1
                   total[sum][1] = num1
                   total[sum][2] = num2
                   see "" + listnum + ": [" + num1 + "," + num2 + "]" + nl
                ok
             ok
            nextPermutation(list)
       next

func nextPermutation(a)
     elementcount = len(a)
     if elementcount < 1 then return ok
     pos = elementcount-1
     while a[pos] >= a[pos+1]
           pos -= 1
           if pos <= 0 permutationReverse(a, 1, elementcount)
              return ok
     end
     last = elementcount
     while a[last] <= a[pos]
           last -= 1
     end
     temp = a[pos]
     a[pos] = a[last]
     a[last] = temp
     permutationReverse(a, pos+1, elementcount)

 func permutationReverse a, first, last
      while first < last
            temp = a[first]
            a[first] = a[last]
            a[last] = temp
            first += 1
            last -= 1
      end

func fact(nr)
        if nr = 1
           return 1
        else
           return nr * fact(nr-1)
        ok

func newlist(x,y)
        if isstring(x) x=0+x ok
        if isstring(y) y=0+y ok
        alist = list(x)
        for t in alist
              t = list(y)
        next
        return alist


def factor_pairs n
  first = n / (10 ** (n.to_s.size / 2) - 1)
  (first .. n ** 0.5).map { |i| [i, n / i] if n % i == 0 }.compact
end

def vampire_factors n
  return [] if n.to_s.size.odd?
  half = n.to_s.size / 2
  factor_pairs(n).select do |a, b|
    a.to_s.size == half && b.to_s.size == half &&
    [a, b].count {|x| x%10 == 0} != 2          &&
    "#{a}#{b}".chars.sort == n.to_s.chars.sort
  end
end

i = vamps = 0
until vamps == 25
  vf = vampire_factors(i += 1)
  unless vf.empty?
    puts "#{i}:\t#{vf}"
    vamps += 1
  end
end

[16758243290880, 24959017348650, 14593825548650].each do |n|
  if (vf = vampire_factors n).empty?
    puts "#{n} is not a vampire number!"
  else
    puts "#{n}:\t#{vf}"
  end
end


(defn luhn? [cc]
  (let [sum (->> cc
                 (map #(Character/digit ^char % 10))
                 reverse
                 (map * (cycle [1 2]))
                 (map #(+ (quot % 10) (mod % 10)))
                 (reduce +))]
    (zero? (mod sum 10))))

(defn is-valid-isin? [isin]
  (and (re-matches #"^[A-Z]{2}[A-Z0-9]{9}[0-9]$" isin)
       (->> isin
            (map #(Character/digit ^char % 36))
            (apply str)
            luhn?)))

(use 'clojure.pprint)
(doseq [isin ["US0378331005" "US0373831005" "U50378331005" "US03378331005"
              "AU0000XVGZA3" "AU0000VXGZA3" "FR0000988040"]]
  (cl-format *out* "~A: ~:[invalid~;valid~]~%" isin (is-valid-isin? isin)))


        >>SOURCE FORMAT FREE
*>   this is gnucobol 2.0
identification division.
program-id. callISINtest.
data division.
working-storage section.
01  ISINtest-result binary-int.
procedure division.
start-callISINtest.
    display 'should be valid ' with no advancing
    call 'ISINtest' using 'US0378331005' ISINtest-result
    perform display-ISINtest-result
    display 'should not be valid ' with no advancing
    call 'ISINtest' using 'US0373831005' ISINtest-result
    perform display-ISINtest-result
    display 'should not be valid ' with no advancing
    call 'ISINtest' using 'U50378331005' ISINtest-result
    perform display-ISINtest-result
    display 'should not be valid ' with no advancing
    call 'ISINtest' using 'US03378331005' ISINtest-result
    perform display-ISINtest-result
    display 'should be valid ' with no advancing
    call 'ISINtest' using 'AU0000XVGZA3' ISINtest-result
    perform display-ISINtest-result
    display 'should be valid ' with no advancing
    call 'ISINtest' using 'AU0000VXGZA3' ISINtest-result
    perform display-ISINtest-result
    display 'should be valid ' with no advancing
    call 'ISINtest' using 'FR0000988040' ISINtest-result
    perform display-ISINtest-result
    stop run
    .
display-ISINtest-result.
    evaluate ISINtest-result
    when 0
        display ' is valid'
    when -1
        display ' invalid length '
    when -2
        display ' invalid countrycode '
    when -3
        display ' invalid base36 digit '
    when -4
        display ' luhn test failed'
    when other
        display ' invalid return code ' ISINtest-result
    end-evaluate
    .
end program callISINtest.

identification division.
program-id. ISINtest.
data division.
working-storage section.
01  country-code-values value
    'ADAEAFAGAIALAMAOAQARASATAUAWAXAZBABBBDBEBFBGBHBIBJBLBMBNBOBQBRBS'
&   'BTBVBWBYBZCACCCDCFCGCHCICKCLCMCNCOCRCUCVCWCXCYCZDEDJDKDMDODZECEE'
&   'EGEHERESETFIFJFKFMFOFRGAGBGDGEGFGGGHGIGLGMGNGPGQGRGSGTGUGWGYHKHM'
&   'HNHRHTHUIDIEILIMINIOIQIRISITJEJMJOJPKEKGKHKIKMKNKPKRKWKYKZLALBLC'
&   'LILKLRLSLTLULVLYMAMCMDMEMFMGMHMKMLMMMNMOMPMQMRMSMTMUMVMWMXMYMZNA'
&   'NCNENFNGNINLNONPNRNUNZOMPAPEPFPGPHPKPLPMPNPRPSPTPWPYQARERORSRURW'
&   'SASBSCSDSESGSHSISJSKSLSMSNSOSRSSSTSVSXSYSZTCTDTFTGTHTJTKTLTMTNTO'
&   'TRTTTVTWTZUAUGUMUSUYUZVAVCVEVGVIVNVUWFWSYEYTZAZMZW'.
    03  country-codes occurs 249
        ascending key country-code
        indexed by cc-idx.
        05  country-code pic xx.

01  b pic 99.
01  base36-digits pic x(36) value
    '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'.

01  i pic 99.
01  p pic 99.
01  luhn-number pic x(20).
01  luhntest-result binary-int.

linkage section.
01  test-number any length.
01  ISINtest-result binary-int.

procedure division using test-number ISINtest-result.
start-ISINtest.
    display space test-number with no advancing

    *> format test
    if function length(test-number) <> 12
        move -1 to ISINtest-result
        goback
    end-if

    *> countrycode test
    search all country-codes
    at end
        move -2 to ISINtest-result
        goback
    when test-number(1:2) = country-code(cc-idx)
        continue
    end-search

    *> convert each character from base 36 to base 10
    *> and add to the luhn-number
    move 0 to p
    perform varying i from 1 by 1 until i > 12
        if test-number(i:1) >= '0' and <= '9'
            move test-number(i:1) to luhn-number(p + 1:1)
            add 1 to p
        else
            perform varying b from 9 by 1 until b > 35
            or base36-digits(b + 1:1) = test-number(i:1)
                continue
            end-perform
            if b > 35
                 move -3 to ISINtest-result
                 goback
            end-if
            move b to luhn-number(p + 1:2)
            add 2 to p
        end-if
    end-perform

    call 'luhntest' using luhn-number(1:p) luhntest-result
    if luhntest-result <> 0
        move -4 to ISINtest-result
        goback
    end-if

    move 0 to ISINtest-result
    goback
    .
end program ISINtest.

identification division.
program-id. luhntest.
data division.
working-storage section.
01  i pic S99.
01  check-sum pic 999.
linkage section.
01  test-number any length.
01  luhntest-result binary-int.
procedure division using test-number luhntest-result.
start-luhntest.
    display space test-number with no advancing
    move 0 to check-sum

    *> right to left sum the odd numbered digits
    compute i = function length(test-number)
    perform varying i from i by -2 until i < 1
        add function numval(test-number(i:1)) to check-sum
    end-perform
    display space check-sum with no advancing

    *> right to left double sum the even numbered digits
    compute i = function length(test-number) - 1
    perform varying i from i by -2 until i < 1
        add function numval(test-number(i:1)) to check-sum
        add function numval(test-number(i:1)) to check-sum
        *> convert a two-digit double sum number to a single digit
        if test-number(i:1) >= '5'
            subtract 9 from check-sum
        end-if
    end-perform
    display space check-sum with no advancing

    if function mod(check-sum,10) = 0
        move 0 to luhntest-result *> success
    else
        move -1 to luhntest-result *> failure
    end-if
    goback
    .
end program luhntest.


function dot_product(sequence a, b)
    return sum(sq_mul(a,b))
end function

function cross_product(sequence a, b)
integer {a1,a2,a3} = a, {b1,b2,b3} = b
    return {a2*b3-a3*b2, a3*b1-a1*b3, a1*b2-a2*b1}
end function

function scalar_triple_product(sequence a, b, c)
    return dot_product(a,cross_product(b,c))
end function

function vector_triple_product(sequence a, b, c)
    return cross_product(a,cross_product(b,c))
end function

constant a = {3, 4, 5}, b = {4, 3, 5}, c = {-5, -12, -13}

printf(1,"      a . b = %v\n",{dot_product(a,b)})
printf(1,"      a x b = %v\n",{cross_product(a,b)})
printf(1,"a . (b x c) = %v\n",{scalar_triple_product(a,b,c)})
printf(1,"a x (b x c) = %v\n",{vector_triple_product(a,b,c)})


use std::cmp::{max, min};

static TENS: [u64; 20] = [
    1,
    10,
    100,
    1000,
    10000,
    100000,
    1000000,
    10000000,
    100000000,
    1000000000,
    10000000000,
    100000000000,
    1000000000000,
    10000000000000,
    100000000000000,
    1000000000000000,
    10000000000000000,
    100000000000000000,
    1000000000000000000,
    10000000000000000000,
];

/// Get the number of digits present in x
fn ndigits(mut x: u64) -> u64 {
    let mut n = 0;

    while x != 0 {
        n += 1;
        x /= 10;
    }

    n
}

fn dtally(mut x: u64) -> u64 {
    let mut t = 0;

    while x != 0 {
        t += 1 << ((x % 10) * 6);
        x /= 10;
    }

    t
}

/// Get a list of all fangs of x. Get only the first divider of each fang. The second one can be found simply with x / fang.
fn fangs(x: u64) -> Vec<u64> {
    let mut nd = ndigits(x) as usize;

    let mut fangs = vec![];

    if nd & 1 != 1 {
        nd /= 2;

        let lo = max(TENS[nd - 1], (x + TENS[nd] - 2) / (TENS[nd] - 1));
        let hi = min(x / lo, (x as f64).sqrt() as u64);

        let t = dtally(x);

        for a in lo..(hi + 1) {
            let b = x / a;
            if a * b == x && ((a % 10) > 0 || b % 10 > 0) && t == dtally(a) + dtally(b) {
                fangs.push(a);
            }
        }
    }

    fangs
}

/// Pretty print the fangs of x
fn print_fangs(x: u64, fangs: Vec<u64>) {
    print!("{} = ", x);

    if fangs.is_empty() {
        print!("is not vampiric");
    } else {
        for fang in fangs {
            print!("{} x {}, ", fang, x / fang);
        }
    }
    print!("\n");
}

fn main() {
    println!("The first 25 vampire numbers are :");

    let mut nfangs = 0;
    let mut x = 1;

    while nfangs < 25 {
        let fangs = fangs(x);
        if !fangs.is_empty() {
            nfangs += 1;
            print_fangs(x, fangs);
        }

        x += 1;
    }

    println!("\nSpecial requests :");

    print_fangs(16758243290880, fangs(16758243290880));
    print_fangs(24959017348650, fangs(24959017348650));
    print_fangs(14593825548650, fangs(14593825548650));
}

#[test]
fn test() {
    assert_eq!(
        fangs(16758243290880),
        vec![1982736, 2123856, 2751840, 2817360]
    );

    assert_eq!(
        fangs(24959017348650),
        vec![2947050, 2949705, 4125870, 4129587, 4230765]
    );

    assert_eq!(fangs(14593825548650), vec![]);
}


import Stream._
import math._
import scala.collection.mutable.ListBuffer

object VampireNumbers extends App {
  val elapsed: (=> Unit) => Long = f => {val s = System.currentTimeMillis; f; (System.currentTimeMillis - s)/1000}

  val sexp = from(1, 2)   // stream of integer: 1,3,5,7, ...
  val rs: Stream[Int] => Stream[Pair[Long,Long]] = exps => Pair(pow(10,exps.head).toLong,(pow(10,exps.head)*10-1).toLong)#::rs(exps.tail)
  val srs = rs(sexp)   // stream of ranges: [10..99], [1000..9999], [100000..999999], ...
  val cs: Stream[Pair[Long,Long]] => Stream[Long] = rs => (rs.head._1 to rs.head._2).toStream#:::cs(rs.tail)
  val scs = cs(srs)   // stream of candidates: 10,11,..,99,1000,1001,..,9999, ...
  val it = scs.iterator

  val checkVN: Long => Pair[Long,Seq[Pair[Long,Long]]] = n => {
    val check: Pair[Long,Long] => Pair[Long,Long] = p => {
      val len: Long => Int = n => n.toString.size
      val (a,b) = p
      if ((a%10==0)&&(b%10==0)) Pair(0,0) else
      if (len(a) != len(b)) Pair(0,0) else
      if (n.toString.toList.diff(a.toString.toList++b.toString.toList)!=Nil) Pair(0,0) else p
    }
    Pair(n,(pow(10,log10(sqrt(n).toLong).toLong).toLong+1 to sqrt(n).toLong).filter{i=>n%i==0}
     .map {fac =>Pair(fac,n/fac)}.map {p => check(p)}.filter {p => p._1 != 0})
  }

  val et = elapsed {
    val lb = new ListBuffer[Pair[Long,Seq[Pair[Long,Long]]]]
    while ((lb.size<25)&&(it.hasNext)) {
      checkVN(it.next) match {
        case (n, Seq()) =>
        case p          => lb += p
      }
    }

    lb.toList.zipWithIndex.foreach {p =>
      println(p._2+1+": "+p._1._1+(p._1._2:\"")((x,y)=>" = "+x._1+" x "+x._2+y))
    }
    println

    List(16758243290880L, 24959017348650L, 14593825548650L)
      .map {checkVN(_)}
      .foreach {
         case (n, Seq()) => println(n+" is not vampiric")
         case p => println(p._1+(p._2:\"")((x,y)=>" = "+x._1+" x "+x._2+y))
       }
  }

  println("\n"+"elapsed time: "+et+" seconds")
}


(defun alphap (char)
  (char<= #\A char #\Z))

(defun alpha-digit-char-p (char)
  (or (alphap char) (digit-char-p char)))

(defun valid-isin-format-p (isin)
  (and (= (length isin) 12)
       (alphap (char isin 0))
       (alphap (char isin 1))
       (loop for i from 2 to 10
             always (alpha-digit-char-p (char isin i)))
       (digit-char-p (char isin 11))))

(defun isin->digits (isin)
  (apply #'concatenate 'string
         (loop for c across isin
               collect (princ-to-string (digit-char-p c 36)))))

(defun luhn-test (string)
  (loop for c across (reverse string)
        for oddp = t then (not oddp)
        if oddp
          sum (digit-char-p c) into result
        else
          sum (let ((n (* 2 (digit-char-p c))))
                (if (> n 9) (- n 9) n))
            into result
        finally (return (zerop (mod result 10)))))

(defun valid-isin-p (isin)
  (and (valid-isin-format-p isin)
       (luhn-test (isin->digits isin))))

(defun test ()
  (dolist (isin '("US0378331005" "US0373831005" "U50378331005" "US03378331005"
                  "AU0000XVGZA3" "AU0000VXGZA3" "FR0000988040"))
    (format t "~A: ~:[invalid~;valid~]~%" isin (valid-isin-p isin))))