Running gene crossover algorithm

JavaScript (ES6), 47 45 bytes

Saved 2 bytes thanks to @ETHproductions

Takes input as a triplet [a, b, c] where a and b are the gene sequences and c is the list of 0-indexed cross-points.

x=>x[i=j=0].map(_=>x[(j+=x[2][j]==i)&1][i++])

Try it online!

Commented

x =>                    // given x = [ geneSeqA, geneSeqB, crossPoints ]
  x[i = j = 0]          // initialize i = gene sequence pointer and j = cross point pointer
  .map(_ =>             // for each value in the first gene sequence:
    x[(                 //   access x[]
      j += x[2][j] == i //     increment j if i is equal to the next cross point
    ) & 1]              //   access either x[0] or x[1] according to the parity of j
    [i++]               //   read gene at x[0][i] or x[1][i]; increment i
  )                     // end of map()

Haskell, 58 53 51 45 bytes

(fst.).foldl(\(a,b)p->(take p a++drop p b,a))

The two gene sequences are taken as a pair of lists and the cross points as a second argument.

Try it online!

foldl           -- fold the pair of genes into the list of
                -- cross points and on each step
    \(a,b) p -> -- let the pair of genes be (a,b) and the next cross point 'p'
      (take p a++drop p b,a)  
                -- let 'b' the new first element of the pair, but
                --   drop the first 'p' elements and 
                --   prepend the first 'p' elements of 'a'
                -- let 'a' the new second element 
fst             -- when finished, return the first gene   

APL (Dyalog 16.0), 26 bytes

+/a⎕×(~,⊢)⊂≠\d←1@⎕⊢0⍴⍨≢a←⎕

Try it online!

Input is a, c, then b. c is 1 indexed.

How?

a←⎕ - get a.

0⍴⍨≢ - create array of 0s at its length.

1@⎕⊢ - take c and change the 0s to 1s on the indices.

d← - assign to d.

⊂≠\d - expand d with xor to create the selection sequence (0 for a, 1 for b), and enclose.

(~,⊢) - take d and its inverse.

a⎕× - and multiply respectively with inputted b and a.

+/ - sum each pair of elements, yielding the as on 0s and bs on 1s.