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 0
s at its length.
1@⎕⊢
- take c and change the 0
s to 1
s 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 0
s and bs on 1
s.