# Casting out Nines
#
# Nigel Galloway: June 27th., 2012,
#
def CastOut(Base=10, Start=1, End=999999):
  ran = [y for y in range(Base-1) if y%(Base-1) == (y*y)%(Base-1)]
  x,y = divmod(Start, Base-1)
  while True:
    for n in ran:
      k = (Base-1)*x + n
      if k < Start:
        continue
      if k > End:
        return
      yield k
    x += 1

for V in CastOut(Base=16,Start=1,End=255):
  print(V, end=' ')


  [ true unrot swap
    witheach
      [ over find
        over found not if
          [ dip not
            conclude ] ]
    drop ]                is subset ( [ [ --> [ )

  [ abs 0 swap
    [ 10 /mod rot +
      dup 8 > if [ 9 - ]
      swap dup 0 = until ]
   drop ]                  is co9   ( n --> n   )

  say "Part 1: Examples from Dr Math page." cr cr
  say "6395 1259 + = " 6395 1259 + echo cr
  say "6395 co9    = " 6395 co9    echo cr
  say "1259 co9    = " 1259 co9    echo cr
  say "5 8 + co9   = " 5 8 + co9   echo cr
  say "7654 co9    = " 7654 co9    echo cr cr

  say "6395 1259 * = " 6395 1259 * echo cr
  say "6395 co9    = " 6395 co9    echo cr
  say "1259 co9    = " 1259 co9    echo cr
  say "5 8 * co9   = " 5 8 * co9   echo cr
  say "8051305 co9 = " 7654 co9    echo cr cr

  say "Part 2: Kaprekar numbers." cr cr

  say "Kaprekar numbers less than one hundred:    "
  []
  100 times
    [ i^ kaprekar if
      [ i^ join ] ]
  dup echo cr
  say '0...99 with property "n co9 n 2 ** co9 =": '
  []
  100 times
    [ i^ co9
      i^ 2 ** co9 = if
        [ i^ join ] ]
  dup echo cr
  say "Is the former a subset of the latter? "
  subset iff [ say "Yes." ] else [ say "No." ] cr cr

  say "Part 3: Same as Part 2, but base 17." cr cr

  say "Kaprekar (base 17) numbers less than one hundred: "
  17 base put
  []
  100 times
    [ i^ kaprekar if
      [ i^ join ] ]
  base release
  dup echo cr
  say '0...99 with property "n 16 mod n 2 ** 16 mod =":  '
  []
  100 times
    [ i^ 16 mod
      i^ 2 ** 16 mod = if
        [ i^ join ] ]
  dup echo cr
  say "Is the former a subset of the latter? "
  subset iff [ say "Yes." ] else [ say "No." ]


#lang racket
(require math)

(define (digits n)
  (map (compose1 string->number string)
       (string->list (number->string n))))

(define (cast-out-nines n)
  (with-modulus 9
    (for/fold ([sum 0]) ([d (digits n)])
      (mod+ sum d))))


PROC Main()
  CHAR ARRAY dog="Bernie"

  PrintF("There is just one dog named %S.",dog)
RETURN


with Ada.Text_IO;
procedure Dogs is
   Dog : String := "Bernie";
begin
   Ada.Text_IO.Put_Line ("There is just one dog named " & DOG);
end Dogs;


scope
    local dog := "Benjamin";
    scope
        local Dog := "Samba";
        scope
            local DOG := "Bernie";
            if DOG <> Dog or DOG <> dog
            then print( "The three dogs are named: " & dog & ", " & Dog & " and " & DOG )
            else print( "There is just one dog named: " & DOG )
            fi
        epocs
    epocs
epocs


text dog, Dog, DOG;

dog = "Benjamin";
Dog = "Samba";
DOG = "Bernie";

o_form("The three dogs are named ~, ~ and ~.\n", dog, Dog, DOG);


#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #

STRING dog = "Benjamin";
OP D = (INT og)STRING: "Samba";
OP DOG = (INT gy)STRING: "Bernie";
INT og=~, gy=~;

main:(
  printf(($"The three dogs are named "g", "g" and "g"."l$, dog, Dog, DOGgy));
  0
)


chaosGame := proc(numPoints)
	local points, i;
	randomize();
	use geometry in
	RegularPolygon(triSideways, 3, point(cent, [0, 0]), 1);
	rotation(tri, triSideways, Pi/2, counterclockwise);
	randpoint(currentP, -1/2*sqrt(3)..1/2*sqrt(3), -1/2..1/2);
	points := [coordinates(currentP)];
	for i to numPoints do
		midpoint(mid, currentP, parse(cat("rotate_triSideways_", rand(1..3)(), "_tri")));
		points := [op(points), coordinates(mid)];
		point(currentP, coordinates(mid));
	end do:
	end use;
	use plottools in
		plots:-display( seq([plots:-display([seq(point(points[i]), i = 1..j)])], j = 1..numelems(points) ), insequence=true);
	end use;
end proc:


import random

import rapid/gfx

var
  window = initRWindow()
    .title("Rosetta Code - Chaos Game")
    .open()
  surface = window.openGfx()
  sierpinski = window.newRCanvas()
  points: array[3, Vec2[float]]

for i in 0..<3:
  points[i] = vec2(cos(PI * 2 / 3 * i.float), sin(PI * 2 / 3 * i.float)) * 300

var point = vec2(rand(0.0..surface.width), rand(0.0..surface.height))

surface.vsync = false
surface.loop:
  draw ctx, step:
    let vertex = sample(points)
    point = (point + vertex) / 2
    ctx.renderTo(sierpinski):
      ctx.transform():
        ctx.translate(surface.width / 2, surface.height / 2)
        ctx.rotate(-PI / 2)
        ctx.begin()
        ctx.point((point.x, point.y))
        ctx.draw(prPoints)
    ctx.clear(gray(0))
    ctx.begin()
    ctx.texture = sierpinski
    ctx.rect(0, 0, surface.width, surface.height)
    ctx.draw()
    ctx.noTexture()
  update step:
    discard


sub cast-out(\BASE = 10, \MIN = 1, \MAX = BASE**2 - 1) {
  my \B9 = BASE - 1;
  my @ran = ($_ if $_ % B9 == $_**2 % B9 for ^B9);
  my $x = MIN div B9;
  gather loop {
    for @ran -> \n {
      my \k = B9 * $x + n;
      take k if k >= MIN;
    }
    $x++;
  } ...^ * > MAX;
}

say cast-out;
say cast-out 16;
say cast-out 17;


/*REXX program demonstrates the  casting─out─nines  algorithm  (with Kaprekar numbers). */
parse arg LO HI base .                           /*obtain optional arguments from the CL*/
if LO=='' | LO==","  then do; LO=1; HI=1000; end /*Not specified?   Then use the default*/
if HI=='' | HI==","  then HI= LO                 /* "      "          "   "   "     "   */
if base=='' | base==","  then base= 10           /* "      "          "   "   "     "   */
numeric digits max(9, 2*length(HI**2) )          /*insure enough decimal digits for HI².*/
numbers= castOut(LO, HI, base)                   /*generate a list of (cast out) numbers*/
@cast_out= 'cast-out-'  || (base-1)     "test"   /*construct a shortcut text for output.*/
say 'For'     LO     "through"     HI', the following passed the'       @cast_out":"
say numbers;         say                         /*display the list of cast out numbers.*/
q= HI - LO + 1                                   /*Q:   is the range of numbers in list.*/
p= words(numbers)                                /*P"    "  " number  "    "     "   "  */
pc= format(p/q * 100, , 2) / 1  ||  '%'          /*calculate the percentage (%) cast out*/
say 'For'   q   "numbers,"   p   'passed the'    @cast_out    "("pc') for base'    base"."
if base\==10  then exit                          /*if radix isn't ten, then exit program*/
Kaps= Kaprekar(LO, HI)                           /*generate a list of Kaprekar numbers. */
say;  say   'The Kaprekar numbers in the same range are:'   Kaps
say
      do i=1  for words(Kaps);    x= word(Kaps, i)                 /*verify 'em in list.*/
      if wordpos(x, numbers)\==0  then iterate                     /*it's OK so far ··· */
      say 'Kaprekar number'   x   "isn't in the numbers list."     /*oops─ay!           */
      exit 13                                                      /*go spank the coder.*/
      end   /*i*/

say 'All Kaprekar numbers are in the'     @cast_out     "numbers list."             /*OK*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
castOut:  procedure;  parse arg low,high,radix;       rm= word(radix 10, 1) - 1;        $=
                          do j=low  to  word(high low, 1)    /*test a range of numbers. */
                          if j//rm == j*j//rm  then $= $ j   /*did number pass the test?*/
                          end   /*j*/                        /* [↑]  Then add # to list.*/
          return strip($)                        /*strip and leading blanks from result.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
Kaprekar: procedure;  parse arg L,H;   $=;   if L<=1  then $= 1  /*add unity if in range*/
            do j=max(2, L)  to H;        s= j*j  /*a slow way to find Kaprekar numbers. */
               do m=1  for length(s)%2
               if j==left(s, m) + substr(s, m+1)  then do;  $= $ j;   leave;    end
               end   /*m*/                       /*     [↑]  found a Kaprekar number.   */
            end       /*j*/
          return strip($)                        /*return Kaprekar numbers to invoker.  */


begin
    string(8) dog;
    dog := "Benjamin";
    begin
        string(8) Dog;
        Dog := "Samba";
        begin
            string(8) DOG;
            DOG := "Bernie";
            if DOG not = Dog
            or DOG not = dog
            then write( "The three dogs are named: ", dog, ", ", Dog, " and ", DOG )
            else write( "There is just one dog named: ", DOG )
        end
    end
end.


      DOG←'Benjamin'
      Dog←'Samba'
      dog←'Bernie'
      'The three dogs are named ',DOG,', ',Dog,', and ',dog
The three dogs are named Benjamin, Samba, and Bernie


dog: "Benjamin"
Dog: "Samba"
DOG: "Bernie"

dogs: @[dog Dog DOG]

print ["The" size dogs "dog(s) are named" join.with:", " dogs]


dog := "Benjamin"
Dog := "Samba"
DOG := "Bernie"
MsgBox There is just one dog named %dOG%


BEGIN {
	dog = "Benjamin"
	Dog = "Samba"
	DOG = "Bernie"
	printf "The three dogs are named %s, %s and %s.\n", dog, Dog, DOG
}


\\ Chaos Game  (Sierpinski triangle) 2/15/17 aev
pChaosGameS3(size,lim)={
my(sz1=size\2,sz2=sz1*sqrt(3),M=matrix(size,size),x,y,xf,yf,v);
x=random(size); y=random(sz2);
for(i=1,lim, v=random(3);
  if(v==0, x/=2; y/=2;);
  if(v==1, x=sz1+(sz1-x)/2; y=sz2-(sz2-y)/2;);
  if(v==2, x=size-(size-x)/2; y/=2;);
  xf=floor(x); yf=floor(y); if(xf<1||xf>size||yf<1||yf>size, next);
  M[xf,yf]=1;
);\\fend
plotmat(M);
}
\\ Test:
pChaosGameS3(600,30000); \\ SierpTri1.png


program ChaosGame;

// FPC 3.0.2
uses
  Graph, windows, math;

// Return a point on a circle defined by angle and the circles radius
// Angle 0 = Radius points to the left
// Angle 90 = Radius points upwards
Function PointOfCircle(Angle: SmallInt; Radius: integer): TPoint;
var Ia: Double;
begin
  Ia:=DegToRad(-Angle);
  result.x:=round(cos(Ia)*Radius);
  result.y:=round(sin(Ia)*Radius);
end;

{ Main }

var
  GraphDev,GraphMode: smallint;
  Triangle: array[0..2] of Tpoint; // Corners of the triangle
  TriPnt: Byte;                    // Point in ^^^^
  Origin: TPoint;                  // Defines center of triangle
  Itterations: integer;            // Number of Itterations
  Radius: Integer;
  View: viewPorttype;
  CurPnt: TPoint;
  Rect: TRect;
  Counter: integer;
begin

  Repeat {forever}

    // Get the Itteration count 0=exit
    Write('Itterations: ');
    ReadLn(Itterations);

    if Itterations=0 then halt;

    // Set Up Graphics screen (everythings Auto detect)
    GraphDev:=Detect;
    GraphMode:=0;
    InitGraph(GraphDev,GraphMode,'');
    if GraphResult<>grok then
    begin
      Writeln('Graphics doesn''t work');
      Halt;
    end;

    // set Origin to center of the _Triangle_ (Not the creen)
    GetViewSettings(View);
    Rect.Create(View.x1,View.y1+10,View.x2,View.y2-10);
    Origin:=Rect.CenterPoint;
    Origin.Offset(0,Rect.Height div 6);  //  Center Triangle on screen

    // Define Equilateral triangle,
    Radius:=Origin.y;         // Radius of Circumscribed circle
    for Counter:=0 to 2 do
      Triangle[Counter]:=PointOfCircle((Counter*120)+90,Radius)+Origin;

    // Choose random starting point, in the incsribed circle of the triangle
    Radius:=Radius div 2;     // Radius of inscribed circle
    CurPnt:=PointOfCircle(random(360),random(Radius div 2))+Origin;

    // Play the Chaos Game
    for Counter:=0 to Itterations do
    begin
      TriPnt:=Random(3);                      // Select Triangle Point
      Rect.Create(Triangle[TriPnt],CurPnt);;  // Def. rect. between TriPnt and CurPnt
      CurPnt:=Rect.CenterPoint;               // New CurPnt is center of rectangle
      putPixel(CurPnt.x,CurPnt.y,cyan);       // Plot the new CurPnt
    end;

  until False;
end.


# Project : Casting out nines

co9(1, 10, 99, [1,9,45,55,99])
co9(1, 10, 1000, [1,9,45,55,99,297,703,999])

func co9(start,base,lim,kaprekars)
c1=0
c2=0
s = []
for k = start to lim
     c1 = c1 + 1
      if k % (base-1) = (k*k) % (base-1)
         c2 = c2 + 1
         add(s,k)
      ok
next
msg = "Valid subset" + nl
for i = 1 to len(kaprekars)
     if not find(s,kaprekars[i])
       msg = "***Invalid***" + nl
       exit
     ok
next
showarray(s)
see "Kaprekar numbers:" + nl
showarray(kaprekars)
see msg
see "Trying " + c2 + " numbers instead of " + c1 + " saves " + (100-(c2/c1)*100) + "%" + nl + nl

func showarray(vect)
        see "{"
        svect = ""
        for n = 1 to len(vect)
              svect = svect + vect[n] + ", "
        next
        svect = left(svect, len(svect) - 2)
        see svect + "}" + nl


N = 2
base = 10
c1 = 0
c2 = 0

for k in 1 .. (base ** N) - 1
    c1 = c1 + 1
    if k % (base - 1) == (k * k) % (base - 1) then
        c2 = c2 + 1
        print "%d " % [k]
    end
end

puts
print "Trying %d numbers instead of %d numbers saves %f%%" % [c2, c1, 100.0 - 100.0 * c2 / c1]


fn compare_co9_efficiency(base: u64, upto: u64) {
    let naive_candidates: Vec<u64> = (1u64..upto).collect();
    let co9_candidates: Vec<u64> = naive_candidates.iter().cloned()
        .filter(|&x| x % (base - 1) == (x * x) % (base - 1))
        .collect();
    for candidate in &co9_candidates {
        print!("{} ", candidate);
    }
    println!();
    println!(
        "Trying {} numbers instead of {} saves {:.2}%",
        co9_candidates.len(),
        naive_candidates.len(),
        100.0 - 100.0 * (co9_candidates.len() as f64 / naive_candidates.len() as f64)
    );
}

fn main() {
    compare_co9_efficiency(10, 100);
    compare_co9_efficiency(16, 256);
}


object kaprekar{
    // PART 1
    val co_base = ((x:Int,base:Int) => (x%(base-1) == (x*x)%(base-1)))
    //PART 2
    def get_cands(n:Int,base:Int):List[Int] = {
        if(n==1)                                List[Int]()
        else if (co_base(n,base))               n :: get_cands(n-1,base)
        else                                    get_cands(n-1,base)
    }
    def main(args:Array[String]) : Unit = {
        //PART 3
        val base = 31
        println("Candidates for Kaprekar numbers found by casting out method with base %d:".format(base))
        println(get_cands(1000,base))
    }
}


DOG$ = "Benjamin"
DOG$ = "Samba"
DOG$ = "Bernie"
PRINT "There is just one dog, named "; DOG$


dog = "Benjamin"
Dog = "Samba"
DOG = "Bernie"
print "There is just one dog, named "; dog
end


@echo off

set dog=Benjamin
set Dog=Samba
set DOG=Bernie

echo There is just one dog named %dog%.
pause>nul


      dog$ = "Benjamin"
      Dog$ = "Samba"
      DOG$ = "Bernie"
      PRINT "The three dogs are " dog$ ", " Dog$ " and " DOG$ "."


obase = 16
ibase = 16

/*
 * Store the hexadecimal number 'BE27A312'
 * in the variable 'd'.
 */
d = BE27A312
"There is just one dog named "; d
quit


use Imager;

my $width  = 1000;
my $height = 1000;

my @points = (
    [ $width/2,         0],
    [        0, $height-1],
    [$height-1, $height-1],
);

my $img = Imager->new(
                      xsize    => $width,
                      ysize    => $height,
                      channels => 3,
                     );

my $color = Imager::Color->new('#ff0000');
my $r = [int(rand($width)), int(rand($height))];

foreach my $i (1 .. 100000) {
    my $p = $points[rand @points];

    my $h = [
        int(($p->[0] + $r->[0]) / 2),
        int(($p->[1] + $r->[1]) / 2),
    ];

    $img->setpixel(
        x     => $h->[0],
        y     => $h->[1],
        color => $color,
    );

    $r = $h;
}

$img->write(file => 'chaos_game_triangle.png');


$ include "seed7_05.s7i";

const func bitset: castOut (in integer: base, in integer: start, in integer: ending) is func
  result
    var bitset: casted is {};
  local
    var bitset: ran is {};
    var integer: x is 0;
    var integer: n is 0;
    var integer: k is 0;
    var boolean: finished is FALSE;
  begin
    for x range 0 to base - 2 do
      if x rem pred(base) = x ** 2 rem pred(base) then
        incl(ran, x);
      end if;
    end for;
    x := start div pred(base);
    repeat
      for n range ran until finished do
        k := pred(base) * x + n;
        if k >= start then
          if k > ending then
            finished := TRUE;
          else
            incl(casted, k);
          end if;
        end if;
      end for;
      incr(x);
    until finished;
  end func;

const proc: main is func
  begin
    writeln(castOut(16, 1, 255));
  end func;


func cast_out(base = 10, min = 1, max = (base**2 - 1)) {

    var b9  = base-1
    var ran = b9.range.grep {|n| n%b9 == (n*n % b9) }

    var x = min//b9
    var r = []

    loop {
        ran.each {|n|
            var k = (b9*x + n)
            return r if (k > max)
            r << k if (k >= min)
        }
        ++x
    }

    return r
}

say cast_out().join(' ')
say cast_out(16).join(' ')
say cast_out(17).join(' ')


proc co9 {x} {
    while {[string length $x] > 1} {
	set x [tcl::mathop::+ {*}[split $x ""]]
    }
    return $x
}
# Extended to the general case
proc coBase {x {base 10}} {
    while {$x >= $base} {
	for {set digits {}} {$x} {set x [expr {$x / $base}]} {
	    lappend digits [expr {$x % $base}]
	}
	set x [tcl::mathop::+ {*}$digits]
    }
    return $x
}

# Simple helper
proc percent {part whole} {format "%.2f%%" [expr {($whole - $part) * 100.0 / $whole}]}

puts "In base 10..."
set satisfying {}
for {set i 1} {$i < 100} {incr i} {
    if {[co9 $i] == [co9 [expr {$i*$i}]]} {
	lappend satisfying $i
    }
}
puts $satisfying
puts "Trying [llength $satisfying] numbers instead of 99 numbers saves [percent [llength $satisfying] 99]"

puts "In base 16..."
set satisfying {}
for {set i 1} {$i < 256} {incr i} {
    if {[coBase $i 16] == [coBase [expr {$i*$i}] 16]} {
	lappend satisfying $i
    }
}
puts $satisfying
puts "Trying [llength $satisfying] numbers instead of 255 numbers saves [percent [llength $satisfying] 255]"


( Benjamin:?dog
& Samba:?Dog
& Bernie:?DOG
& out$("There are three dogs:" !dog !Dog and !DOG)
);


opendb dogs.g y            # Create a database to hold our dogs
units ft                   # The dogs are measured in feet
in dog.s sph 0 0 0 1       # Benjie is a little Scottie dog
in Dog.s sph 4 0 0 3       # Samba is a Labrador
in DOG.s sph 13 0 0 5      # Bernie is massive. He is a New Foundland
echo The three dogs are named Benjamin, Samba and Bernie


#include <stdio.h>

static const char *dog = "Benjamin";
static const char *Dog = "Samba";
static const char *DOG = "Bernie";

int main()
{
    printf("The three dogs are named %s, %s and %s.\n", dog, Dog, DOG);
    return 0;
}


using System;

class Program
{
    static void Main(string[] args)
    {
        string dog = "Benjamin";
        string Dog = "Samba";
        string DOG = "Bernie";
        Console.WriteLine(string.Format("The three dogs are named {0}, {1}, and {2}.", dog, Dog, DOG));
    }
}


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

Ihandle dlg, canvas
cdCanvas cddbuffer, cdcanvas

enum TRI,SQ1,SQ2,SQ3,PENT

sequence descs = {"Sierpinsky Triangle",
                  "Square 1",
                  "Square 2",
                  "Square 3",
                  "Pentagon"}

integer mode = TRI

function redraw_cb(Ihandle /*ih*/, integer /*posx*/, /*posy*/)
    atom {w,h} = IupGetIntInt(canvas, "DRAWSIZE")
    atom {x,y} = {w*0.05,h*0.05}
    {w,h} = {w*0.9,h*0.9}
    sequence points = iff(mode<SQ1?{{x,y},{x+w/2,y+h},{x+w,y}}:
                      iff(mode<PENT?{{x,y},{x,y+h},{x+w,y+h},{x+w,y}}
                                   :{{x+w/6,y},{x,y+h*2/3},{x+w/2,y+h},{x+w,y+h*2/3},{x+w*5/6,y}}))
    cdCanvasActivate(cddbuffer)
    integer last = 0
    for i=1 to 1000 do
        integer r = rand(length(points))
        if mode=TRI or r!=last then
            atom {nx,ny} = points[r]
            {x,y} = {(x+nx)/2,(y+ny)/2}
            cdCanvasPixel(cddbuffer, x, y, CD_GREY)
            if mode=SQ2
            or mode=SQ3 then
                r = mod(r,length(points))+1
                if mode=SQ3 then
                    r = mod(r,length(points))+1
                end if
            end if
            last = r
        end if
    end for
    cdCanvasFlush(cddbuffer)
    IupSetStrAttribute(dlg, "TITLE", "Chaos Game (%s)", {descs[mode]})
    return IUP_DEFAULT
end function

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

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

function key_cb(Ihandle /*ih*/, atom c)
    if c=K_ESC then return IUP_CLOSE end if
    if c=' ' then
        mode += 1
        if mode>PENT then
            mode = TRI
        end if
        cdCanvasClear(cddbuffer)
        IupRedraw(canvas)
    end if
    return IUP_CONTINUE
end function

procedure main()
    IupOpen()

    canvas = IupCanvas("RASTERSIZE=640x640")
    IupSetCallbacks(canvas, {"MAP_CB", Icallback("map_cb"),
                             "ACTION", Icallback("redraw_cb")})
    dlg = IupDialog(canvas, `TITLE="Chaos Game"`)
    IupSetCallback(dlg, "KEY_CB", Icallback("key_cb"))

    IupShow(dlg)
    IupSetAttribute(canvas, "RASTERSIZE", NULL)
    Ihandle timer = IupTimer(Icallback("timer_cb"), 40)
    if platform()!=JS then
        IupMainLoop()
        IupClose()
    end if
end procedure

main()


Module Module1
    Sub Print(ls As List(Of Integer))
        Dim iter = ls.GetEnumerator
        Console.Write("[")
        If iter.MoveNext Then
            Console.Write(iter.Current)
        End If
        While iter.MoveNext
            Console.Write(", ")
            Console.Write(iter.Current)
        End While
        Console.WriteLine("]")
    End Sub

    Function CastOut(base As Integer, start As Integer, last As Integer) As List(Of Integer)
        Dim ran = Enumerable.Range(0, base - 1).Where(Function(y) y Mod (base - 1) = (y * y) Mod (base - 1)).ToArray()
        Dim x = start \ (base - 1)

        Dim result As New List(Of Integer)
        While True
            For Each n In ran
                Dim k = (base - 1) * x + n
                If k < start Then
                    Continue For
                End If
                If k > last Then
                    Return result
                End If
                result.Add(k)
            Next
            x += 1
        End While
        Return result
    End Function

    Sub Main()
        Print(CastOut(16, 1, 255))
        Print(CastOut(10, 1, 99))
        Print(CastOut(17, 1, 288))
    End Sub

End Module


var castOut = Fn.new { |base, start, end|
    var b = base - 1
    var ran = (0...b).where { |n| n % b == (n * n) % b }
    var x = (start/b).floor
    var result = []
    while (true) {
        for (n in ran) {
            var k = b*x + n
            if (k >= start) {
                if (k > end) return result
                result.add(k)
            }
        }
        x = x + 1
    }
}

System.print(castOut.call(16, 1, 255))
System.print()
System.print(castOut.call(10, 1, 99))
System.print()
System.print(castOut.call(17, 1, 288))


#include <iostream>
#include <string>
using namespace std;

int main() {
    string dog = "Benjamin", Dog = "Samba", DOG = "Bernie";

    cout << "The three dogs are named " << dog << ", " << Dog << ", and " << DOG << endl;
}


user=> (let [dog "Benjamin" Dog "Samba" DOG "Bernie"] (format "The three dogs are named %s, %s and %s." dog Dog DOG))
"The three dogs are named Benjamin, Samba and Bernie."


* Case sensitivity of identifiers
       *>* Commented-out lines in the working storage
       *>* are considered as invalid redefinitions
       *>* of ''dog'' that can only be ambiguously
       *>* referenced in the procedure body.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. case-sensitivity.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       *>* 01  dog PICTURE X(8) VALUE IS "Benjamin".
       *>* 01  Dog PICTURE X(5) VALUE IS "Samba".
       01  DOG PICTURE X(6) VALUE IS "Bernie".
       PROCEDURE DIVISION.
         DISPLAY
       *>*     "The three dogs are named "
       *>*     dog ", " Dog " and " DOG "."
           "There is just one dog named " DOG "."
         END-DISPLAY
         STOP RUN.
       END PROGRAM case-sensitivity.


dog="Benjamin"
Dog = "Samba"
DOG = "Bernie"
console.log "The three dogs are names #{dog}, #{Dog}, and #{DOG}."


To run:
Start up.
Initialize our reference points.
Clear the screen to the lightest gray color.
Play the chaos game.
Refresh the screen.
Wait for the escape key.
Shut down.

To play the chaos game:
Pick a spot within 2 inches of the screen's center.
Loop.
Draw the spot.
If a counter is past 20000, exit.
Pick a reference spot.
Find a middle spot of the spot and the reference spot.
Put the middle spot into the spot.
Repeat.

To find a middle spot of a spot and another spot:
Put the spot's x coord plus the other spot's x coord divided by 2 into the middle spot's x coord.
Put the spot's y coord plus the other spot's y coord divided by 2 into the middle spot's y coord.

The top spot is a spot.
The left spot is a spot.
The right spot is a spot.

To initialize our reference points:
Move up 2-1/2 inches.
Put the context's spot into the top spot.
Turn right. Turn 1/6 of the way around.
Move 5 inches.
Put the context's spot into the right spot.
Turn 1/3 of the way around.
Move 5 inches.
Put the context's spot into the left spot.

To pick a reference spot:
Pick a number between 1 and 3.
If the number is 1, put the top spot into the reference spot.
If the number is 2, put the right spot into the reference spot.
If the number is 3, put the left spot into the reference spot.


size(300, 260);

background(#ffffff); // white

int x = floor(random(width));
int y = floor(random(height));

int colour = #ffffff;

for (int i=0; i<30000; i++) {
  int v = floor(random(3));
  switch (v) {
  case 0:
    x = x / 2;
    y = y / 2;
    colour = #00ff00; // green
    break;
  case 1:
    x = width/2 + (width/2 - x)/2;
    y = height - (height - y)/2;
    colour = #ff0000; // red
    break;
  case 2:
    x = width - (width - x)/2;
    y = y / 2;
    colour = #0000ff; // blue
  }
  set(x, height-y, colour);
}


fcn castOut(base=10, start=1, end=999999){
   base-=1;
   ran:=(0).filter(base,'wrap(n){ n%base == (n*n)%base });
   result:=Sink(List);
   foreach a,b in ([start/base ..],ran){  // foreach{ foreach {} }
      k := base*a + b;
      if (k < start) continue;
      if (k > end) return(result.close());
      result.write(k);
   }
   // doesn't get here
}


10 LET Base=10
20 LET N=2
30 LET c1=0
40 LET c2=0
50 LET k=1
60 IF k>=(Base^N)-1 THEN GO TO 150
70 LET c1=c1+1
80 IF FN m(k,Base-1)=FN m(k*k,Base-1) THEN LET c2=c2+1: PRINT k;" ";
90 LET k=k+1
100 GO TO 60
150 PRINT '"Trying ";c2;" numbers instead of ";c1;" numbers saves ";100-(c2/c1)*100;"%"
160 STOP
170 DEF FN m(a,b)=a-INT (a/b)*b


CL-USER> (let* ((dog "Benjamin") (Dog "Samba") (DOG "Bernie"))
	   (format nil "There is just one dog named ~a." dog))
; in: LAMBDA NIL
;     (LET* ((DOG "Benjamin") (DOG "Samba") (DOG "Bernie"))
;       (FORMAT NIL "There is just one dog named ~a." DOG))
;
; caught STYLE-WARNING:
;   The variable DOG is defined but never used.
;
; caught STYLE-WARNING:
;   The variable DOG is defined but never used.
;
; compilation unit finished
;   caught 2 STYLE-WARNING conditions
"There is just one dog named Bernie."


dog = "Benjamin"
Dog = "Samba"
DOG = "Bernie"

puts "The three dogs are named #{dog}, #{Dog} and #{DOG}."


import std.stdio;

void main() {
    string dog = "Benjamin";
    // identifiers that start with capital letters are type names
    string Dog = "Samba";
    string DOG = "Bernie";
    writefln("There are three dogs named ",
             dog, ", ", Dog, ", and ", DOG, "'");
}


[Benjamin]sd
[Samba]sD
[The two dogs are named ]P ldP [ and ]P lDP [.
]P


program CaseSensitiveIdentifiers;

{$APPTYPE CONSOLE}

var
  dog: string;
begin
  dog := 'Benjamin';
  Dog := 'Samba';
  DOG := 'Bernie';
  Writeln('There is just one dog named ' + dog);
end.


import argparse
import random
import shapely.geometry as geometry
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def main(args):
    # Styles
    plt.style.use("ggplot")

    # Creating figure
    fig = plt.figure()
    line, = plt.plot([], [], ".")

    # Limit axes
    plt.xlim(0, 1)
    plt.ylim(0, 1)

    # Titles
    title = "Chaos Game"
    plt.title(title)
    fig.canvas.set_window_title(title)

    # Getting data
    data = get_data(args.frames)

    # Creating animation
    line_ani = animation.FuncAnimation(
        fig=fig,
        func=update_line,
        frames=args.frames,
        fargs=(data, line),
        interval=args.interval,
        repeat=False
    )

    # To save the animation install ffmpeg and uncomment
    # line_ani.save("chaos_game.gif")

    plt.show()

def get_data(n):
    """
    Get data to plot
    """
    leg = 1
    triangle = get_triangle(leg)
    cur_point = gen_point_within_poly(triangle)
    data = []
    for _ in range(n):
        data.append((cur_point.x, cur_point.y))
        cur_point = next_point(triangle, cur_point)
    return data

def get_triangle(n):
    """
    Create right triangle
    """
    ax = ay = 0.0
    a = ax, ay

    bx = 0.5  *  n
    by = 0.75 * (n ** 2)
    b = bx, by

    cx = n
    cy = 0.0
    c = cx, cy

    triangle = geometry.Polygon([a, b, c])
    return triangle

def gen_point_within_poly(poly):
    """
    Generate random point inside given polygon
    """
    minx, miny, maxx, maxy = poly.bounds
    while True:
        x = random.uniform(minx, maxx)
        y = random.uniform(miny, maxy)
        point = geometry.Point(x, y)
        if point.within(poly):
            return point

def next_point(poly, point):
    """
    Generate next point according to chaos game rules
    """
    vertices = poly.boundary.coords[:-1]  # Last point is the same as the first one
    random_vertex = geometry.Point(random.choice(vertices))
    line = geometry.linestring.LineString([point, random_vertex])
    return line.centroid

def update_line(num, data, line):
    """
    Update line with new points
    """
    new_data = zip(*data[:num]) or [(), ()]
    line.set_data(new_data)
    return line,

if __name__ == "__main__":
    arg_parser = argparse.ArgumentParser(description="Chaos Game by Suenweek (c) 2017")
    arg_parser.add_argument("-f", dest="frames", type=int, default=1000)
    arg_parser.add_argument("-i", dest="interval", type=int, default=10)

    main(arg_parser.parse_args())


var dog : String;

dog := 'Benjamin';
Dog := 'Samba';
DOG := 'Bernie';

PrintLn('There is just one dog named ' + dog);


local :dog "Benjamin"
local :Dog "Samba"
local :DOG "Bernie"

!print( "There are three dogs named " dog ", " Dog " and " DOG "." )


(define dog "Benjamin")
(define Dog "Samba")
(define DOG "Bernie")

(printf "The three dogs are named %a, %a and %a. " dog Dog DOG)
    The three dogs are named Benjamin, Samba and Bernie.


import extensions;

public program()
{
    var dog := "Benjamin";
    var Dog := "Samba";
    var DOG := "Bernie";
    console.printLineFormatted("The three dogs are named {0}, {1} and {2}", dog, Dog, DOG)
}


dog = "Benjamin"
doG = "Samba"
dOG = "Bernie"
IO.puts "The three dogs are named #{dog}, #{doG} and #{dOG}."


# Chaos Game  (Sierpinski triangle) 2/15/17 aev
# pChaosGameS3(size, lim, clr, fn, ttl)
# Where: size - defines matrix and picture size; lim - limit of the dots;
#   fn - file name (.ext will be added); ttl - plot title;
pChaosGameS3 <- function(size, lim, clr, fn, ttl)
{
  cat(" *** START:", date(), "size=",size, "lim=",lim, "clr=",clr, "\n");
  sz1=floor(size/2); sz2=floor(sz1*sqrt(3)); xf=yf=v=0;
  M <- matrix(c(0), ncol=size, nrow=size, byrow=TRUE);
  x <- sample(1:size, 1, replace=FALSE);
  y <- sample(1:sz2, 1, replace=FALSE);
  pf=paste0(fn, ".png");
  for (i in 1:lim) { v <- sample(0:3, 1, replace=FALSE);
    if(v==0) {x=x/2; y=y/2;}
    if(v==1) {x=sz1+(sz1-x)/2; y=sz2-(sz2-y)/2;}
    if(v==2) {x=size-(size-x)/2; y=y/2;}
    xf=floor(x); yf=floor(y); if(xf<1||xf>size||yf<1||yf>size) {next};
    M[xf,yf]=1;
  }
  plotmat(M, fn, clr, ttl, 0, size);
  cat(" *** END:",date(),"\n");
}
pChaosGameS3(600, 30000, "red", "SierpTriR1", "Sierpinski triangle")


#lang racket

(require 2htdp/image)

(define SIZE 300)

(define (game-of-chaos fns WIDTH HEIGHT SIZE
                       #:offset-x [offset-x 0] #:offset-y [offset-y 0]
                       #:iters [iters 10000]
                       #:bg [bg 'white] #:fg [fg 'black])
  (define dot (square 1 'solid fg))
  (define all-choices (apply + (map first fns)))
  (for/fold ([image (empty-scene WIDTH HEIGHT bg)]
             [x (random)] [y (random)]
             #:result image)
            ([i (in-range iters)])
    (define picked (random all-choices))
    (define fn (for/fold ([acc 0] [result #f] #:result result) ([fn (in-list fns)])
                 #:break (> acc picked)
                 (values (+ (first fn) acc) (second fn))))
    (match-define (list x* y*) (fn x y))
    (values (place-image dot (+ offset-x (* SIZE x*)) (+ offset-y (* SIZE y*)) image)
            x* y*)))

(define (draw-triangle)
  (define ((mid a b) x y) (list (/ (+ a x) 2) (/ (+ b y) 2)))
  (define (triangle-height x) (* (sqrt 3) 0.5 x))
  (game-of-chaos (list (list 1 (mid 0 0))
                       (list 1 (mid 1 0))
                       (list 1 (mid 0.5 (triangle-height 1))))
                 SIZE (triangle-height SIZE) SIZE))

(define (draw-fern)
  (define (f1 x y) (list 0 (* 0.16 y)))
  (define (f2 x y) (list (+ (* 0.85 x) (* 0.04 y)) (+ (* -0.04 x) (* 0.85 y) 1.6)))
  (define (f3 x y) (list (+ (* 0.2 x) (* -0.26 y)) (+ (* 0.23 x) (* 0.22 y) 1.6)))
  (define (f4 x y) (list (+ (* -0.15 x) (* 0.28 y)) (+ (* 0.26 x) (* 0.24 y) 0.44)))
  (game-of-chaos (list (list 1 f1) (list 85 f2) (list 7 f3) (list 7 f4))
                 (/ SIZE 2) SIZE (/ SIZE 11) #:offset-x 70 #:offset-y 10
                 #:bg 'black #:fg 'white))

(define (draw-dragon)
  (game-of-chaos
   (list (list 1 (λ (x y) (list (+ (* 0.5 x) (* -0.5 y)) (+ (* 0.5 x) (* 0.5 y)))))
         (list 1 (λ (x y) (list (+ (* -0.5 x) (* 0.5 y) 1) (+ (* -0.5 x) (* -0.5 y))))))
   SIZE (* 0.8 SIZE) (/ SIZE 1.8) #:offset-x 64 #:offset-y 120))

(draw-triangle)
(draw-fern)
(draw-dragon)


use Image::PNG::Portable;

my ($w, $h) = (640, 640);

my $png = Image::PNG::Portable.new: :width($w), :height($h);

my @vertex = [0, 0], [$w, 0], [$w/2, $h];

my @xy = [0,0], [0,0], [0,0], [0,0];

# :degree must be equal to or less than @xy elements.
(^1e5).race(:4degree).map: {
    my $p = ++$ % +@xy;
    @xy[$p] = do given @vertex.pick -> @v { ((@xy[$p] »+« @v) »/» 2)».Int };
    $png.set: |@xy[$p], 0, 255, 0;
}

$png.write: 'Chaos-game-perl6.png';


-module( case_sensitivity_of_identifiers ).

-export( [task/0] ).

task() ->
	catch dog = "Benjamin", % Function will crash without catch
	Dog = "Samba",
	DOG = "Bernie",
	io:fwrite( "The three dogs are named ~s, ~s and ~s~n", [dog, Dog, DOG] ).


-- These variables are all different
sequence dog = "Benjamin"
sequence Dog = "Samba"
sequence DOG = "Bernie"
printf( 1, "The three dogs are named %s, %s and %s\n", {dog, Dog, DOG} )


let dog = "Benjamin"
let Dog = "Samba"
let DOG = "Bernie"
printfn "There are three dogs named %s, %s and %s" dog Dog DOG


USING: formatting locals ;
IN: scratchpad
[let
    "Benjamin" :> dog
    "Samba"    :> Dog
    "Bernie"   :> DOG
    { dog Dog DOG } "There are three dogs named %s, %s, and %s." vprintf
]


: DOG ." Benjamin" ;
: Dog ." Samba" ;
: dog ." Bernie" ;
: HOWMANYDOGS ." There is just one dog named " DOG ;
HOWMANYDOGS


/*REXX pgm draws a Sierpinski triangle by running the  chaos game  with a million points*/
parse value  scrsize()   with  sd  sw  .         /*obtain the depth and width of screen.*/
sw= sw - 2                                       /*adjust the screen width down by two. */
sd= sd - 4                                       /*   "    "     "   depth   "   " four.*/
parse arg pts chr seed .                         /*obtain optional arguments from the CL*/
if pts=='' | pts==","  then pts= 1000000         /*Not specified?  Then use the default.*/
if chr=='' | chr==","  then chr= '∙'             /* "      "         "   "   "      "   */
if datatype(seed,'W')  then call random ,,seed   /*Is  specified?    "   "  RANDOM seed.*/
x= sw;       hx= x % 2;     y= sd                /*define the initial starting position.*/
@.= ' '                                          /*   "   all screen points as a blank. */
        do pts;  ?= random(1, 3)                 /* [↓]  draw a # of (million?)  points.*/
                       select                    /*?:  will be a random number: 1 ──► 3.*/
                       when ?==1  then parse value          x%2          y%2   with   x  y
                       when ?==2  then parse value  hx+(hx-x)%2  sd-(sd-y)%2   with   x  y
                       otherwise       parse value  sw-(sw-x)%2          y%2   with   x  y
                       end   /*select*/
        @.x.y= chr                               /*set the    X, Y    point to a bullet.*/
        end   /*pts*/                            /* [↑]  one million points ≡ overkill? */
                                                 /* [↓]  display the points to the term.*/
        do      row=sd   to 0  by -1;   _=       /*display the points, one row at a time*/
             do col=0   for sw+2                 /*   "     a  row (one line) of image. */
             _= _ || @.col.row                   /*construct a  "    "    "    "   "    */
             end   /*col*/                       /*Note: display image from top──►bottom*/
                                                 /* [↑]  strip trailing blanks (output).*/
        say strip(_, 'T')                        /*display one row (line) of the image. */
        end        /*row*/                       /*stick a fork in it,  we're all done. */


# Project : Chaos game

load "guilib.ring"

paint = null

new qapp
       {
       win1 = new qwidget() {
                  setwindowtitle("Archimedean spiral")
                  setgeometry(100,100,500,600)
                  label1 = new qlabel(win1) {
                               setgeometry(10,10,400,400)
                               settext("")
                  }
                 new qpushbutton(win1) {
                        setgeometry(150,500,100,30)
                        settext("draw")
                        setclickevent("draw()")
                    }
               show()
       }
       exec()
       }

func draw
       p1 = new qpicture()
               color = new qcolor() {
               setrgb(0,0,255,255)
       }
       pen = new qpen() {
                setcolor(color)
                setwidth(1)
       }
       paint = new qpainter() {
                  begin(p1)
                  setpen(pen)

       x = floor(random(10)/10 * 200)
       y = floor(random(10/10) * 173)
       for i = 1 to 20000
           v = floor(random(10)/10 * 3) + 1
	   if v = 1
	      x = x/2
	      y = y/2
	   ok
	   if v = 2
	      x = 100 + (100-x)/2
	      y = 173 - (173-y)/2
	   ok
	   if v = 3
	      x = 200 - (200-x)/2
	      y = y/2
	   ok
	   drawpoint(x,y)
       next
       endpaint()
       }
       label1 {setpicture(p1) show()}


x	= int(rnd(0) * 200)
y	= int(rnd(0) * 173)
graphic #g, 200,200
#g color("green")
for i =1 TO 20000
	v = int(rnd(0) * 3) + 1
	if v = 1 then
		x = x/2
		y = y/2
	end if
	if v = 2 then
		x = 100 + (100-x)/2
		y = 173 - (173-y)/2
	end if
	if v = 3 then
		x = 200 - (200-x)/2
		y = y/2
	end if
	#g set(x,y)
next
render #g


program Example
  implicit none

  character(8) :: dog, Dog, DOG

  dog = "Benjamin"
  Dog = "Samba"
  DOG = "Bernie"

  if (dog == DOG) then
    write(*,*) "There is just one dog named ", dog
  else
    write(*,*) "The three dogs are named ", dog, Dog, " and ", DOG
  end if

end program Example


' FB 1.05.0 Win64

' FreeBASIC is case-insensitive
Dim dog As String
dog = "Benjamin"
Dog = "Samba"
DOG = "Bernie"
Print "There is just one dog, named "; dog
Sleep


dog = "Benjamin"
Dog = "Samba"
DOG = "Bernie"
println["There are three dogs named $dog, $Dog and $DOG"]


Public Sub Main()
Dim dog As String

Dog = "Benjamin"
DOG = "Samba"
dog = "Bernie"
Print "There is just one dog, named "; dog

End


# GAP is case sensitive
ThreeDogs := function()
	local dog, Dog, DOG;
	dog := "Benjamin";
	Dog := "Samba";
	DOG := "Bernie";
	if dog = DOG then
		Print("There is just one dog named ", dog, "\n");
	else
		Print("The three dogs are named ", dog, ", ", Dog, " and ", DOG, "\n");
	fi;
end;

ThreeDogs();
# The three dogs are named Benjamin, Samba and Bernie


package dogs

import "fmt"

// Three variables, three different names.
// (It wouldn't compile if the compiler saw the variable names as the same.)
var dog = "Salt"
var Dog = "Pepper"
var DOG = "Mustard"

func PackageSees() map[*string]int {
    // Print dogs visible from here.
    fmt.Println("Package sees:", dog, Dog, DOG)
    // Return addresses of the variables visible from here.
    // The point of putting them in a map is that maps store only
    // unique keys, so it will end up with three items only if
    // the variables really represent different places in memory.
    return map[*string]int{&dog: 1, &Dog: 1, &DOG: 1}
}


extern crate image;
extern crate rand;

use rand::prelude::*;
use std::f32;

fn main() {
    let max_iterations = 50_000;
    let img_side = 800;
    let tri_size = 400.0;

    // Create a new ImgBuf
    let mut imgbuf = image::ImageBuffer::new(img_side, img_side);

    // Create triangle vertices
    let mut vertices: [[f32; 2]; 3] = [[0.0, 0.0]; 3];
    for i in 0..vertices.len() {
        vertices[i][0] = (img_side as f32 / 2.0)
            + (tri_size / 2.0) * (f32::consts::PI * i as f32 * 2.0 / 3.0).cos();
        vertices[i][1] = (img_side as f32 / 2.0)
            + (tri_size / 2.0) * (f32::consts::PI * i as f32 * 2.0 / 3.0).sin();
    }
    for v in &vertices {
        imgbuf.put_pixel(v[0] as u32, v[1] as u32, image::Luma([255u8]));
    }
    println!("Verticies: {:?}", vertices);

    // Iterate chaos game
    let mut rng = rand::thread_rng();
    let mut x = img_side as f32 / 2.0;
    let mut y = img_side as f32 / 2.0;
    for _ in 0..max_iterations {
        let choice = rng.gen_range(0..vertices.len());
        x = (x + vertices[choice][0]) / 2.0;
        y = (y + vertices[choice][1]) / 2.0;

        imgbuf.put_pixel(x as u32, y as u32, image::Luma([255u8]));
    }

    // Save image
    imgbuf.save("fractal.png").unwrap();
}


import javax.swing._
import java.awt._
import java.awt.event.ActionEvent

import scala.collection.mutable
import scala.util.Random

object ChaosGame extends App {
  SwingUtilities.invokeLater(() =>
    new JFrame("Chaos Game") {

      class ChaosGame extends JPanel {
        private val (dim, margin)= (new Dimension(640, 640), 60)
        private val sizez: Int = dim.width - 2 * margin
        private val (stack, r) = (new mutable.Stack[ColoredPoint], new Random)
        private val points = Seq(new Point(dim.width / 2, margin),
          new Point(margin, sizez),
          new Point(margin + sizez, sizez)
        )
        private val colors = Seq(Color.red, Color.green, Color.blue)

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

          def drawPoints(g: Graphics2D): Unit = {
            for (p <- stack) {
              g.setColor(colors(p.colorIndex))
              g.fillOval(p.x, p.y, 1, 1)
            }
          }

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

        private def addPoint(): Unit = {
          val colorIndex = r.nextInt(3)

          def halfwayPoint(a: Point, b: Point, idx: Int) =
            new ColoredPoint((a.x + b.x) / 2, (a.y + b.y) / 2, idx)

          stack.push(halfwayPoint(stack.top, points(colorIndex), colorIndex))
        }

        class ColoredPoint(x: Int, y: Int, val colorIndex: Int) extends Point(x, y)

        stack.push(new ColoredPoint(-1, -1, 0))
        new Timer(100, (_: ActionEvent) => {
          if (stack.size < 50000) {
            for (i <- 0 until 1000) addPoint()
            repaint()
          }
        }).start()
        setBackground(Color.white)
        setPreferredSize(dim)
      }

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

}


def dog = "Benjamin", Dog = "Samba", DOG = "Bernie"
println (dog == DOG ? "There is one dog named ${dog}" : "There are three dogs named ${dog}, ${Dog} and ${DOG}.")


import Text.Printf

main = printf "The three dogs are named %s, %s and %s.\n" dog dOG dOg
    where dog = "Benjamin"
          dOG = "Samba"
          dOg = "Bernie"


procedure main()

   dog := "Benjamin"
   Dog := "Samba"
   DOG := "Bernie"

   if dog == DOG then
      write("There is just one dog named ", dog,".")
   else
      write("The three dogs are named ", dog, ", ", Dog, " and ", DOG, ".")

end


   NB. These variables are all different
   dog=: 'Benjamin'
   Dog=: 'Samba'
   DOG=: 'Bernie'
   'The three dogs are named ',dog,', ',Dog,', and ',DOG
The three dogs are named Benjamin, Samba, and Bernie


String dog = "Benjamin";
String Dog = "Samba"; //in general, identifiers that start with capital letters are class names
String DOG = "Bernie"; //in general, identifiers in all caps are constants
//the conventions listed in comments here are not enforced by the language
System.out.println("There are three dogs named " + dog + ", " + Dog + ", and " + DOG + "'");


//Input
n_sides = 3;
side_length = 1;
ratio = 0.5;
n_steps = 1.0d5;
first_step = 0;

if n_sides<3 then
    error("n_sides should be at least 3.");
end

//Calculating vertices' positions
theta = (2 * %pi) / n_sides;
alpha = (180 - (360/n_sides)) / 2 * (%pi/180);
radius = (sin(theta) / side_length) / sin(alpha);
vertices = zeros(1,n_sides);
for i=1:n_sides
    vertices(i) = radius * exp( %i * theta * (i-1) ); //equally spaced vertices over a circumference
                                                      //centered on 0 + 0i, or (0,0)
end
clear theta alpha radius i

//Iterations
tic();
points = zeros(1,n_steps);
points(1) = first_step;
i = 2;
while i <= n_steps
    random=grand(1,'prm',[1:n_sides]'); //sort vertices randomly
    random=random(1);                   //choose the first random vertices

    points(i) = ( vertices(random) - points(i-1) ) * (1-ratio) + points(i-1);

    i = i + 1;
end
time=toc();
disp('Time: '+string(time)+'s.');

//Ploting
scf(0); clf();
xname('Chaos game: '+string(n_sides)+'-sides polygon');
plot2d(real(points),imag(points),0)
plot2d(real(vertices),imag(vertices),-3);
set(gca(),'isoview','on');


require('Imager')

var width  = 600
var height = 600

var points = [
    [width//2,        0],
    [       0, height-1],
    [height-1, height-1],
]

var img = %O|Imager|.new(
                      xsize => width,
                      ysize => height,
                     )

var color = %O|Imager::Color|.new('#ff0000')
var r = [(width-1).irand, (height-1).irand]

30000.times {
    var p = points.rand

    r[] = (
        (p[0] + r[0]) // 2,
        (p[1] + r[1]) // 2,
    )

    img.setpixel(
        x     => r[0],
        y     => r[1],
        color => color,
    )
}

img.write(file => 'chaos_game.png')


var dog = "Benjamin";
var Dog = "Samba";
var DOG = "Bernie";
document.write("The three dogs are named " + dog + ", " + Dog + ", and " + DOG + ".");


def task(dog; Dog; DOG):
 "The three dogs are named \(dog), \(Dog), and \(DOG)." ;

task("Benjamin"; "Samba"; "Bernie")


dog, Dog, DOG = "Benjamin", "Samba", "Bernie"

if dog === Dog
    println("There is only one dog, ", DOG)
else
    println("The three dogs are:  ", dog, ", ", Dog, " and ", DOG)
end


  dog: "Benjamin"
  Dog: "Samba"
  DOG: "Bernie"
  "There are three dogs named ",dog,", ",Dog," and ",DOG
"There are three dogs named Benjamin, Samba and Bernie"


fun main(args: Array<String>) {
    val dog = "Benjamin"
    val Dog = "Samba"
    val DOG = "Bernie"
    println("The three dogs are named $dog, $Dog and $DOG")
}


local(dog = 'Benjamin')
local(Dog = 'Samba')
local(DOG = 'Bernie')

stdoutnl('There is just one dog named ' + #dog)


BEGIN
    INTEGER U, COLUMNS, LINES;
    COLUMNS := 40;
    LINES := 80;
    U := ININT;
    BEGIN
        CHARACTER ARRAY SCREEN(0:LINES, 0:COLUMNS);
        INTEGER X, Y, I, VERTEX;

        FOR X := 0 STEP 1 UNTIL LINES-1 DO
            FOR Y := 0 STEP 1 UNTIL COLUMNS-1 DO
                SCREEN(X, Y) := ' ';

        X := RANDINT(0, LINES - 1, U);
        Y := RANDINT(0, COLUMNS - 1, U);

        FOR I := 1 STEP 1 UNTIL 5000 DO
        BEGIN
            VERTEX := RANDINT(1, 3, U);
            IF VERTEX = 1 THEN BEGIN X := X // 2;
                                     Y := Y // 2;
                               END ELSE
            IF VERTEX = 2 THEN BEGIN X := LINES // 2 + (LINES // 2 - X) // 2;
                                     Y := COLUMNS - (COLUMNS - Y) // 2;
                               END ELSE
            IF VERTEX = 3 THEN BEGIN X := LINES - (LINES - X) // 2;
                                     Y := Y // 2;
                               END ELSE ERROR("VERTEX OUT OF BOUNDS");
            SCREEN(X, Y) := 'X';
        END;

        FOR Y := 0 STEP 1 UNTIL COLUMNS-1 DO
        BEGIN
            FOR X := 0 STEP 1 UNTIL LINES-1 DO
                OUTCHAR(SCREEN(X, Y));
            OUTIMAGE;
        END;
    END;
END


import "dome" for Window
import "graphics" for Canvas, Color
import "math" for Point
import "random" for Random
import "./dynamic" for Tuple
import "./seq" for Stack

var ColoredPoint = Tuple.create("ColoredPoint", ["x", "y", "colorIndex"])

class ChaosGame {
    construct new(width, height) {
        Window.resize(width, height)
        Canvas.resize(width, height)
        Window.title = "Chaos game"
        _width = width
        _height = height
        _stack = Stack.new()
        _points = null
        _colors = [Color.red, Color.green, Color.blue]
        _r = Random.new()
    }

    init() {
        Canvas.cls(Color.white)
        var margin = 60
        var size = _width - 2 * margin
        _points = [
            Point.new((_width/2).floor, margin),
            Point.new(margin, size),
            Point.new(margin + size, size)
        ]
        _stack.push(ColoredPoint.new(-1, -1, 0))
    }

    addPoint() {
        var colorIndex = _r.int(3)
        var p1 = _stack.peek()
        var p2 = _points[colorIndex]
        _stack.push(halfwayPoint(p1, p2, colorIndex))
    }

    drawPoints() {
        for (cp in _stack) {
            var c = _colors[cp.colorIndex]
            Canvas.circlefill(cp.x, cp.y, 1, c)
        }
    }

    halfwayPoint(a, b, idx) { ColoredPoint.new(((a.x + b.x)/2).floor, ((a.y + b.y)/2).floor, idx) }

    update() {
        if (_stack.count < 50000) {
            for (i in 0...25) addPoint()
        }
    }

    draw(alpha) {
        drawPoints()
    }
}

var Game = ChaosGame.new(640, 640)


vertex face_point(face f)
{
	int i;
	vertex v;

	if (!f->avg) {
		f->avg = vertex_new();
		foreach(i, v, f->v)
			if (!i) f->avg->pos = v->pos;
			else    vadd(f->avg->pos, v->pos);

		vdiv(f->avg->pos, len(f->v));
	}
	return f->avg;
}

#define hole_edge(e) (len(e->f)==1)
vertex edge_point(edge e)
{
	int i;
	face f;

	if (!e->e_pt) {
		e->e_pt = vertex_new();
		e->avg = e->v[0]->pos;
		vadd(e->avg, e->v[1]->pos);
		e->e_pt->pos = e->avg;

		if (!hole_edge(e)) {
			foreach (i, f, e->f)
				vadd(e->e_pt->pos, face_point(f)->pos);
			vdiv(e->e_pt->pos, 4);
		} else
			vdiv(e->e_pt->pos, 2);

		vdiv(e->avg, 2);
	}

	return e->e_pt;
}

#define hole_vertex(v) (len((v)->f) != len((v)->e))
vertex updated_point(vertex v)
{
	int i, n = 0;
	edge e;
	face f;
	coord_t sum = {0, 0, 0};

	if (v->v_new) return v->v_new;

	v->v_new = vertex_new();
	if (hole_vertex(v)) {
		v->v_new->pos = v->pos;
		foreach(i, e, v->e) {
			if (!hole_edge(e)) continue;
			vadd(v->v_new->pos, edge_point(e)->pos);
			n++;
		}
		vdiv(v->v_new->pos, n + 1);
	} else {
		n = len(v->f);
		foreach(i, f, v->f)
			vadd(sum, face_point(f)->pos);
		foreach(i, e, v->e)
			vmadd(sum, edge_point(e)->pos, 2, sum);
		vdiv(sum, n);
		vmadd(sum, v->pos, n - 3, sum);
		vdiv(sum, n);
		v->v_new->pos = sum;
	}

	return v->v_new;
}

model catmull(model m)
{
	int i, j, a, b, c, d;
	face f;
	vertex v, x;

	model nm = model_new();
	foreach (i, f, m->f) {
		foreach(j, v, f->v) {
			_get_idx(a, updated_point(v));
			_get_idx(b, edge_point(elem(f->e, (j + 1) % len(f->e))));
			_get_idx(c, face_point(f));
			_get_idx(d, edge_point(elem(f->e, j)));
			model_add_face(nm, 4, a, b, c, d);
		}
	}
	return nm;
}


dog$ = "Benjamin"
Dog$ = "Samba"
DOG$ = "Bernie"
print "The three dogs are "; dog$; ", "; Dog$; " and "; DOG$; "."

end


dog = "Benjamin"
Dog = "Samba"
DOG = "Bernie"

print( "There are three dogs named "..dog..", "..Dog.." and "..DOG.."." )


MoDuLe CheckIT {
      \\ keys as case sensitive if they are strings
      Inventory A= "Dog":=1, "dog":=2,"DOG":="Hello", 100:="Dog"
      Print A("Dog"), A("dog"), A$("DOG"), A$(100)

      \\ Enumeration get type as defined (same case)
      Enum Dogs {Benjamin, Samba, Bernie}
      Print Type$(Bernie)="Dogs"
      Print Type$(DOGS)="Dogs"
      m=BenJamiN
      m++
      Print Eval$(m)="Samba"  ' same case as defined

      DoG$="Benjamin"
      DOG$="Samba"
      doG$="Bernie"
      PrinT "There is just one dog named "+Dog$+"."
      goto Dog
dog:
      Print "dog"
      Exit
Dog:
      Print "Dog"
      GoTo dog
}
Checkit


> dog, Dog, DOG := "Benjamin", "Samba", "Bernie":
> if nops( { dog, Dog, DOG } ) = 3 then
>   printf( "There are three dogs named %s, %s and %s.\n", dog, Dog, DOG )
> elif nops( { dog, Dog, DOG } ) = 2 then
>   printf( "WTF? There are two dogs named %s and %s.\n", op( { dog, Dog, DOG } ) )
> else
>   printf( "There is one dog named %s.\n", dog )
> end if:
There are three dogs named Benjamin, Samba and Bernie.


dog = "Benjamin"; Dog = "Samba"; DOG = "Bernie";
"The three dogs are named "<> dog <>", "<> Dog <>" and "<> DOG

-> "The three dogs are named Benjamin, Samba and Bernie"


  dog = 'Benjamin';
  Dog = 'Samba';
  DOG = 'Bernie';

  printf('There are three dogs %s, %s, %s.\n',dog, Dog, DOG);


      1                                  ;Assemble with: tasm, tlink /t
      2     0000                                 .model  tiny
      3     0000                                 .code
      4                                          .386
      5                                          org     100h
      6                                  ;assume: ax=0, bx=0, cx=00FFh, dx=cs, si=0100h
      7
      8     0100  B0 12                  start:  mov     al, 12h         ;set 640x480x4 graphic screen
      9     0102  CD 10                          int     10h
     10
     11     0104  69 04 4E35             cha10:  imul    ax, [si], 4E35h ;generate random number
     12     0108  40                             inc     ax
     13     0109  89 04                          mov     [si], ax        ;save seed
     14     010B  8A C4                          mov     al, ah          ;use high byte
     15     010D  D4 03                          aam     3               ;al:= rem(al/3)
     16     010F  8A D8                          mov     bl, al
     17     0111  02 DB                          add     bl, bl          ;double to index words
     18
     19     0113  03 8F 0130r                    add     cx, [bx+Tx]     ;X:= (X+Tx(R)) /2
     20     0117  D1 E9                          shr     cx, 1
     21
     22     0119  03 97 0136r                    add     dx, [bx+Ty]     ;Y:= (Y+Ty(R)) /2
     23     011D  D1 EA                          shr     dx, 1
     24
     25     011F  B8 0C02                        mov     ax, 0C02h       ;write green (2) graphics pixel
     26     0122  CD 10                          int     10h             ;(bh=0)
     27
     28     0124  B4 01                          mov     ah, 01h         ;loop until keystroke
     29     0126  CD 16                          int     16h
     30     0128  74 DA                          jz      cha10
     31
     32     012A  B8 0003                        mov     ax, 0003h       ;restore normal text-mode screen
     33     012D  CD 10                          int     10h
     34     012F  C3                             ret                     ;return to DOS
     35
     36     0130  0140 002B 0255         Tx      dw      320, 320-277, 320+277 ;equilateral triangle
     37     0136  0000 01DF 01DF         Ty      dw        0, 479,     479
     38                                          end     start


package main

import (
    "fmt"
    "sort"
)

type (
    Point [3]float64
    Face  []int

    Edge struct {
        pn1 int   // point number 1
        pn2 int   // point number 2
        fn1 int   // face number 1
        fn2 int   // face number 2
        cp  Point // center point
    }

    PointEx struct {
        p Point
        n int
    }
)

func sumPoint(p1, p2 Point) Point {
    sp := Point{}
    for i := 0; i < 3; i++ {
        sp[i] = p1[i] + p2[i]
    }
    return sp
}

func mulPoint(p Point, m float64) Point {
    mp := Point{}
    for i := 0; i < 3; i++ {
        mp[i] = p[i] * m
    }
    return mp
}

func divPoint(p Point, d float64) Point {
    return mulPoint(p, 1.0/d)
}

func centerPoint(p1, p2 Point) Point {
    return divPoint(sumPoint(p1, p2), 2)
}

func getFacePoints(inputPoints []Point, inputFaces []Face) []Point {
    facePoints := make([]Point, len(inputFaces))
    for i, currFace := range inputFaces {
        facePoint := Point{}
        for _, cpi := range currFace {
            currPoint := inputPoints[cpi]
            facePoint = sumPoint(facePoint, currPoint)
        }
        facePoint = divPoint(facePoint, float64(len(currFace)))
        facePoints[i] = facePoint
    }
    return facePoints
}

func getEdgesFaces(inputPoints []Point, inputFaces []Face) []Edge {
    var edges [][3]int
    for faceNum, face := range inputFaces {
        numPoints := len(face)
        for pointIndex := 0; pointIndex < numPoints; pointIndex++ {
            pointNum1 := face[pointIndex]
            var pointNum2 int
            if pointIndex < numPoints-1 {
                pointNum2 = face[pointIndex+1]
            } else {
                pointNum2 = face[0]
            }
            if pointNum1 > pointNum2 {
                pointNum1, pointNum2 = pointNum2, pointNum1
            }
            edges = append(edges, [3]int{pointNum1, pointNum2, faceNum})
        }
    }
    sort.Slice(edges, func(i, j int) bool {
        if edges[i][0] == edges[j][0] {
            if edges[i][1] == edges[j][1] {
                return edges[i][2] < edges[j][2]
            }
            return edges[i][1] < edges[j][1]
        }
        return edges[i][0] < edges[j][0]
    })
    numEdges := len(edges)
    eIndex := 0
    var mergedEdges [][4]int
    for eIndex < numEdges {
        e1 := edges[eIndex]
        if eIndex < numEdges-1 {
            e2 := edges[eIndex+1]
            if e1[0] == e2[0] && e1[1] == e2[1] {
                mergedEdges = append(mergedEdges, [4]int{e1[0], e1[1], e1[2], e2[2]})
                eIndex += 2
            } else {
                mergedEdges = append(mergedEdges, [4]int{e1[0], e1[1], e1[2], -1})
                eIndex++
            }
        } else {
            mergedEdges = append(mergedEdges, [4]int{e1[0], e1[1], e1[2], -1})
            eIndex++
        }
    }
    var edgesCenters []Edge
    for _, me := range mergedEdges {
        p1 := inputPoints[me[0]]
        p2 := inputPoints[me[1]]
        cp := centerPoint(p1, p2)
        edgesCenters = append(edgesCenters, Edge{me[0], me[1], me[2], me[3], cp})
    }
    return edgesCenters
}

func getEdgePoints(inputPoints []Point, edgesFaces []Edge, facePoints []Point) []Point {
    edgePoints := make([]Point, len(edgesFaces))
    for i, edge := range edgesFaces {
        cp := edge.cp
        fp1 := facePoints[edge.fn1]
        var fp2 Point
        if edge.fn2 == -1 {
            fp2 = fp1
        } else {
            fp2 = facePoints[edge.fn2]
        }
        cfp := centerPoint(fp1, fp2)
        edgePoints[i] = centerPoint(cp, cfp)
    }
    return edgePoints
}

func getAvgFacePoints(inputPoints []Point, inputFaces []Face, facePoints []Point) []Point {
    numPoints := len(inputPoints)
    tempPoints := make([]PointEx, numPoints)
    for faceNum := range inputFaces {
        fp := facePoints[faceNum]
        for _, pointNum := range inputFaces[faceNum] {
            tp := tempPoints[pointNum].p
            tempPoints[pointNum].p = sumPoint(tp, fp)
            tempPoints[pointNum].n++
        }
    }
    avgFacePoints := make([]Point, numPoints)
    for i, tp := range tempPoints {
        avgFacePoints[i] = divPoint(tp.p, float64(tp.n))
    }
    return avgFacePoints
}

func getAvgMidEdges(inputPoints []Point, edgesFaces []Edge) []Point {
    numPoints := len(inputPoints)
    tempPoints := make([]PointEx, numPoints)
    for _, edge := range edgesFaces {
        cp := edge.cp
        for _, pointNum := range []int{edge.pn1, edge.pn2} {
            tp := tempPoints[pointNum].p
            tempPoints[pointNum].p = sumPoint(tp, cp)
            tempPoints[pointNum].n++
        }
    }
    avgMidEdges := make([]Point, len(tempPoints))
    for i, tp := range tempPoints {
        avgMidEdges[i] = divPoint(tp.p, float64(tp.n))
    }
    return avgMidEdges
}

func getPointsFaces(inputPoints []Point, inputFaces []Face) []int {
    numPoints := len(inputPoints)
    pointsFaces := make([]int, numPoints)
    for faceNum := range inputFaces {
        for _, pointNum := range inputFaces[faceNum] {
            pointsFaces[pointNum]++
        }
    }
    return pointsFaces
}

func getNewPoints(inputPoints []Point, pointsFaces []int, avgFacePoints, avgMidEdges []Point) []Point {
    newPoints := make([]Point, len(inputPoints))
    for pointNum := range inputPoints {
        n := float64(pointsFaces[pointNum])
        m1, m2, m3 := (n-3)/n, 1.0/n, 2.0/n
        oldCoords := inputPoints[pointNum]
        p1 := mulPoint(oldCoords, m1)
        afp := avgFacePoints[pointNum]
        p2 := mulPoint(afp, m2)
        ame := avgMidEdges[pointNum]
        p3 := mulPoint(ame, m3)
        p4 := sumPoint(p1, p2)
        newPoints[pointNum] = sumPoint(p4, p3)
    }
    return newPoints
}

func switchNums(pointNums [2]int) [2]int {
    if pointNums[0] < pointNums[1] {
        return pointNums
    }
    return [2]int{pointNums[1], pointNums[0]}
}

func cmcSubdiv(inputPoints []Point, inputFaces []Face) ([]Point, []Face) {
    facePoints := getFacePoints(inputPoints, inputFaces)
    edgesFaces := getEdgesFaces(inputPoints, inputFaces)
    edgePoints := getEdgePoints(inputPoints, edgesFaces, facePoints)
    avgFacePoints := getAvgFacePoints(inputPoints, inputFaces, facePoints)
    avgMidEdges := getAvgMidEdges(inputPoints, edgesFaces)
    pointsFaces := getPointsFaces(inputPoints, inputFaces)
    newPoints := getNewPoints(inputPoints, pointsFaces, avgFacePoints, avgMidEdges)
    var facePointNums []int
    nextPointNum := len(newPoints)
    for _, facePoint := range facePoints {
        newPoints = append(newPoints, facePoint)
        facePointNums = append(facePointNums, nextPointNum)
        nextPointNum++
    }
    edgePointNums := make(map[[2]int]int)
    for edgeNum := range edgesFaces {
        pointNum1 := edgesFaces[edgeNum].pn1
        pointNum2 := edgesFaces[edgeNum].pn2
        edgePoint := edgePoints[edgeNum]
        newPoints = append(newPoints, edgePoint)
        edgePointNums[[2]int{pointNum1, pointNum2}] = nextPointNum
        nextPointNum++
    }
    var newFaces []Face
    for oldFaceNum, oldFace := range inputFaces {
        if len(oldFace) == 4 {
            a, b, c, d := oldFace[0], oldFace[1], oldFace[2], oldFace[3]
            facePointAbcd := facePointNums[oldFaceNum]
            edgePointAb := edgePointNums[switchNums([2]int{a, b})]
            edgePointDa := edgePointNums[switchNums([2]int{d, a})]
            edgePointBc := edgePointNums[switchNums([2]int{b, c})]
            edgePointCd := edgePointNums[switchNums([2]int{c, d})]
            newFaces = append(newFaces, Face{a, edgePointAb, facePointAbcd, edgePointDa})
            newFaces = append(newFaces, Face{b, edgePointBc, facePointAbcd, edgePointAb})
            newFaces = append(newFaces, Face{c, edgePointCd, facePointAbcd, edgePointBc})
            newFaces = append(newFaces, Face{d, edgePointDa, facePointAbcd, edgePointCd})
        }
    }
    return newPoints, newFaces
}

func main() {
    inputPoints := []Point{
        {-1.0, 1.0, 1.0},
        {-1.0, -1.0, 1.0},
        {1.0, -1.0, 1.0},
        {1.0, 1.0, 1.0},
        {1.0, -1.0, -1.0},
        {1.0, 1.0, -1.0},
        {-1.0, -1.0, -1.0},
        {-1.0, 1.0, -1.0},
    }

    inputFaces := []Face{
        {0, 1, 2, 3},
        {3, 2, 4, 5},
        {5, 4, 6, 7},
        {7, 0, 3, 5},
        {7, 6, 1, 0},
        {6, 1, 2, 4},
    }

    outputPoints := make([]Point, len(inputPoints))
    outputFaces := make([]Face, len(inputFaces))
    copy(outputPoints, inputPoints)
    copy(outputFaces, inputFaces)
    iterations := 1
    for i := 0; i < iterations; i++ {
        outputPoints, outputFaces = cmcSubdiv(outputPoints, outputFaces)
    }
    for _, p := range outputPoints {
        fmt.Printf("% .4f\n", p)
    }
    fmt.Println()
    for _, f := range outputFaces {
        fmt.Printf("%2d\n", f)
    }
}


/* Maxima is case sensitive */
a: 1$
A: 2$

is(a = A);
false


"Benjamin" :dog
"Samba" :Dog
"Bernie" :DOG

"There are three dogs named $1, $2, and $3." (dog Dog DOG)=> % print


dog = "Benjamin"
Dog = "Samba"
DOG = "Bernie"

print "There are three dogs named " + dog + ", " + Dog + " and " + DOG


MODULE  dog;

IMPORT  InOut;

TYPE    String          = ARRAY [0..31] OF CHAR;

VAR     dog, Dog, DOG   : String;

(* No compiler error, so the rest is simple  *)

BEGIN
  InOut.WriteString ("Three happy dogs.");
  InOut.WriteLn
END dog.


dog = "Benjamin"
Dog = "Samba"
DOG = "Bernie"

print format("The three dogs are named %s, %s, and %s.\n", dog, Dog, DOG)


def dog = "Benjamin";
def Dog = "Samba";
def DOG = "Bernie";
WriteLine($"The three dogs are named $dog, $Dog, and $DOG");


dog = "Benjamin";
Dog = "Samba";
DOG = "Bernie";
"There is just one dog, named " ++ dog;


int Tx, Ty, X, Y, R;
[SetVid($12);                   \640x480x4 graphics
Tx:= [320, 320-277, 320+277];   \equilateral triangle
Ty:= [0, 479, 479];             \277 = 480 / (2*Sin(60))
X:= Ran(640);                   \random starting point
Y:= Ran(480);
repeat  R:= Ran(3);             \select random triangle point
        X:= (X+Tx(R))/2;        \new point is halfway to it
        Y:= (Y+Ty(R))/2;
        Point(X, Y, 2\green\);  \plot new point
until   KeyHit;
SetVid($03);                    \restore normal text mode
]


width = 640 : height = 480
open window width, height
window origin "lb"

x = ran(width)
y = ran(height)

for i = 1 to 200000
    vertex = int(ran(3))
    if vertex = 1 then
        x = width / 2 + (width / 2 - x) / 2
        y = height - (height - y) / 2
    elseif vertex = 2 then
        x = width - (width - x) / 2
        y = y / 2
    else
        x = x / 2
        y = y / 2
    end if
    color 255 * (vertex = 0), 255 * (vertex = 1), 255 * (vertex = 2)
    dot x, y
next


VREG:	equ	99h	; VDP register port
VR0:	equ	0F3DFh	; Copy of VDP R0 in memory
VR1:	equ	0F3E0h	; Copy of VDP R1 in memory
NEWKEY:	equ	0FBE5h	; MSX BIOS puts key data here
VDP:	equ	98h	; VDP data port
ROM:	equ	0FCC0h	; Main ROM slot
JIFFY:	equ	0FCE9h	; BIOS timer
calslt:	equ	1Ch	; Interslot call routine
initxt:	equ	6Ch	; Switch to default text mode
	org	100h
	ld	bc,(JIFFY)	; Initialize RNG with time
	ld	d,b
	ld	e,c
	exx		; RNG state stored in alternate registers
	di		; Set up the VDP for 256x192 graphics mode
	ld	a,(VR0)	; Get old value of R0
	and	112	; Blank out mode bits
	or	6	; Set high 3 bits = 011(0)
	out	(VREG),a
	ld	a,128	; Store in register 0
	out	(VREG),a
	ld	a,(VR1)	; Get old value of R1
	and	99	; Blank out mode bits
	out	(VREG),a
	ld	a,129	; Low mode bits are 0 so we can just send it
	out	(VREG),a
	ld	a,31	; Bitmap starts at beginning of VRAM
	out	(VREG),a
	ld	a,130
	out	(VREG),a
	xor	a	; Zero out the VRAM - set address to 0
	out	(VREG),a
	ld	a,142
	out	(VREG),a
	xor	a
	out	(VREG),a
	ld	a,64	; Tell VDP to allow writing to VRAM
	out	(VREG),a
	xor	a 	; Write zeroes to the VDP
	ld	c,192	; 2 pixels per byte, meaning 128*192 bytes
zero1:	ld	b,128
zero2:	out	(VDP),a
	djnz	zero2
	dec	c
	jr	nz,zero1
	ei
genX:	call	random	; Generate starting X coordinate
	cp	200
	jr	nc,genX
	ld	b,a	; B = X
genY:	call	random	; Generate starting Y coordinate
	cp	173
	jr	nc,genY
	ld	c,a	; C = Y
step:	call	random	; Get direction
	and	a,3	; Directions {0,1,2}
	cp 	a,3
	jr	z,step
	ld	ixh,a	; Store direction in IXH for color
	dec	a	; Select direction
	jr 	z,d1
	dec	a
	jr	z,d2
	xor	a	; X /= 2
	rr	b
	xor	a	; Y /= 2
	rr	c
	jr	plot
d1:	xor	a	; There's a 16-bit SBC but not a 16-bit SUB
	ld 	hl,100	; (16-bit math or intermediate values won't fit)
	ld	d,a	; DE = X
	ld	e,b
	sbc	hl,de	; 100 - X
	xor	a
	rr	h	; (100 - X) / 2
	rr	l
	ld	e,100	; (100 - X) / 2 + 100
	add	hl,de
	ld	b,l	; -> X
	xor	a
	ld	hl,173	; 173
	ld	e,c
	sbc	hl,de	; (173 - Y)
	rr	h	; (173 - Y) / 2
	rr	l
	ex	de,hl
	ld	l,173
	xor	a
	sbc	hl,de	; 173 - (173-Y)/2
	ld	c,l 	; -> Y
	jr	plot
d2:	xor	a
	rr 	c	; Y /= 2
	xor	a
	ld	hl,200
	ld	d,a	; DE = X
	ld	e,b
	sbc	hl,de	; 200-X
	xor	a
	rr	h	; (200-X)/2
	rr	l
	ex	de,hl
	ld 	l,200
	sbc	hl,de	; 200 - (200-X)/2
	ld	b,l	; -> X
plot:	ld	d,c	; Write address = CB/2
	ld	e,b
	xor	a
	rr	d
	rr	e
	ld	a,d	; First control byte =
	rlca		; high 2 bytes of address
	rlca
	and	3
	ld	h,a	; Keep this value, we'll need it again
	di
	out	(VREG),a
	ld	a,142	; To port 14
	out	(VREG),a
	ld	a,e	; 2nd control byte = low 8 bits
	out	(VREG),a
	ld	a,d	; 3rd control byte = middle 6 bits
	and	63	; Bit 6 off = read
	out	(VREG),a
	nop		; Give it some processing time
	nop
	in	a,(VDP)	; Read the two pixels there
	ld	l,a	; Keep this byte
	ld	a,h	; Now set the VDP to write to that address
	out	(VREG),a
	ld	a,142
	out	(VREG),a
	ld	a,e
	out	(VREG),a
	ld	a,d
	and	63	; Bit 6 on = write
	or	64
	out	(VREG),a
	ld	a,ixh	; Get color
	add	a,12
	ld	d,b	; Left or right pixel?
	rr	d
	jr 	c,wpix
	rlca		; Shift left if X is even
	rlca
	rlca
	rlca
wpix:	or	l	; OR with other pixel in the byte
	out	(VDP),a	; Write byte
	ei
wkey:	ld	a,(NEWKEY+8)
	inc	a	; Check if space key pushed
	jp	z,step	; If not, do another step
	ld	iy,ROM	; Switch back to text mode and quit
	ld	ix,initxt
	jp	calslt
random:	exx		; RNG state stored in alternate registers
	inc	b	; X++
	ld	a,b	; X,
	xor	e	; ^ C,
	xor	c	; ^ A,
	ld	c,a	; -> A
	add	a,d	; + B
	ld	d,a	; -> B
	rra		; >> 1
	xor	c	; ^ A,
	add	a,e	; + C,
	ld	e,a	; -> C
	exx
	ret


{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}

import Data.Array
import Data.Foldable (length, concat, sum)
import Data.List (genericLength)
import Data.Maybe (mapMaybe)
import Prelude hiding (length, concat, sum)
import qualified Data.Map.Strict as Map

{-
A SimpleMesh consists of only vertices and faces that refer to them.
A Mesh extends the SimpleMesh to contain edges as well as references to
adjoining mesh components for each other component, such as a vertex
also contains what faces it belongs to.
An isolated edge can be represented as a degenerate face with 2 vertices.
Faces with 0 or 1 vertices can be thrown out, as they do not contribute to
the result (they can also propagate NaNs).
-}

newtype VertexId = VertexId { getVertexId :: Int } deriving (Ix, Ord, Eq, Show)
newtype EdgeId = EdgeId { getEdgeId :: Int } deriving (Ix, Ord, Eq, Show)
newtype FaceId = FaceId { getFaceId :: Int } deriving (Ix, Ord, Eq, Show)

data Vertex a = Vertex
  { vertexPoint :: a
  , vertexEdges :: [EdgeId]
  , vertexFaces :: [FaceId]
  } deriving Show

data Edge = Edge
  { edgeVertexA :: VertexId
  , edgeVertexB :: VertexId
  , edgeFaces :: [FaceId]
  } deriving Show

data Face = Face
  { faceVertices :: [VertexId]
  , faceEdges :: [EdgeId]
  } deriving Show

type VertexArray a = Array VertexId (Vertex a)
type EdgeArray = Array EdgeId Edge
type FaceArray = Array FaceId Face

data Mesh a = Mesh
  { meshVertices :: VertexArray a
  , meshEdges :: EdgeArray
  , meshFaces :: FaceArray
  } deriving Show

data SimpleVertex a = SimpleVertex { sVertexPoint :: a } deriving Show
data SimpleFace = SimpleFace { sFaceVertices :: [VertexId] } deriving Show

type SimpleVertexArray a = Array VertexId (SimpleVertex a)
type SimpleFaceArray = Array FaceId SimpleFace

data SimpleMesh a = SimpleMesh
  { sMeshVertices :: SimpleVertexArray a
  , sMeshFaces :: SimpleFaceArray
  } deriving Show

-- Generic helpers.
fmap1 :: Functor f => (t -> a -> b) -> (t -> f a) -> t -> f b
fmap1 g h x = fmap (g x) (h x)

aZipWith :: Ix i1 => (a -> b -> e) -> Array i1 a -> Array i b -> Array i1 e
aZipWith f a b = listArray (bounds a) $ zipWith f (elems a) (elems b)

average :: (Foldable f, Fractional a) => f a -> a
average xs = (sum xs) / (fromIntegral $ length xs)

-- Intermediary point types for ultimately converting into a point `a`.
newtype FacePoint a = FacePoint { getFacePoint :: a } deriving Show
newtype EdgeCenterPoint a = EdgeCenterPoint { getEdgeCenterPoint :: a } deriving Show
newtype EdgePoint a = EdgePoint { getEdgePoint :: a } deriving Show
newtype VertexPoint a = VertexPoint { getVertexPoint :: a } deriving Show

type FacePointArray a = Array FaceId (FacePoint a)
type EdgePointArray a = Array EdgeId (EdgePoint a)
type EdgeCenterPointArray a = Array EdgeId (EdgeCenterPoint a)
type IsEdgeHoleArray = Array EdgeId Bool
type VertexPointArray a = Array VertexId (VertexPoint a)

-- Subdivision helpers.
facePoint :: Fractional a => Mesh a -> Face -> FacePoint a
facePoint mesh = FacePoint . average . (fmap $ vertexPointById mesh) . faceVertices

allFacePoints :: Fractional a => Mesh a -> FacePointArray a
allFacePoints = fmap1 facePoint meshFaces

vertexPointById :: Mesh a -> VertexId -> a
vertexPointById mesh = vertexPoint . (meshVertices mesh !)

edgeCenterPoint :: Fractional a => Mesh a -> Edge -> EdgeCenterPoint a
edgeCenterPoint mesh (Edge ea eb _)
  = EdgeCenterPoint . average $ fmap (vertexPointById mesh) [ea, eb]

allEdgeCenterPoints :: Fractional a => Mesh a -> EdgeCenterPointArray a
allEdgeCenterPoints = fmap1 edgeCenterPoint meshEdges

allIsEdgeHoles :: Mesh a -> IsEdgeHoleArray
allIsEdgeHoles = fmap ((< 2) . length . edgeFaces) . meshEdges

edgePoint :: Fractional a => Edge -> FacePointArray a -> EdgeCenterPoint a -> EdgePoint a
edgePoint (Edge _ _ [_]) _ (EdgeCenterPoint ecp) = EdgePoint ecp
edgePoint (Edge _ _ faceIds) facePoints (EdgeCenterPoint ecp)
  = EdgePoint $ average [ecp, average $ fmap (getFacePoint . (facePoints !)) faceIds]

allEdgePoints :: Fractional a => Mesh a -> FacePointArray a -> EdgeCenterPointArray a -> EdgePointArray a
allEdgePoints mesh fps ecps = aZipWith (\e ecp -> edgePoint e fps ecp) (meshEdges mesh) ecps

vertexPoint' :: Fractional a => Vertex a -> FacePointArray a -> EdgeCenterPointArray a -> IsEdgeHoleArray -> VertexPoint a
vertexPoint' vertex facePoints ecps iehs
  | length faceIds == length edgeIds = VertexPoint newCoords
  | otherwise = VertexPoint avgHoleEcps
  where
    newCoords = (oldCoords * m1) + (avgFacePoints * m2) + (avgMidEdges * m3)
    oldCoords = vertexPoint vertex
    avgFacePoints = average $ fmap (getFacePoint . (facePoints !)) faceIds
    avgMidEdges = average $ fmap (getEdgeCenterPoint . (ecps !)) edgeIds
    m1 = (n - 3) / n
    m2 = 1 / n
    m3 = 2 / n
    n = genericLength faceIds
    faceIds = vertexFaces vertex
    edgeIds = vertexEdges vertex
    avgHoleEcps = average . (oldCoords:) . fmap (getEdgeCenterPoint . (ecps !)) $ filter (iehs !) edgeIds

allVertexPoints :: Fractional a => Mesh a -> FacePointArray a -> EdgeCenterPointArray a -> IsEdgeHoleArray -> VertexPointArray a
allVertexPoints mesh fps ecps iehs = fmap (\v -> vertexPoint' v fps ecps iehs) (meshVertices mesh)

-- For each vertex in a face, generate a set of new faces from it with its vertex point,
-- neighbor edge points, and face point. The new faces will refer to vertices in the
-- combined vertex array.
newFaces :: Face -> FaceId -> Int -> Int -> [SimpleFace]
newFaces (Face vertexIds edgeIds) faceId epOffset vpOffset
  = take (genericLength vertexIds)
  $ zipWith3 newFace (cycle vertexIds) (cycle edgeIds) (drop 1 (cycle edgeIds))
  where
    f = VertexId . (+ epOffset) . getEdgeId
    newFace vid epA epB = SimpleFace
      [ VertexId . (+ vpOffset) $ getVertexId vid
      , f epA
      , VertexId $ getFaceId faceId
      , f epB]

subdivide :: Fractional a => SimpleMesh a -> SimpleMesh a
subdivide simpleMesh
  = SimpleMesh combinedVertices (listArray (FaceId 0, FaceId (genericLength faces - 1)) faces)
  where
    mesh = makeComplexMesh simpleMesh
    fps = allFacePoints mesh
    ecps = allEdgeCenterPoints mesh
    eps = allEdgePoints mesh fps ecps
    iehs = allIsEdgeHoles mesh
    vps = allVertexPoints mesh fps ecps iehs
    edgePointOffset = length fps
    vertexPointOffset = edgePointOffset + length eps
    combinedVertices
      = listArray (VertexId 0, VertexId (vertexPointOffset + length vps - 1))
      . fmap SimpleVertex
      $ concat [ fmap getFacePoint $ elems fps
               , fmap getEdgePoint $ elems eps
               , fmap getVertexPoint $ elems vps]
    faces
      = concat $ zipWith (\face fid -> newFaces face fid edgePointOffset vertexPointOffset)
      (elems $ meshFaces mesh) (fmap FaceId [0..])

-- Transform to a Mesh by filling in the missing references and generating edges.
-- Faces can be updated with their edges, but must be ordered.
-- Edge and face order does not matter for vertices.
-- TODO: Discard degenerate faces (ones with 0 to 2 vertices/edges),
-- or we could transform these into single edges or vertices.
makeComplexMesh :: forall a. SimpleMesh a -> Mesh a
makeComplexMesh (SimpleMesh sVertices sFaces) = Mesh vertices edges faces
  where
    makeEdgesFromFace :: SimpleFace -> FaceId -> [Edge]
    makeEdgesFromFace (SimpleFace vertexIds) fid
      = take (genericLength vertexIds)
      $ zipWith (\a b -> Edge a b [fid]) verts (drop 1 verts)
      where
        verts = cycle vertexIds

    edgeKey :: VertexId -> VertexId -> (VertexId, VertexId)
    edgeKey a b = (min a b, max a b)

    sFacesList :: [SimpleFace]
    sFacesList = elems sFaces

    fids :: [FaceId]
    fids = fmap FaceId [0..]

    eids :: [EdgeId]
    eids = fmap EdgeId [0..]

    faceEdges :: [[Edge]]
    faceEdges = zipWith makeEdgesFromFace sFacesList fids

    edgeMap :: Map.Map (VertexId, VertexId) Edge
    edgeMap
      = Map.fromListWith (\(Edge a b fidsA) (Edge _ _ fidsB) -> Edge a b (fidsA ++ fidsB))
      . fmap (\e[email protected](Edge a b _) -> (edgeKey a b, edge))
      $ concat faceEdges

    edges :: EdgeArray
    edges = listArray (EdgeId 0, EdgeId $ (Map.size edgeMap) - 1) $ Map.elems edgeMap

    edgeIdMap :: Map.Map (VertexId, VertexId) EdgeId
    edgeIdMap = Map.fromList $ zipWith (\(Edge a b _) eid -> ((edgeKey a b), eid)) (elems edges) eids

    faceEdgeIds :: [[EdgeId]]
    faceEdgeIds = fmap (mapMaybe (\(Edge a b _) -> Map.lookup (edgeKey a b) edgeIdMap)) faceEdges

    faces :: FaceArray
    faces
      = listArray (FaceId 0, FaceId $ (length sFaces) - 1)
      $ zipWith (\(SimpleFace verts) edgeIds -> Face verts edgeIds) sFacesList faceEdgeIds

    vidsToFids :: Map.Map VertexId [FaceId]
    vidsToFids
      = Map.fromListWith (++)
      . concat
      $ zipWith (\(SimpleFace vertexIds) fid -> fmap (\vid -> (vid, [fid])) vertexIds) sFacesList fids

    vidsToEids :: Map.Map VertexId [EdgeId]
    vidsToEids
      = Map.fromListWith (++)
      . concat
      $ zipWith (\(Edge a b _) eid -> [(a, [eid]), (b, [eid])]) (elems edges) eids

    simpleToComplexVert :: SimpleVertex a -> VertexId -> Vertex a
    simpleToComplexVert (SimpleVertex point) vid
      = Vertex point
      (Map.findWithDefault [] vid vidsToEids)
      (Map.findWithDefault [] vid vidsToFids)

    vertices :: VertexArray a
    vertices
      = listArray (bounds sVertices)
      $ zipWith simpleToComplexVert (elems sVertices) (fmap VertexId [0..])

pShowSimpleMesh :: Show a => SimpleMesh a -> String
pShowSimpleMesh (SimpleMesh vertices faces)
  = "Vertices:\n" ++ (arrShow vertices sVertexPoint)
  ++ "Faces:\n" ++ (arrShow faces (fmap getVertexId . sFaceVertices))
  where
    arrShow a f = concatMap ((++ "\n") . show . (\(i, e) -> (i, f e))) . zip [0 :: Int ..] $ elems a

-- Testing types.
data Point a = Point a a a deriving (Show)

instance Functor Point where
  fmap f (Point x y z) = Point (f x) (f y) (f z)

zipPoint :: (a -> b -> c) -> Point a -> Point b -> Point c
zipPoint f (Point x y z) (Point x' y' z') = Point (f x x') (f y y') (f z z')

instance Num a => Num (Point a) where
  (+) = zipPoint (+)
  (-) = zipPoint (-)
  (*) = zipPoint (*)
  negate = fmap negate
  abs = fmap abs
  signum = fmap signum
  fromInteger i = let i' = fromInteger i in Point i' i' i'

instance Fractional a => Fractional (Point a) where
  recip = fmap recip
  fromRational r = let r' = fromRational r in Point r' r' r'

testCube :: SimpleMesh (Point Double)
testCube = SimpleMesh vertices faces
  where
    vertices = listArray (VertexId 0, VertexId 7)
      $ fmap SimpleVertex
      [ Point (-1) (-1) (-1)
      , Point (-1) (-1) 1
      , Point (-1) 1 (-1)
      , Point (-1) 1 1
      , Point 1 (-1) (-1)
      , Point 1 (-1) 1
      , Point 1 1 (-1)
      , Point 1 1 1]
    faces = listArray (FaceId 0, FaceId 5)
      $ fmap (SimpleFace . (fmap VertexId))
      [ [0, 4, 5, 1]
      , [4, 6, 7, 5]
      , [6, 2, 3, 7]
      , [2, 0, 1, 3]
      , [1, 5, 7, 3]
      , [0, 2, 6, 4]]

testCubeWithHole :: SimpleMesh (Point Double)
testCubeWithHole
  = SimpleMesh (sMeshVertices testCube) (ixmap (FaceId 0, FaceId 4) id (sMeshFaces testCube))

testTriangle :: SimpleMesh (Point Double)
testTriangle = SimpleMesh vertices faces
  where
    vertices = listArray (VertexId 0, VertexId 2)
      $ fmap SimpleVertex
      [ Point 0 0 0
      , Point 0 0 1
      , Point 0 1 0]
    faces = listArray (FaceId 0, FaceId 0)
      $ fmap (SimpleFace . (fmap VertexId))
      [ [0, 1, 2]]

main :: IO ()
main = putStr . pShowSimpleMesh $ subdivide testCube


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

dog = "Benjamin";
Dog = "Samba";
DOG = "Bernie";

if dog == Dog & Dog == DOG & dog == DOG then do
  say 'There is just one dog named' dog'.'
  end
else do
  say 'The three dogs are named' dog',' Dog 'and' DOG'.'
  end

return


var dog, Dog: string
(dog, Dog, DOG) = ("Benjamin", "Samba", "Bernie")

if dog == Dog:
  if dog == DOG:
    echo "There is only one dog, ", DOG)
  else:
    echo "There are two dogs: ", dog, " and ", DOG
elif Dog == DOG :
  echo "There are two dogs: ", dog, " and ", DOG
else:
  echo "There are three dogs:  ", dog, ", ", Dog, " and ", DOG


MODULE CaseSensitivity;
IMPORT
  Out;
VAR
  dog, Dog, DOG: STRING;
BEGIN
  dog := "Benjamin";
  Dog := "Samba";
  DOG := "Bernie";
  Out.Object("The three dogs are named " + dog + ", " + Dog + " and " + DOG);
  Out.Ln
END CaseSensitivity.


class Program {
  function : Main(args : String[]) ~ Nil {
    dog := "Benjamin";
    Dog := "Samba";
    DOG := "Bernie";
    "The three dogs are named {$dog}, {$Dog}, and {$DOG}."->PrintLine();
  }
}


let () =
  let dog = "Benjamin" in
  let dOG = "Samba" in
  let dOg = "Bernie" in
  Printf.printf "The three dogs are named %s, %s and %s.\n" dog dOG dOg


w,h:=640,640;
bitmap:=PPM(w,h,0xFF|FF|FF);  // White background
colors:=T(0xFF|00|00,0x00|FF|00,0x00|00|FF);   // red,green,blue

margin,size:=60, w - 2*margin;
points:=T(T(w/2, margin), T(margin,size), T(margin + size,size) );
N,done:=Atomic.Int(0),Atomic.Bool(False);

Thread.HeartBeat('wrap(hb){  // a thread
   var a=List(-1,-1);

   if(N.inc()<50){
      do(500){
	 colorIndex:=(0).random(3);  // (0..2)
	 b,p:=points[colorIndex], halfwayPoint(a,b);
	 x,y:=p;
	 bitmap[x,y]=colors[colorIndex];
	 a=p;
      }
      bitmap.writeJPGFile("chaosGame.jpg",True);
   }
   else{ hb.cancel(); done.set(); }  // stop thread and signal done
},2).go();     // run every 2 seconds, starting now

fcn halfwayPoint([(ax,ay)], [(bx,by)]){ T((ax + bx)/2, (ay + by)/2) }

done.wait();  // don't exit until thread is done
println("Done");


avg=: +/ % #

havePoints=: e."1/~ [email protected]#

catmullclark=:3 :0
  'mesh points'=. y
  face_point=. avg"2 mesh{points
  point_face=. |: mesh havePoints points
  avg_face_points=. point_face [email protected]#"1 2 face_point
  edges=. ~.,/ meshEdges=. mesh /:[email protected],"+1|."1 mesh
  edge_face=. *./"2 edges e."0 1/ mesh
  edge_center=. avg"2 edges{points
  edge_point=. (0.5*edge_center) + 0.25 * edge_face +/ .* face_point
  point_edge=. |: edges havePoints points
  avg_mid_edges=.  point_edge [email protected]#"1 2 edge_center
  n=. +/"1 point_edge
  'm3 m2 m1'=. (2,1,:n-3)%"1 n
  new_coords=. (m1 * points) + (m2 * avg_face_points) + (m3 * avg_mid_edges)
  pts=. face_point,edge_point,new_coords
  c0=. (#edge_point)+ e0=. #face_point
  msh=. (,c0+mesh),.(,e0+edges i. meshEdges),.((#i.)~/$mesh),.,e0+_1|."1 edges i. meshEdges
  msh;pts
)


using Makie, Statistics

# Point3f0 is a 3-tuple of 32-bit floats for 3-dimensional space, and all Points are 3D.
Point = Point3f0

# a Face is defined by the points that are its vertices, in order.
Face = Vector{Point}

# an Edge is a line segment where the points are sorted
struct Edge
    p1::Point
    p2::Point
    Edge(a, b) = new(min(a, b), max(a, b))
end

edgemidpoint(edge) = (edge.p1  + edge.p2) / 2.0
facesforpoint(p, faces) = [f for f in faces if p in f]
facesforedge(e, faces) = [f for f in faces if (e.p1 in f) && (e.p2 in f)]
nexttohole(edge, faces) = length(facesforedge(edge, faces)) < 2

function newedgepoint(edge, faces)
    f = facesforedge(edge, faces)
    p1, p2, len = edge.p1, edge.p2, length(f)
    if len == 2
        return (p1 + p2 + mean(f[1]) + mean(f[2])) / 4.0
    elseif len == 1
        return (p1 + p2 + mean(f[1])) / 3.0
    end
    return (p1 + p2) / 2.0
end

function edgesforface(face)
    ret, indices = Vector{Edge}(), collect(1:length(face))
    for i in 1:length(face)-1
        push!(ret, Edge(face[indices[1]], face[indices[2]]))
        indices .= circshift(indices, 1)
    end
    ret
end

function edgesforpoint(p, faces)
    f = filter(x -> p in x, faces)
    return filter(e -> p == e.p1 || p == e.p2, mapreduce(edgesforface, vcat, f))
end

function adjacentpoints(point, face)
    a = indexin([point], face)
    if a[1] != nothing
        adjacent = (a[1] == 1) ? [face[end], face[2]] :
            a[1] == length(face) ? [face[end-1], face[1]] :
            [face[a[1] - 1], face[a[1] + 1]]
        return sort(adjacent)
    else
        throw("point $point not in face $face")
    end
end

adjacentedges(point, face) = [Edge(point, x) for x in adjacentpoints(point, face)]
facewrapped(face) = begin f = deepcopy(face); push!(f, f[1]); f end
drawface(face, colr) = lines(facewrapped(face); color=colr)
drawface!(face, colr) = lines!(facewrapped(face); color=colr)
drawfaces!(faces, colr) = for f in faces drawface!(f, colr) end
const colors = [:red, :green, :blue, :gold]

function drawfaces(faces, colr)
    scene = drawface(faces[1], colr)
    if length(faces) > 1
        for f in faces[2:end]
            drawface!(f, colr)
        end
    end
    scene
end

function catmullclarkstep(faces)
    d, E, dprime = Set(reduce(vcat, faces)), Dict{Vector, Point}(), Dict{Point, Point}()
    for face in faces, (i, p) in enumerate(face)
        edge = (p == face[end]) ? Edge(p, face[1]) : Edge(p, face[i + 1])
        E[[edge, face]] = newedgepoint(edge, faces)
    end
    for p in d
        F = mean([mean(face) for face in facesforpoint(p, faces)])
        pe = edgesforpoint(p, faces)
        R = mean(map(edgemidpoint, pe))
        n = length(pe)
        dprime[p] = (F + 2 * R + p * (n - 3)) / n
    end
    newfaces = Vector{Face}()
    for face in faces
        v = mean(face)
        for point in face
            fp1, fp2 = map(x -> E[[x, face]], adjacentedges(point, face))
            push!(newfaces, [fp1, dprime[point], fp2, v])
        end
    end
    return newfaces
end

"""
    catmullclark(faces, iters, scene)

Perform a multistep Catmull-Clark subdivision of a surface. See Wikipedia or page 53
of http://graphics.stanford.edu/courses/cs468-10-fall/LectureSlides/10_Subdivision.pdf
Plots the iterations, with colors for each iteration as set in the colors array.
Uses a Makie Scene of scene to plot the iters iterations.
"""
function catmullclark(faces, iters, scene)
    nextfaces = deepcopy(faces)
    for i in 1:iters
        nextfaces = catmullclarkstep(nextfaces)
        drawfaces!(nextfaces, colors[i])
        display(scene)
        sleep(1)
    end
end

const inputpoints = [
    [-1.0, -1.0, -1.0],
    [-1.0, -1.0, 1.0],
    [-1.0, 1.0, -1.0],
    [-1.0, 1.0, 1.0],
    [1.0, -1.0, -1.0],
    [1.0, -1.0, 1.0],
    [1.0, 1.0, -1.0],
    [1.0, 1.0, 1.0]
]

const inputfaces = [
    [0, 4, 5, 1],
    [4, 6, 7, 5],
    [6, 2, 3, 7],
    [2, 0, 1, 3],
    [1, 5, 7, 3],
    [0, 2, 6, 4]
]

const faces = [map(x -> Point3f0(inputpoints[x]), p .+ 1) for p in inputfaces]

scene = drawfaces(faces, :black)
display(scene)
sleep(1)

catmullclark(faces, 4, scene)

println("Press Enter to continue", readline())


: threeDogs
| dog Dog DOG |

   "Benjamin" ->dog
   "Samba"  ->Dog
   "Bernie" ->DOG

   System.Out "The three dogs are named " << dog << ", " << Dog << " and " << DOG << "." << cr ;


(define dog "Benjamin")
(define Dog "Samba")
(define DOG "Bernie")

(print "The three dogs are named " dog ", " Dog " and " DOG ".\n")


dog="Benjamin";
Dog="Samba";
DOG="Bernie";
printf("The three dogs are named %s, %s, and %s.", dog, Dog, DOG)


# These variables are all different
$dog='Benjamin';
$Dog='Samba';
$DOG='Bernie';
print "The three dogs are named $dog, $Dog, and $DOG \n"


sequence dog = "Benjamin",
         Dog = "Samba",
         DOG = "Bernie"
printf( 1, "The three dogs are named %s, %s and %s\n", {dog, Dog, DOG} )