<commit_before>#include <random>
#include <chrono>
#include <algorithm>
#include <sstream>
#include "NPointCrossover.h"

using namespace std;

NPointCrossover::NPointCrossover(int newNumPoints) : CrossoverOperation() {
	numPoints = newNumPoints;
}

NPointCrossover::NPointCrossover(int newNumPoints, unsigned newSeed) : CrossoverOperation(newSeed) {
	numPoints = newNumPoints;
}

int ** NPointCrossover::crossOver(int firstGenome[], int secondGenome[], int firstGenomeLength, int secondGenomeLength) {
	int points[numPoints];
	int shortestGenome;

	if (firstGenomeLength > secondGenomeLength) {
		shortestGenome = secondGenomeLength;
	} else {
		shortestGenome = firstGenomeLength;
	}

	//We're generating two children - each one uses the same crossover
	//points, but draws from the parents in a different order
	int ** children = (int**)malloc(sizeof(int*)*2);

	children[0] = (int*)malloc(sizeof(int)*shortestGenome);
	children[1] = (int*)malloc(sizeof(int)*shortestGenome);

	uniform_int_distribution<int> distribution(0, firstGenomeLength);

	//Generate the points - duplicates will be taken care of later
	for (int i = 0; i < numPoints; i++) {
		points[i] = distribution(generator);
	}

	//Sort the points
	sort(points, points+numPoints);

	//Replace the duplicate points with -1 (which would never appear as a
	//valid point)
	for (int i = 0; i < numPoints-1; i++) {
		if (points[i+1] == points[i]) {
			for (int k = i+1; k < numPoints && points[k] == points[i]; k++) {
				points[k] = -1;
			}
		}
	}

	int currentPoint = 0;
	bool firstOrSecond = false; //false = first, true = second

	for (int i = 0; i < shortestGenome; i++) {
		if (i == points[currentPoint]) {
			firstOrSecond = !firstOrSecond;
			currentPoint += 1;
		} else {
			for (; points[currentPoint] == -1; currentPoint++);
		}

		if (firstOrSecond == true) {
			children[0][i] = firstGenome[i];
			children[1][i] = secondGenome[i];
		} else {
			children[1][i] = firstGenome[i];
			children[0][i] = secondGenome[i];
		}
	}

	return children;
}

string NPointCrossover::toString() {
	string returnString = "";
	stringstream ss;

	ss << "Type: N-Point Crossover\nRandom Seed: " << seed << "\nNumber of points: " << numPoints << "\n";

	returnString = ss.str();

	return returnString;
}
<commit_msg>[N-Point Crossover]: Fixed potential segfault<commit_after>#include <random>
#include <chrono>
#include <algorithm>
#include <sstream>
#include "NPointCrossover.h"

using namespace std;

NPointCrossover::NPointCrossover(int newNumPoints) : CrossoverOperation() {
	numPoints = newNumPoints;
}

NPointCrossover::NPointCrossover(int newNumPoints, unsigned newSeed) : CrossoverOperation(newSeed) {
	numPoints = newNumPoints;
}

int ** NPointCrossover::crossOver(int firstGenome[], int secondGenome[], int firstGenomeLength, int secondGenomeLength) {
	int points[numPoints];
	int shortestGenome;

	if (firstGenomeLength > secondGenomeLength) {
		shortestGenome = secondGenomeLength;
	} else {
		shortestGenome = firstGenomeLength;
	}

	//We're generating two children - each one uses the same crossover
	//points, but draws from the parents in a different order
	int ** children = (int**)malloc(sizeof(int*)*2);

	children[0] = (int*)malloc(sizeof(int)*shortestGenome);
	children[1] = (int*)malloc(sizeof(int)*shortestGenome);

	uniform_int_distribution<int> distribution(0, firstGenomeLength);

	//Generate the points - duplicates will be taken care of later
	for (int i = 0; i < numPoints; i++) {
		points[i] = distribution(generator);
	}

	//Sort the points
	sort(points, points+numPoints);

	//Replace the duplicate points with -1 (which would never appear as a
	//valid point)
	for (int i = 0; i < numPoints-1; i++) {
		if (points[i+1] == points[i]) {
			for (int k = i+1; k < numPoints && points[k] == points[i]; k++) {
				points[k] = -1;
			}
		}
	}

	int currentPoint = 0;
	bool firstOrSecond = false; //false = first, true = second

	for (int i = 0; i < shortestGenome; i++) {
		if (currentPoint < numPoints) {
			if (i == points[currentPoint]) {
				firstOrSecond = !firstOrSecond;
				currentPoint += 1;
			} else {
				for (; currentPoint < numPoints && points[currentPoint] == -1; currentPoint++);
			}
		}

		if (firstOrSecond == true) {
			children[0][i] = firstGenome[i];
			children[1][i] = secondGenome[i];
		} else {
			children[1][i] = firstGenome[i];
			children[0][i] = secondGenome[i];
		}
	}

	return children;
}

string NPointCrossover::toString() {
	string returnString = "";
	stringstream ss;

	ss << "Type: N-Point Crossover\nRandom Seed: " << seed << "\nNumber of points: " << numPoints << "\n";

	returnString = ss.str();

	return returnString;
}

{'fraction_non_alphanumeric': 0.14562688496337786, 'fraction_numerical': 0.008186126669538992, 'mean_word_length': 4.488179669030733, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2472484', 'n_tokens_mistral': 1733, 'n_tokens_neox': 1573, 'n_words': 407}