fork download
  1. #include <iostream>
  2. #include <string>
  3.  
  4. //
  5. // a class for computing the n-bit sequences with no adjacent 1's
  6. //
  7. // Approach taken was to search the entire solution space for all n-bit
  8. // sequences that satisfy the criteria
  9. // An small optimization was made to prune the solution space by not checking
  10. // the lower bits of a sequence if
  11. // an adjacent pair of 1's is found in the higher bits.
  12. //
  13. class NBitSequenceTest
  14. {
  15. public:
  16. //
  17. // constructor takes the number of bits in the sequence
  18. //
  19. NBitSequenceTest(unsigned int n);
  20.  
  21. //
  22. // outputs all n bit sequences with no consecutive 1's to standard output.
  23. // returns the number of sequences found.
  24. //
  25. unsigned int Evaluate() const;
  26.  
  27. private:
  28.  
  29. //
  30. // returns the position of the least significant bit of the pair of
  31. // adjacent 1's in the number. returns -1 if there are no adjacent 1s
  32. // in the bit pattern.
  33. //
  34. int hasAdjacentBitSetAtPosition(unsigned int number) const;
  35.  
  36. //
  37. // helper function for numberToBinaryString tests if a bit at a certain position is set.
  38. //
  39. bool isBitSet(unsigned int number, unsigned int nBit) const;
  40.  
  41. //
  42. // outputs the input number as a string in binary format
  43. //
  44. std::string numberToBinaryString(unsigned int number) const;
  45.  
  46. //
  47. // store the number of bits in the sequence
  48. //
  49. unsigned int m_nDigits;
  50.  
  51. };
  52.  
  53. inline bool NBitSequenceTest::isBitSet(unsigned int number, unsigned int nBit) const
  54. {
  55. return (number & 1 << nBit) != 0;
  56. }
  57.  
  58. NBitSequenceTest::NBitSequenceTest(unsigned int n) : m_nDigits(n)
  59. {}
  60.  
  61. std::string NBitSequenceTest::numberToBinaryString(unsigned int number) const
  62. {
  63. std::string strBinary(m_nDigits, '0');
  64. int bitPos = 0;
  65. for (std::string::reverse_iterator i = strBinary.rbegin(); i != strBinary.rend(); i++)
  66. {
  67. if (isBitSet(number,bitPos++))
  68. *i = '1';
  69. }
  70.  
  71. return strBinary;
  72. }
  73.  
  74. int NBitSequenceTest::hasAdjacentBitSetAtPosition(unsigned int number) const
  75. {
  76. //
  77. // our minimum condition is 2 adjacent bits set,
  78. // so our test will loop through the bits looking for this pattern
  79. //
  80. const unsigned int twoBits = 1 | 1 << 1;
  81. int pos = -1;
  82. bool bStopChecking = false;
  83. for (unsigned int i = 0; i < (m_nDigits - 1) && !bStopChecking; i++)
  84. {
  85. unsigned int currentMask = twoBits << i;
  86. if ((number & currentMask) == currentMask)
  87. {
  88. pos = i;
  89. bStopChecking = true;
  90. }
  91. else if (number < currentMask)
  92. {
  93. //
  94. // no point chekcing any further as the bits will all be zero
  95. //
  96. bStopChecking = true;
  97. }
  98. }
  99.  
  100. return pos;
  101. }
  102.  
  103. unsigned int NBitSequenceTest::Evaluate() const
  104. {
  105. const unsigned int upperBound = (1 << m_nDigits);
  106. unsigned int i = 0;
  107. unsigned int count = 0;
  108. do
  109. {
  110. int posBitPair = hasAdjacentBitSetAtPosition(i);
  111. if (posBitPair < 0)
  112. {
  113. std::cout << numberToBinaryString(i++) << std::endl;
  114. count++;
  115. }
  116. else
  117. {
  118. //
  119. // optimization... if we found a pair of adjacent bits they will remain set
  120. // until the lsb of the bit pair flips back to zero when the remaining lower
  121. // significant bits overflow and reset
  122. // back to all zeros. so we can skip these candidates
  123. //
  124. i += (1 << posBitPair);
  125. }
  126.  
  127. } while (i < upperBound);
  128.  
  129. return count;
  130. }
  131.  
  132.  
  133. int main() {
  134. int n;
  135. std::cin >> n;
  136.  
  137. NBitSequenceTest b(n);
  138.  
  139. std::cout << b.Evaluate() << " results found" << std::endl;
  140. }
Success #stdin #stdout 0s 3464KB
stdin
10
stdout
0000000000
0000000001
0000000010
0000000100
0000000101
0000001000
0000001001
0000001010
0000010000
0000010001
0000010010
0000010100
0000010101
0000100000
0000100001
0000100010
0000100100
0000100101
0000101000
0000101001
0000101010
0001000000
0001000001
0001000010
0001000100
0001000101
0001001000
0001001001
0001001010
0001010000
0001010001
0001010010
0001010100
0001010101
0010000000
0010000001
0010000010
0010000100
0010000101
0010001000
0010001001
0010001010
0010010000
0010010001
0010010010
0010010100
0010010101
0010100000
0010100001
0010100010
0010100100
0010100101
0010101000
0010101001
0010101010
0100000000
0100000001
0100000010
0100000100
0100000101
0100001000
0100001001
0100001010
0100010000
0100010001
0100010010
0100010100
0100010101
0100100000
0100100001
0100100010
0100100100
0100100101
0100101000
0100101001
0100101010
0101000000
0101000001
0101000010
0101000100
0101000101
0101001000
0101001001
0101001010
0101010000
0101010001
0101010010
0101010100
0101010101
1000000000
1000000001
1000000010
1000000100
1000000101
1000001000
1000001001
1000001010
1000010000
1000010001
1000010010
1000010100
1000010101
1000100000
1000100001
1000100010
1000100100
1000100101
1000101000
1000101001
1000101010
1001000000
1001000001
1001000010
1001000100
1001000101
1001001000
1001001001
1001001010
1001010000
1001010001
1001010010
1001010100
1001010101
1010000000
1010000001
1010000010
1010000100
1010000101
1010001000
1010001001
1010001010
1010010000
1010010001
1010010010
1010010100
1010010101
1010100000
1010100001
1010100010
1010100100
1010100101
1010101000
1010101001
1010101010
144 results found