I'm starting to learn Clojure and as an exercise I've implemented the following functions (written in Java) in Clojure:
private int[] SwapValues(int val1, int val2, int[] array) {
int[] result = new int[array.length];
for (int i = 0; i < array.length; i++) {
if (array[i] == val1) {
result[i] = val2;
} else if(array[i] == val2) {
result[i] = val1;
} else {
result[i] = array[i];
}
}
return result;
}
public int[][] PartialCross(int[] subject1, int[] subject2, final int begin, final int end) {
int[][] result = new int[2][subject1.length];
int[] child1 = subject1.clone();
int[] child2 = subject2.clone();
for (int i = begin; i < end; i++) {
child1 = SwapValues(subject1[i], subject2[i], child1);
child2 = SwapValues(subject1[i], subject2[i], child2);
}
result[0] = child1;
result[1] = child2;
return result;
}
My result is:
(def chromosone1 [5 8 1 7 6 4 9 3 2])
(def chromosone2 [5 3 2 6 1 8 7 4 9])
(defn extract [input i j]
(filter #(not (nil? %1))
(map-indexed #(if (and (>= %1 i) (< %1 j)) %2) input)))
(defn chrossover-swap [input i]
(let [i1 (first i)
i2 (last i)]
(map #(cond
(= %1 i1) i2
(= %1 i2) i1
:else %1) input)))
(defn crossover [input1 input2]
(let [i1 (extract input1 3 5)
i2 (extract input2 3 5)
i3 (partition 2 (interleave i1 i2))]
(loop [to-swap i3
o1 input1
o2 input2]
(if (zero? (count to-swap))
[o1 o2]
(do
(def i (first to-swap))
(recur (rest to-swap) (chrossover-swap o1 i) (chrossover-swap o2 i)))))))
(print (crossover chromosone1 chromosone2))
The code works, but I may have made it more complicated than it needs to be. I'm a beginner in functional programming and would like to know if this could be written in a simpler or more efficient way.