+def shifted_ints(total_bits, int_bits):
+ """ Generate a sequence like a generalized binary version of A037124.
+
+ See https://oeis.org/A037124
+
+ Generates the sequence of all non-negative integers ``n`` in ascending
+ order with no repeats where ``n < (1 << total_bits) and n == (v << i)``
+ where ``i`` is a non-negative integer and ``v`` is a non-negative
+ integer less than ``1 << int_bits``.
+ """
+ n = 0
+ while n < (1 << total_bits):
+ yield n
+ if n < (1 << int_bits):
+ n += 1
+ else:
+ n += 1 << (n.bit_length() - int_bits)
+
+
+def partitioned_ints(bit_width):
+ """ Get ints with all 1s on one side and 0s on the other. """
+ for i in range(bit_width):
+ yield (-1 << i) & ((1 << bit_width) - 1)
+ yield (1 << (i + 1)) - 1
+
+
+class TestShiftedInts(unittest.TestCase):
+ def test(self):
+ expected = [0x000,
+ 0x001,
+ 0x002, 0x003,
+ 0x004, 0x005, 0x006, 0x007,
+ 0x008, 0x009, 0x00A, 0x00B, 0x00C, 0x00D, 0x00E, 0x00F,
+ 0x010, 0x012, 0x014, 0x016, 0x018, 0x01A, 0x01C, 0x01E,
+ 0x020, 0x024, 0x028, 0x02C, 0x030, 0x034, 0x038, 0x03C,
+ 0x040, 0x048, 0x050, 0x058, 0x060, 0x068, 0x070, 0x078,
+ 0x080, 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0,
+ 0x100, 0x120, 0x140, 0x160, 0x180, 0x1A0, 0x1C0, 0x1E0,
+ 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x340, 0x380, 0x3C0,
+ 0x400, 0x480, 0x500, 0x580, 0x600, 0x680, 0x700, 0x780,
+ 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00, 0xF00]
+ self.assertEqual(list(shifted_ints(12, 4)), expected)
+
+