     [c1, c2]
   , 'probability', value: probability
 
-  exchange = (c1, c2, pos)->
-    temp = c1[pos]; c1[pos] = c2[pos]; c2[pos] = temp
+  exchange = (array1, array2, p)->
+    temp = array1[p]
+    array1[p] = array2[p]
+    array2[p] = temp
+    undefined
 
 
   # Order crossover operation
-  @OX: @order = (n = 2)-> Object.defineProperty(
+  @OX: @order = (n)-> withRotation n, (c1, c2, p)->
+    (o = c1[...p]).push (utils.reject c2, o)...
+    o
+
+
+  withRotation = (n = 2, operator)-> Object.defineProperty(
     if 1 <= n <= 2
       (c1, c2)->
-        r = randomLocusOf c1 if n == 2
-        [c1, c2] = rotate c1, c2, r
+        if n == 2 and r = randomLocusOf c1
+          c1 = utils.rotate c1, r
+          c2 = utils.rotate c2, r
         p = randomLocusOf c1
-        o1 = order c1, c2, p
-        o2 = order c2, c1, p
-        rotate o1, o2, -r
+        o1 = operator c1, c2, p
+        o2 = operator c2, c1, p
+        if r
+          o1 = utils.rotate o1, -r
+          o2 = utils.rotate o2, -r
+        [o1, o2]
     else
       throw new Error "invalid number of crossover point: #{n}"
   , 'n', value: n)
-
-  order = (c1, c2, p)->
-    (o = c1[...p]).push (reject c2, o)...
-    o
-
-  reject = (array, excepts)->
-    array.filter (e)-> (excepts.indexOf e) < 0
-
-  rotate = (c1, c2, p)->
-    if p
-      c1 = c1[p...].concat c1[...p]
-      c2 = c2[p...].concat c2[...p]
-    [c1, c2]
 
 
   # Cycle crossover operation

# http://opensource.org/licenses/mit-license.php
###

{randomInt} = require './utils'

class CrossoverOperator
  randomLocusOf = (c)-> randomInt c.length

  # N point crossover operation
  @point: (n = 1)-> Object.defineProperty(

        o2[p] = c2[p]
        p = c1.indexOf c2[p]
        throw new Error 'Invalid chromosome for cyclic crossover' if p < 0
      break if o1.length == length == utils.count o1
      p++ while o1[p]
      p = 0 if p == length
      [c1, c2] = [c2, c1]
    [o1, o2]


  # Partially-mapped crossover operation
  @PMX: (n)-> withRotation n, (c1, c2, p)->
    o = c1[...p]
    for q in [p..c1.length - 1]
      o[q] ?= do ->
        while utils.contains o, (g = c2[q])
          q = c1.indexOf g
        g
    o

