#include #include #include #include #define FRC_NO_ICU 1 #include "FRC.h" #include "path.h" #include "keyboard.h" constexpr static unsigned char code(char c) { return static_cast(c)-'a'; } constexpr static char key(unsigned char c) { return static_cast(c+'a'); } phenotype keymap(std::string d) { return build( d.begin(), d.end(), &code ); } std::string keymap(phenotype d) { return build( d.begin(), d.end(), &key ); } sKeymap::sKeymap(pcg32_k64& r) { unsigned char s = r(126); auto spaces = space_maps[s]; auto p = buildiota>(code('a'), 1); std::shuffle(p.begin(), p.end(), r); for (unsigned j = 0, i = 0; i < keys.size(); ++i) { if (spaces[i]) { keys[i] = code(' '); } else { keys[i] = p[j++]; } } fixGenome(); } sKeymap sKeymap::mutate_fast(int divergence, pcg32_k64& r) const { auto tmp = keys; for (auto n = divergence; n; --n) { std::swap(tmp[r(tmp.size())], tmp[r(tmp.size())]); } return {tmp}; } sKeymap sKeymap::mutate_slow(int divergence, pcg32_k64& r) const { auto tmp = keys; for (auto n = divergence; n; --n) { int sel = r(tmp.size()), sel2; std::array offsets { -(rowlen-1), -rowlen, -(rowlen+1), -1, 1, rowlen-1, rowlen, rowlen+1 }; //Simple advancing shuffler //Not necessarily the most efficient, but it provides // early breakout //Selects a random (existing) neighbor of the chosen key for (unsigned i = 0; i < offsets.size()-1; ++i) { unsigned j = r(offsets.size()-i)+i; if (j != i) { // std::cerr<<"mutate_slow: moving offset["<= 0 && sel2 < static_cast(tmp.size())) { std::swap(tmp[sel], tmp[sel2]); break; } } } return {tmp}; } void printChromosome(chromosome& g) { for (auto& i : g.second) { std::cout<<+i<<" "; } std::cout<4) { auto sel = r(25); // std::clog<<"["< mutators = {1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 2, -2, 2, -2, 2, -2, 2, -2, 2, -2, 3, -3, 3, -3, 4, -4}; auto m = mutators[r(mutators.size())]; tmp.second[sel] = ( tmp.second[sel] + m ) % (tmp.second.size() - sel); // std::clog<<" into "<<+tmp.second[sel]< s = spaceTable[tmp.first]; unsigned sel1 = r(9), sel2 = r(9); while (sel2 == sel1 || s[sel1] == s[sel2]) { sel2 = r(9); } bool b = s[sel1]; s[sel1] = s[sel2]; s[sel2] = b; tmp.first = find_in(spaceTable, s.to_ulong()); // std::clog<<" into "<<+tmp.first< p1_b = std::bitset<9>(spaceTable[first.genome.first]), p2_b = std::bitset<9>(spaceTable[second.genome.first]), c = p1_b & p2_b, t = p1_b ^ p2_b; int d = t.count()/2; while (d) { auto s = r(9); if (t[s]) { c.set(s); t.reset(s); --d; } } tmp.first = find_in(spaceTable, c.to_ulong()); return {tmp}; } phenotype keysFromGenome(chromosome g) { phenotype p; auto spaces = space_maps[g.first]; auto symbols = buildiota>(26, code('a')); auto pop = [](std::vector& v, size_t index) { auto r = v.at(index); // std::cout<<"popping "< spaces; chromosome g; for (unsigned j = 0, i = 0; i < k.size(); ++i) { if (k[i] == code(' ')) { spaces[i] = true; } else { spaces[i] = false; g.second[j++] = k[i]; } } g.first = find_in(space_maps, spaces); for (unsigned i = 0; i < g.second.size(); ++i) { for (unsigned j = i+1; j < g.second.size(); ++j) { if (g.second[j] > g.second[i]) { --g.second[j]; } } } return g; }