.PS
# samplesort.pic
# Slightly modified from an example by Duncan Simpson

define boxen
{
  box sprintf("$2%g",0)
  { for i=1 to $1-1 do {
      move to last box .s
      move down
      box sprintf("$2%g",i) }
  } 
}

define splarrow
{
  { if ($1 .y < $2 .y) then {
      spline -> from $1 .ne to $2 .sw-(dist,dist) to $2 .sw } \
    else { if ($1 .y > $2 .y) then {
      spline -> from $1 .se to $2 .nw+(-dist,dist) to $2 .nw } \
    else { arrow from $1.e to $2.w } }
  }
}
	
define inarrows
{
  for i=$3 to $1+$3-1 do { splarrow({i}th last box, $2) }
}

define outarrows
{
  for i=1 to $1 do { splarrow($2, {i}th last box) }
}


define merge_pattern
{
  for i=1 to $1 do {
    for j=1 to $1 do { splarrow({j+$1}th last box,{i}th last box) } }
}

define bypass
{
  { move to $1 .n
    line up $3
    TL: arc up cw
    move to $2 .n
    line <- up $3
    TR: arc up
    line from TL .end to TR .end
  }
}

define sample
{
  oscale=scale
  natwidth=8.200
  scale=$2/natwidth*scale
  textht = textht*scale
  ellipsewid = ellipsewid*1.5
# boxwid = boxwid*1.2
  dist=0.2*scale
  [ 
    left
    line <-
    move left 0.5 "nums "
    right
    G: ellipse "generate" fill $3 with .w at last line .start
    move
    boxen($1,sort)
    outarrows($1, G)
    move
    S: box "sample"
    inarrows($1, S, 2)
    arrow
    boxen($1,split)
    outarrows($1,S)
    { for i=1 to $1-1 do {
        arrow from {i+$1+1}th last box .e to {i}th last box .w }
    } 
    bypass({$1+$1+1}th last box, {$1}th last box, 0.25*scale)
    move right 1.2*scale
    boxen($1,merge)
    merge_pattern($1)
    move
    O: ellipse "output" fill $3
    inarrows($1, O, 1)
    bypass(G, O, 0.5*scale)
  ]
  scale=oscale
}

sample(3, 6.6, 1-0.3)
.PE 
