You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
2.9KB

  1. // Bjorklunds algorithm for euclidean sequnces
  2. //
  3. // Modified GIST from https://gist.github.com/unohee/d4f32b3222b42de84a5f
  4. #include<iostream>
  5. #include<vector>
  6. #include<algorithm>
  7. struct Bjorklund
  8. {
  9. Bjorklund() { };
  10. Bjorklund(int step, int pulse) : lengthOfSeq(step), pulseAmt(pulse) {};
  11. ~Bjorklund() {
  12. reset();
  13. };
  14. void reset() {
  15. remainder.clear();
  16. count.clear();
  17. sequence.clear();
  18. };
  19. std::vector<int> remainder;
  20. std::vector<int> count;
  21. std::vector<bool> sequence;
  22. int lengthOfSeq;
  23. int pulseAmt;
  24. void init(int step, int pulse) {
  25. lengthOfSeq = step;
  26. pulseAmt = pulse;
  27. }
  28. int getSequence(int index) { return sequence.at(index); };
  29. int size() { return (int)sequence.size(); };
  30. void iter() {
  31. //\Bjorklund algorithm
  32. //\do E[k,n]. k is number of one's in sequence, and n is the length of sequence.
  33. int divisor = lengthOfSeq - pulseAmt; //initial amount of zero's
  34. remainder.push_back(pulseAmt);
  35. //iteration
  36. int index = 0; //we start algorithm from first index.
  37. while (true) {
  38. count.push_back(std::floor(divisor / remainder[index]));
  39. remainder.push_back(divisor % remainder[index]);
  40. divisor = remainder.at(index);
  41. index += 1; //move to next step.
  42. if (remainder[index] <= 1) {
  43. break;
  44. }
  45. }
  46. count.push_back(divisor);
  47. buildSeq(index); //place one's and zero's
  48. reverse(sequence.begin(), sequence.end());
  49. //position correction. some of result of algorithm is one step rotated.
  50. int zeroCount = 0;
  51. if (sequence.at(0) != 1) {
  52. do {
  53. zeroCount++;
  54. } while (sequence.at(zeroCount) == 0);
  55. std::rotate(sequence.begin(), sequence.begin() + zeroCount, sequence.end());
  56. }
  57. }
  58. void buildSeq(int slot) {
  59. //construct a binary sequence of n bits with k one’s, such that the k one’s are distributed as evenly as possible among the zero’s
  60. if (slot == -1) {
  61. sequence.push_back(0);
  62. } else if (slot == -2) {
  63. sequence.push_back(1);
  64. }
  65. else {
  66. for (int i = 0; i < count[slot]; i++)
  67. buildSeq(slot - 1);
  68. if (remainder[slot] != 0)
  69. buildSeq(slot - 2);
  70. }
  71. }
  72. /*
  73. void pad(int p) {
  74. for (int i=0; i<p; i++) {
  75. sequence.push_back(0);
  76. }
  77. }
  78. void rotater(int r) {
  79. for (int i=0; i<r; i++) {
  80. std::rotate(sequence.rbegin(),sequence.rbegin() + 1,sequence.rend());
  81. }
  82. }
  83. */
  84. void print() {
  85. for (unsigned int i = 0; i != sequence.size(); i++) {
  86. std::cout << sequence.at(i);
  87. }
  88. std::cout << '\n';
  89. //std::cout << "Size : " << sequence.size() << '\n';
  90. }
  91. };