<commit_before>#include "genome.h"
#include <vector>
#include <algorithm>

Genome::Genome(const TrainingParameters& parameters) :
	parameters(parameters),
	genes(parameters.numberOfInputs * parameters.numberOfOutputs)
{
	auto *currentGene = &genes.front();
	for (auto in = 0U; in < parameters.numberOfInputs; ++in) {
		for (auto out = 0U; out < parameters.numberOfOutputs; ++out) {
			currentGene->from = in;
			currentGene->to = out + parameters.numberOfInputs;
			++currentGene;
		}
	}
}

std::size_t Genome::ExtrapolateNeuronCount() const {
	auto CompareToNeuron = [](const Gene& lhs, const Gene& rhs) {
		return lhs.to < rhs.to;
	};
	auto maxNeuronGene = std::max_element(genes.begin(), genes.end(), CompareToNeuron);
	// TODO jnf Maybe add lookup table
	return maxNeuronGene->to + 1U;
}

std::size_t Genome::GetGeneCount() const {
	return genes.size();
}

Genome& Genome::operator=(const Genome& other)
{
	this->genes = other.genes; 
	const_cast<TrainingParameters&>(this->parameters) = other.parameters;
	return *this;
}

void Genome::MutateGenes() {
	if (ShouldAddConnection()) {
		AddRandomConnection();
	}
	else
	if (ShouldAddNeuron()) {
		AddRandomNeuron();
	}
	else {
		ShuffleWeights();
	}
}

bool Genome::DidChanceOccure(float chance)
{
	auto num = rand() % 100;
	return num < int(100.0f * chance);
}

void Genome::AddRandomNeuron()
{
	Gene* randGene = nullptr;
	do {
		int num = rand() % genes.size();
		randGene = &genes[num];
	} while (!randGene->isEnabled);

	auto numberOfNeurons = ExtrapolateNeuronCount();

	Gene g1(*randGene);
	g1.to = numberOfNeurons;
	genes.push_back(std::move(g1));

	Gene g2(*randGene);
	g2.from = numberOfNeurons;
	genes.push_back(std::move(g2));

	randGene->isEnabled = false;
}

void Genome::AddRandomConnection()
{
	auto GetRandomNumberBetween = [](size_t min, size_t max) {
		return rand() % (max - min) + min;
	};

	Gene newConnection;
	auto highestNeuronIndex = ExtrapolateNeuronCount() - 1U;

	newConnection.from = GetRandomNumberBetween(0U, highestNeuronIndex - 1U);
	newConnection.to = GetRandomNumberBetween(newConnection.from + 1, highestNeuronIndex);

	genes.push_back(newConnection);
}<commit_msg>Worked on Issue #2. The neuron has stopped being complete garbage<commit_after>#include "genome.h"
#include <vector>
#include <algorithm>

Genome::Genome(const TrainingParameters& parameters) :
	parameters(parameters),
	genes(parameters.numberOfInputs * parameters.numberOfOutputs)
{
	auto *currentGene = &genes.front();
	for (auto in = 0U; in < parameters.numberOfInputs; ++in) {
		for (auto out = 0U; out < parameters.numberOfOutputs; ++out) {
			currentGene->from = in;
			currentGene->to = out + parameters.numberOfInputs;
			++currentGene;
		}
	}
}

std::size_t Genome::ExtrapolateNeuronCount() const {
	auto CompareToNeuron = [](const Gene& lhs, const Gene& rhs) {
		return lhs.to < rhs.to;
	};
	auto maxNeuronGene = std::max_element(genes.begin(), genes.end(), CompareToNeuron);
	// TODO jnf Maybe add lookup table
	return maxNeuronGene->to + 1U;
}

std::size_t Genome::GetGeneCount() const {
	return genes.size();
}

Genome& Genome::operator=(const Genome& other)
{
	this->genes = other.genes; 
	const_cast<TrainingParameters&>(this->parameters) = other.parameters;
	return *this;
}

void Genome::MutateGenes() {
	if (ShouldAddConnection()) {
		AddRandomConnection();
	}
	else
	if (ShouldAddNeuron()) {
		AddRandomNeuron();
	}
	else {
		ShuffleWeights();
	}
}

bool Genome::DidChanceOccure(float chance)
{
	auto num = rand() % 100;
	return num < int(100.0f * chance);
}

void Genome::AddRandomNeuron()
{
	Gene* randGene = nullptr;
	do {
		int num = rand() % genes.size();
		randGene = &genes[num];
	} while (!randGene->isEnabled);

	auto indexOfNewNeuron = ExtrapolateNeuronCount();

	Gene g1;
    g1.from = randGene->from;
	g1.to = indexOfNewNeuron;

	Gene g2;
	g2.from = indexOfNewNeuron;
    g2.to = randGene->to;

	randGene->isEnabled = false;
	genes.push_back(std::move(g1));
	genes.push_back(std::move(g2));
}

void Genome::AddRandomConnection()
{
	auto GetRandomNumberBetween = [](size_t min, size_t max) {
		return rand() % (max - min) + min;
	};

	Gene newConnection;
	auto highestNeuronIndex = ExtrapolateNeuronCount() - 1U;

	newConnection.from = GetRandomNumberBetween(0U, highestNeuronIndex - 1U);
	newConnection.to = GetRandomNumberBetween(newConnection.from + 1, highestNeuronIndex);

	genes.push_back(newConnection);
}
{'fraction_non_alphanumeric': 0.14425483503981798, 'fraction_numerical': 0.009783845278725825, 'mean_word_length': 5.071823204419889, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 25, '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': '3698363', 'n_tokens_mistral': 1718, 'n_tokens_neox': 1536, 'n_words': 328}