1

Тема: Послідовність унікальних значень в N біт [бінарний | двійковий код]

Тепер я бачу код навіть там, де в минулому здавалось що його не може бути. Побачив на машині витeрадло такого типу:

(фото, *.jpg)

conventional wiper blade

і мене "накрило".. з початку думав шо це візуальні галюцинації, але [на всякий випадок] перевірив на компі і виявив що воно дійсно працює. Це була послідовність всіх значень для 3-х біт [або 4-х біт (залежить від ізоморфізму)] такого вигляду:

value value     xor    bits
 0x00  ░░░░    ░░░█       0
 0x01  ░░░█    ░░█░      1.
 0x03  ░░██    ░░░█       0
 0x02  ░░█░    ░█░░     2..
 0x06  ░██░    ░░░█       0
 0x07  ░███    ░░█░      1.
 0x05  ░█░█    ░░░█       0
 0x04  ░█░░    █░░░    3...
 0x0C  ██░░    ░░░█       0
 0x0D  ██░█    ░░█░      1.
 0x0F  ████    ░░░█       0
 0x0E  ███░    ░█░░     2..
 0x0A  █░█░    ░░░█       0
 0x0B  █░██    ░░█░      1.
 0x09  █░░█    ░░░█       0
 0x08  █░░░   █░░░░   4....

Для порівняня, звичайний лічильник (increment | +1), який ми користуємо всюди, має вигляд:

value value     xor    bits
 0x00  ░░░░    ░░░█       0
 0x01  ░░░█    ░░██      10
 0x02  ░░█░    ░░░█       0
 0x03  ░░██    ░███     210
 0x04  ░█░░    ░░░█       0
 0x05  ░█░█    ░░██      10
 0x06  ░██░    ░░░█       0
 0x07  ░███    ████    3210
 0x08  █░░░    ░░░█       0
 0x09  █░░█    ░░██      10
 0x0A  █░█░    ░░░█       0
 0x0B  █░██    ░███     210
 0x0C  ██░░    ░░░█       0
 0x0D  ██░█    ░░██      10
 0x0E  ███░    ░░░█       0
 0x0F  ████   █████   43210

Колони

  • "value" містить значеня послідовності;

  • "xor" - бітова різниця сусідних значень;

  • "bits" - індекси біт для "xor" і вони показують скільки біт [і які] треба змінити для встановленя наступного значеня;

Думаю, ту першу послідовність можна буде використати для зтвореня архітектури енерґо-ефективного процесора, бо там електро-струм буде бігати по мінімальній кількості провідників.

Якщо знаєте ще якісь послідовності з цікавими властивостями, то кидайте сюди.

Подякували: ReAl1

2

Re: Послідовність унікальних значень в N біт [бінарний | двійковий код]

Як то часто буває, я не перший, запізнив на 150 рік [як мінімум]. Той код в різних країнах відомий під різними назвами:

і був використаний в апаратах для теле-комунікацій.

В oeis.org { value: A003188, xor: A006519, bits: A007814 }.

*SCRATCH* Ідемо слідами предків.

Подякували: koala, Tarpan87, Chemist-i3

3

Re: Послідовність унікальних значень в N біт [бінарний | двійковий код]

leofun01 написав:

Як то часто буває, я не перший, запізнив на 150 рік [як мінімум]. Той код в різних країнах відомий під різними назвами:

і був використаний в апаратах для теле-комунікацій.

В oeis.org { value: A003188, xor: A006519, bits: A007814 }.

*SCRATCH* Ідемо слідами предків.

Двобітовий варіант цього коду відомий також під назвою «квадратурний код» і використовується в різноманітних «відносних» енкодерах для регулювання величини замість старого доброго потенціометра (на мордах мікрохвильовок, пральних машин, осцилографів, раніше — у механічних та оптико-механічних мишках).
В «абсолютних» енкодерах використовується цей же код розрядності, потрібної для заданої роздільної здатності, тут для прикладу 3 біти, але зазвичай 6 і більше.

Також може використовуватися в цифрових системах (FPGA) для передачі індексів запису і зчитування FIFO між різними клоковими доменами (пояснення англійською).

Дійсно страшенно корисна і розповсюджена штука

Подякували: leofun011

4

Re: Послідовність унікальних значень в N біт [бінарний | двійковий код]

Було цікаво як буде виглядати послідовність і чи будуть значеня (value) унікальними, якщо побудувати її на основі інвертованих xor сусідів. Взяв послідовності з першого поста, дістав бітові доповненя для xor, за ними послідовно відтворив всі value починаючи з 0. Побачив що послідовності, побудовані таким зпосібом, містять комбінацію 2-х шаблонів, тому я їх розділив (окремо: парні, не парні). Ось шо з того вийшло:

1. ~xor(Baudot) => Lucal код
  value v_mod value     xor      xor     bits
+0+0x00  0x00  ░░░░    ███░  -(1+2^0)    321.
-1-0x01  0x0E  ███░    ██░█  -(1+2^1)    32.0
+0+0x03  0x03  ░░██    ███░  -(1+2^0)    321.
-1-0x02  0x0D  ██░█    █░██  -(1+2^2)    3.10
+0+0x06  0x06  ░██░    ███░  -(1+2^0)    321.
-1-0x07  0x08  █░░░    ██░█  -(1+2^1)    32.0
+0+0x05  0x05  ░█░█    ███░  -(1+2^0)    321.
-1-0x04  0x0B  █░██    ░███  -(1+2^3)    .210
+0+0x0C  0x0C  ██░░    ███░  -(1+2^0)    321.
-1-0x0D  0x02  ░░█░    ██░█  -(1+2^1)    32.0
+0+0x0F  0x0F  ████    ███░  -(1+2^0)    321.
-1-0x0E  0x01  ░░░█    █░██  -(1+2^2)    3.10
+0+0x0A  0x0A  █░█░    ███░  -(1+2^0)    321.
-1-0x0B  0x04  ░█░░    ██░█  -(1+2^1)    32.0
+0+0x09  0x09  █░░█    ███░  -(1+2^0)    321.
-1-0x08  0x07  ░███   ░████  -(1+2^4)   .3210
  value v_mod value     xor      xor     bits
+0+0x00  0x00  ░░░░    ░░██  1+2^(0+1)     10
+0+0x03  0x03  ░░██    ░█░█  1+2^(1+1)    2.0
+0+0x06  0x06  ░██░    ░░██  1+2^(0+1)     10
+0+0x05  0x05  ░█░█    █░░█  1+2^(2+1)   3..0
+0+0x0C  0x0C  ██░░    ░░██  1+2^(0+1)     10
+0+0x0F  0x0F  ████    ░█░█  1+2^(1+1)    2.0
+0+0x0A  0x0A  █░█░    ░░██  1+2^(0+1)     10
+0+0x09  0x09  █░░█   █░░░█  1+2^(3+1)  4...0
  value v_mod value     xor      xor     bits
-1-0x01  0x0E  ███░    ░░██  1+2^(0+1)     10
-1-0x02  0x0D  ██░█    ░█░█  1+2^(1+1)    2.0
-1-0x07  0x08  █░░░    ░░██  1+2^(0+1)     10
-1-0x04  0x0B  █░██    █░░█  1+2^(2+1)   3..0
-1-0x0D  0x02  ░░█░    ░░██  1+2^(0+1)     10
-1-0x0E  0x01  ░░░█    ░█░█  1+2^(1+1)    2.0
-1-0x0B  0x04  ░█░░    ░░██  1+2^(0+1)     10
-1-0x08  0x07  ░███   █░░░█  1+2^(3+1)  4...0
2. (~xor(Baudot))>>1 => код Baudot

Максимальна кількість біт, які змінюйемо при встановлені наступного значеня.

  value v_mod value     xor    bits
+0+0x00  0x00  ░░░░    ████    3210
-1-0x00  0x0F  ████    ███░    321.
+0+0x01  0x01  ░░░█    ████    3210
-1-0x01  0x0E  ███░    ██░█    32.0
+0+0x03  0x03  ░░██    ████    3210
-1-0x03  0x0C  ██░░    ███░    321.
+0+0x02  0x02  ░░█░    ████    3210
-1-0x02  0x0D  ██░█    █░██    3.10
+0+0x06  0x06  ░██░    ████    3210
-1-0x06  0x09  █░░█    ███░    321.
+0+0x07  0x07  ░███    ████    3210
-1-0x07  0x08  █░░░    ██░█    32.0
+0+0x05  0x05  ░█░█    ████    3210
-1-0x05  0x0A  █░█░    ███░    321.
+0+0x04  0x04  ░█░░    ████    3210
-1-0x04  0x0B  █░██   █░███   4.210
  value v_mod value     xor   xor   bits
+0+0x00  0x00  ░░░░    ░░░█   2^0      0
+0+0x01  0x01  ░░░█    ░░█░   2^1     1.
+0+0x03  0x03  ░░██    ░░░█   2^0      0
+0+0x02  0x02  ░░█░    ░█░░   2^2    2..
+0+0x06  0x06  ░██░    ░░░█   2^0      0
+0+0x07  0x07  ░███    ░░█░   2^1     1.
+0+0x05  0x05  ░█░█    ░░░█   2^0      0
+0+0x04  0x04  ░█░░   ░█░░░   2^3   3...
  value v_mod value     xor   xor   bits
-1-0x00  0x0F  ████    ░░░█   2^0      0
-1-0x01  0x0E  ███░    ░░█░   2^1     1.
-1-0x03  0x0C  ██░░    ░░░█   2^0      0
-1-0x02  0x0D  ██░█    ░█░░   2^2    2..
-1-0x06  0x09  █░░█    ░░░█   2^0      0
-1-0x07  0x08  █░░░    ░░█░   2^1     1.
-1-0x05  0x0A  █░█░    ░░░█   2^0      0
-1-0x04  0x0B  █░██   ░█░░░   2^3   3...
3. ~xor(increment) => increment
  value v_mod value     xor    xor    bits
+0+0x00  0x00  ░░░░    ████  -(2^0)   3210
-1-0x00  0x0F  ████    ███░  -(2^1)   321.
+0+0x01  0x01  ░░░█    ████  -(2^0)   3210
-1-0x01  0x0E  ███░    ██░░  -(2^2)   32..
+0+0x02  0x02  ░░█░    ████  -(2^0)   3210
-1-0x02  0x0D  ██░█    ███░  -(2^1)   321.
+0+0x03  0x03  ░░██    ████  -(2^0)   3210
-1-0x03  0x0C  ██░░    █░░░  -(2^3)   3...
+0+0x04  0x04  ░█░░    ████  -(2^0)   3210
-1-0x04  0x0B  █░██    ███░  -(2^1)   321.
+0+0x05  0x05  ░█░█    ████  -(2^0)   3210
-1-0x05  0x0A  █░█░    ██░░  -(2^2)   32..
+0+0x06  0x06  ░██░    ████  -(2^0)   3210
-1-0x06  0x09  █░░█    ███░  -(2^1)   321.
+0+0x07  0x07  ░███    ████  -(2^0)   3210
-1-0x07  0x08  █░░░   █░░░░  -(2^4)  4....
  value v_mod value     xor      xor    bits
+0+0x00  0x00  ░░░░    ░░░█ -1+2^(0+1)     0
+0+0x01  0x01  ░░░█    ░░██ -1+2^(1+1)    10
+0+0x02  0x02  ░░█░    ░░░█ -1+2^(0+1)     0
+0+0x03  0x03  ░░██    ░███ -1+2^(2+1)   210
+0+0x04  0x04  ░█░░    ░░░█ -1+2^(0+1)     0
+0+0x05  0x05  ░█░█    ░░██ -1+2^(1+1)    10
+0+0x06  0x06  ░██░    ░░░█ -1+2^(0+1)     0
+0+0x07  0x07  ░███   ░████ -1+2^(3+1)  3210
  value v_mod value     xor      xor    bits
-1-0x00  0x0F  ████    ░░░█ -1+2^(0+1)     0
-1-0x01  0x0E  ███░    ░░██ -1+2^(1+1)    10
-1-0x02  0x0D  ██░█    ░░░█ -1+2^(0+1)     0
-1-0x03  0x0C  ██░░    ░███ -1+2^(2+1)   210
-1-0x04  0x0B  █░██    ░░░█ -1+2^(0+1)     0
-1-0x05  0x0A  █░█░    ░░██ -1+2^(1+1)    10
-1-0x06  0x09  █░░█    ░░░█ -1+2^(0+1)     0
-1-0x07  0x08  █░░░   ░████ -1+2^(3+1)  3210

Бачимо що значеня (value) унікальні [, і v_mod теж]. Десь на такий результат я й очікував.
Але є проблема: в цих прикладах молодші біти змінюйуть значеня сильно частіше ніж старші біти.
Тепер цікаво, чи можна зробити розподіл таких змін більш рівномірним ?
Ідеально рівномірним - точно не вийде, бо 32/5 - не ціле, і більшість інших (2^N)/N теж. Але було би добре ґарантувати рівномірність для N = 2^X, тоді на кожний розряд (біт) буде [як мінімум] (2^(2^X))/(2^X) = (2^(2^X - X)) змін за всю послідовність.

5

Re: Послідовність унікальних значень в N біт [бінарний | двійковий код]

Цінність коду Грея в тому, що при лінійному переході міняється лише один біт, що і дає можливість боротися з метастабільністю у тому варіанті з FIFO чи з брязкотом контактів (що майже те ж саме) у електро-механічних енкодерах (та люфтами / вібрацією і в оптичних теж) чи в модуляції QAM (розділ про двовимірний код Грея в en-статті) при сповзанні/деформації сузір'я отримувати помилки легші для корекції/виявлення.

А з якою частотою міняється який біт загалом не так важливо.

Подякували: leofun011

6

Re: Послідовність унікальних значень в N біт [бінарний | двійковий код]

Аж тепер до мене дійшло, що якщо я намагатимусь розкидати зміни максимально рівномірно, то єдиного гарного рішеня не вийде. Якщо обмеженя (в постанові задачі) будуть надто тісні, то рішеня взагалі не існує.

ReAl написав:

.. при лінійному переході міняється лише один біт ..

А з якою частотою міняється який біт загалом не так важливо.

Так, але я мусів сам собі це довести. Пошук послідовностів з розподілом по бітах більш рівномірним ніж Gray код дав результати, які зтворюйуть більше проблем ніж вирішують, їх часто не можливо маштабувати. Тут є приклади таких:

1. унікальні але не реґулярні
value value     xor   bits
 0x00  ░░░░    ░░░█      0
 0x01  ░░░█    ░░█░     1.
 0x03  ░░██    ░░░█      0
 0x02  ░░█░    ░█░░    2..
 0x06  ░██░    █░░░   3...
 0x0E  ███░    ░█░░    2..
 0x0A  █░█░    ░░░█      0
 0x0B  █░██    ░░█░     1.
 0x09  █░░█    ░░░█      0
 0x08  █░░░    ░█░░    2..
 0x0C  ██░░    ░░░█      0
 0x0D  ██░█    ░░█░     1.
 0x0F  ████    █░░░   3...
 0x07  ░███    ░░█░     1.
 0x05  ░█░█    ░░░█      0
 0x04  ░█░░    ░█░░    2..
2. унікальні але не реґулярні
value value     xor   bits
 0x00  ░░░░    ░░░█      0
 0x01  ░░░█    ░░█░     1.
 0x03  ░░██    ░░░█      0
 0x02  ░░█░    ░█░░    2..
 0x06  ░██░    ░░░█      0
 0x07  ░███    ░░█░     1.
 0x05  ░█░█    █░░░   3...
 0x0D  ██░█    ░░█░     1.
 0x0F  ████    ░█░░    2..
 0x0B  █░██    ░░█░     1.
 0x09  █░░█    ░░░█      0
 0x08  █░░░    ░░█░     1.
 0x0A  █░█░    ░█░░    2..
 0x0E  ███░    ░░█░     1.
 0x0C  ██░░    █░░░   3...
 0x04  ░█░░    ░█░░    2..

і це були найгарніші версії [, ймовірно тому що вони найбільше подібні на Gray код].

А з Gray кодом (кодом Baudot) таких проблем не є, і багато процесів (алґоритмів) залишаються достатньо простими, щоб можна було збільшити кількість біт якщо треба.

Подякували: ReAl1

7

Re: Послідовність унікальних значень в N біт [бінарний | двійковий код]

З попередніми кодами я завершив. Тепер переходимо до бітових циклів de Bruijn, будемо їх ґенерити. Найменші послідовності можна перебрати без компа.

Bits: 1, Length: 2, Count: 1
0x01 : 0b-1

Bits: 2, Length: 4, Count: 1
0x03 : 0b--11

Bits: 3, Length: 8, Count: 2
0x17 : 0b---1-111
0x1D : 0b---111-1

Тут можуть виникнути питання:

  • "0b це шо ?" : В останіх версіях C# це префікс двійкового числа.

  • "Чому мінуси ? (-)" : Я замінив '0' на '-' щоб візуально було легше читати, щоб бачити властивості.

  • "Це ж не всі послідовності, Де 0xE8 : 0b111-1--- ?" : Залежить як порівнювати. Якщо існує спосіб циклічно змістити послідовність біт A і отримати послідовність біт B, то такі послідовності будемо вважати рівними (A == B). [0xE8 == (0x1D << 3)]

Всі цикли будемо вирівняти так щоб в старших бітах були нулі.
4 <= 16 (зґенерив і перевірив всі)

Bits: 4, Length: 16, Count: 16
0x09AF : 0b----1--11-1-1111
0x09EB : 0b----1--1111-1-11
0x0A6F : 0b----1-1--11-1111
0x0A7B : 0b----1-1--1111-11
0x0B3D : 0b----1-11--1111-1
0x0B4F : 0b----1-11-1--1111
0x0BCD : 0b----1-1111--11-1
0x0BD3 : 0b----1-1111-1--11
0x0CBD : 0b----11--1-1111-1
0x0D2F : 0b----11-1--1-1111
0x0D79 : 0b----11-1-1111--1
0x0DE5 : 0b----11-1111--1-1
0x0F2D : 0b----1111--1-11-1
0x0F4B : 0b----1111-1--1-11
0x0F59 : 0b----1111-1-11--1
0x0F65 : 0b----1111-11--1-1
5 <= 32 (зґенерив всі і тести пройшли всі)

Bits: 5, Length: 32, Count: 2048
0x04653ADF : 0b-----1---11--1-1--111-1-11-11111
0x04653B5F : 0b-----1---11--1-1--111-11-1-11111
0x04653EB7 : 0b-----1---11--1-1--11111-1-11-111
0x04653ED7 : 0b-----1---11--1-1--11111-11-1-111
0x046569DF : 0b-----1---11--1-1-11-1--111-11111
0x046569F7 : 0b-----1---11--1-1-11-1--11111-111
0x04656E9F : 0b-----1---11--1-1-11-111-1--11111
0x04656FA7 : 0b-----1---11--1-1-11-11111-1--111
0x0465769F : 0b-----1---11--1-1-111-11-1--11111
0x04657DA7 : 0b-----1---11--1-1-11111-11-1--111
0x0465A9DF : 0b-----1---11--1-11-1-1--111-11111
0x0465A9F7 : 0b-----1---11--1-11-1-1--11111-111
0x0465BA9F : 0b-----1---11--1-11-111-1-1--11111
0x0465BEA7 : 0b-----1---11--1-11-11111-1-1--111
0x0465DA9F : 0b-----1---11--1-111-11-1-1--11111
0x0465F6A7 : 0b-----1---11--1-11111-11-1-1--111
0x04674ADF : 0b-----1---11--111-1--1-1-11-11111
0x046752DF : 0b-----1---11--111-1-1--1-11-11111
0x0467695F : 0b-----1---11--111-11-1--1-1-11111
0x04676A5F : 0b-----1---11--111-11-1-1--1-11111
0x0467D2B7 : 0b-----1---11--11111-1--1-1-11-111
0x0467D4B7 : 0b-----1---11--11111-1-1--1-11-111
0x0467DA57 : 0b-----1---11--11111-11-1--1-1-111
0x0467DA97 : 0b-----1---11--11111-11-1-1--1-111
0x046959DF : 0b-----1---11-1--1-1-11--111-11111
0x046959F7 : 0b-----1---11-1--1-1-11--11111-111
0x04695CFB : 0b-----1---11-1--1-1-111--11111-11
0x04695D9F : 0b-----1---11-1--1-1-111-11--11111
0x04695F3B : 0b-----1---11-1--1-1-11111--111-11
0x04695F67 : 0b-----1---11-1--1-1-11111-11--111
0x0469CAFB : 0b-----1---11-1--111--1-1-11111-11
0x0469D95F : 0b-----1---11-1--111-11--1-1-11111
...
0x04A367D7 : 0b-----1--1-1---11-11--11111-1-111
...
0x04EB1BE5 : 0b-----1--111-1-11---11-11111--1-1
...
0x0564EF8D : 0b-----1-1-11--1--111-11111---11-1
...
0x05F26A3B : 0b-----1-11111--1--11-1-1---111-11
...
0x067DC5A9 : 0b-----11--11111-111---1-11-1-1--1
...
0x0717D935 : 0b-----111---1-11111-11--1--11-1-1
...
0x07C535D9 : 0b-----11111---1-1--11-1-111-11--1
...
0x07DC4CB5 : 0b-----11111-111---1--11--1-11-1-1
...
0x07DC5699 : 0b-----11111-111---1-1-11-1--11--1
0x07DC5935 : 0b-----11111-111---1-11--1--11-1-1
0x07DC59A9 : 0b-----11111-111---1-11--11-1-1--1
0x07DC5A99 : 0b-----11111-111---1-11-1-1--11--1
0x07DC8A6B : 0b-----11111-111--1---1-1--11-1-11
0x07DC8AD3 : 0b-----11111-111--1---1-1-11-1--11
0x07DC8B53 : 0b-----11111-111--1---1-11-1-1--11
0x07DC98AD : 0b-----11111-111--1--11---1-1-11-1
0x07DC98B5 : 0b-----11111-111--1--11---1-11-1-1
0x07DC9A2B : 0b-----11111-111--1--11-1---1-1-11
0x07DC9A8B : 0b-----11111-111--1--11-1-1---1-11
0x07DC9AC5 : 0b-----11111-111--1--11-1-11---1-1
0x07DCA26B : 0b-----11111-111--1-1---1--11-1-11
0x07DCA6B1 : 0b-----11111-111--1-1--11-1-11---1
0x07DCAC4D : 0b-----11111-111--1-1-11---1--11-1
0x07DCAD13 : 0b-----11111-111--1-1-11-1---1--11
0x07DCAD31 : 0b-----11111-111--1-1-11-1--11---1
0x07DCB135 : 0b-----11111-111--1-11---1--11-1-1
0x07DCB513 : 0b-----11111-111--1-11-1-1---1--11
0x07DCB531 : 0b-----11111-111--1-11-1-1--11---1
0x07DCC4AD : 0b-----11111-111--11---1--1-1-11-1
0x07DCC4B5 : 0b-----11111-111--11---1--1-11-1-1
0x07DCC569 : 0b-----11111-111--11---1-1-11-1--1
0x07DCC5A9 : 0b-----11111-111--11---1-11-1-1--1
0x07DCD12B : 0b-----11111-111--11-1---1--1-1-11
0x07DCD22B : 0b-----11111-111--11-1--1---1-1-11
0x07DCD2B1 : 0b-----11111-111--11-1--1-1-11---1
0x07DCD44B : 0b-----11111-111--11-1-1---1--1-11
0x07DCD48B : 0b-----11111-111--11-1-1--1---1-11
0x07DCD4B1 : 0b-----11111-111--11-1-1--1-11---1
0x07DCD625 : 0b-----11111-111--11-1-11---1--1-1
0x07DCD629 : 0b-----11111-111--11-1-11---1-1--1

6 <= 64 (зґенерив не всі, тільки кілька тисяч початкових і кінцевих, і тести вони пройшли)

Bits: 6, Length: 64, Count: 67108864
0x0218A392CD3D5DBF : 0b------1----11---1-1---111--1--1-11--11-1--1111-1-1-111-11-111111
0x0218A392CD3DBABF : 0b------1----11---1-1---111--1--1-11--11-1--1111-11-111-1-1-111111
0x0218A392CD3F576F : 0b------1----11---1-1---111--1--1-11--11-1--111111-1-1-111-11-1111
0x0218A392CD3F6EAF : 0b------1----11---1-1---111--1--1-11--11-1--111111-11-111-1-1-1111
0x0218A392CD5D3DBF : 0b------1----11---1-1---111--1--1-11--11-1-1-111-1--1111-11-111111
0x0218A392CD5D3F6F : 0b------1----11---1-1---111--1--1-11--11-1-1-111-1--111111-11-1111
0x0218A392CD5DBD3F : 0b------1----11---1-1---111--1--1-11--11-1-1-111-11-1111-1--111111
0x0218A392CD5DBF4F : 0b------1----11---1-1---111--1--1-11--11-1-1-111-11-111111-1--1111
0x0218A392CD5EDD3F : 0b------1----11---1-1---111--1--1-11--11-1-1-1111-11-111-1--111111
0x0218A392CD5FB74F : 0b------1----11---1-1---111--1--1-11--11-1-1-111111-11-111-1--1111
0x0218A392CDA7ABBF : 0b------1----11---1-1---111--1--1-11--11-11-1--1111-1-1-111-111111
0x0218A392CDA7BABF : 0b------1----11---1-1---111--1--1-11--11-11-1--1111-111-1-1-111111
0x0218A392CDA7EAEF : 0b------1----11---1-1---111--1--1-11--11-11-1--111111-1-1-111-1111
0x0218A392CDA7EEAF : 0b------1----11---1-1---111--1--1-11--11-11-1--111111-111-1-1-1111
0x0218A392CDABA7BF : 0b------1----11---1-1---111--1--1-11--11-11-1-1-111-1--1111-111111
0x0218A392CDABA7EF : 0b------1----11---1-1---111--1--1-11--11-11-1-1-111-1--111111-1111
0x0218A392CDABBD3F : 0b------1----11---1-1---111--1--1-11--11-11-1-1-111-1111-1--111111
0x0218A392CDABBF4F : 0b------1----11---1-1---111--1--1-11--11-11-1-1-111-111111-1--1111
0x0218A392CDABDD3F : 0b------1----11---1-1---111--1--1-11--11-11-1-1-1111-111-1--111111
0x0218A392CDABF74F : 0b------1----11---1-1---111--1--1-11--11-11-1-1-111111-111-1--1111
0x0218A392CDD3DABF : 0b------1----11---1-1---111--1--1-11--11-111-1--1111-11-1-1-111111
0x0218A392CDD3F6AF : 0b------1----11---1-1---111--1--1-11--11-111-1--111111-11-1-1-1111
0x0218A392CDD5ED3F : 0b------1----11---1-1---111--1--1-11--11-111-1-1-1111-11-1--111111
0x0218A392CDD5FB4F : 0b------1----11---1-1---111--1--1-11--11-111-1-1-111111-11-1--1111
0x0218A392CDDA7ABF : 0b------1----11---1-1---111--1--1-11--11-111-11-1--1111-1-1-111111
0x0218A392CDDA7EAF : 0b------1----11---1-1---111--1--1-11--11-111-11-1--111111-1-1-1111
0x0218A392CDDABD3F : 0b------1----11---1-1---111--1--1-11--11-111-11-1-1-1111-1--111111
0x0218A392CDDABF4F : 0b------1----11---1-1---111--1--1-11--11-111-11-1-1-111111-1--1111
0x0218A392CDEAED3F : 0b------1----11---1-1---111--1--1-11--11-1111-1-1-111-11-1--111111
0x0218A392CDED5D3F : 0b------1----11---1-1---111--1--1-11--11-1111-11-1-1-111-1--111111
0x0218A392CDFABB4F : 0b------1----11---1-1---111--1--1-11--11-111111-1-1-111-11-1--1111
0x0218A392CDFB574F : 0b------1----11---1-1---111--1--1-11--11-111111-11-1-1-111-1--1111
...
0x03D5DBF2CD271461 : 0b------1111-1-1-111-11-111111--1-11--11-1--1--111---1-1---11----1
...
0x03F6EAF2CD271461 : 0b------111111-11-111-1-1-1111--1-11--11-1--1--111---1-1---11----1
...
0x03F79D71B4A8B261 : 0b------111111-1111--111-1-111---11-11-1--1-1-1---1-11--1--11----1
0x03F79D71B4B09915 : 0b------111111-1111--111-1-111---11-11-1--1-11----1--11--1---1-1-1
0x03F79D71B4B0A899 : 0b------111111-1111--111-1-111---11-11-1--1-11----1-1-1---1--11--1
0x03F79D71B4B21513 : 0b------111111-1111--111-1-111---11-11-1--1-11--1----1-1-1---1--11
0x03F79D71B4B22615 : 0b------111111-1111--111-1-111---11-11-1--1-11--1---1--11----1-1-1
0x03F79D71B4B22A13 : 0b------111111-1111--111-1-111---11-11-1--1-11--1---1-1-1----1--11
0x03F79D71B4B26115 : 0b------111111-1111--111-1-111---11-11-1--1-11--1--11----1---1-1-1
0x03F79D71B4B26151 : 0b------111111-1111--111-1-111---11-11-1--1-11--1--11----1-1-1---1
0x03F79D71B4C22C95 : 0b------111111-1111--111-1-111---11-11-1--11----1---1-11--1--1-1-1
0x03F79D71B4C24595 : 0b------111111-1111--111-1-111---11-11-1--11----1--1---1-11--1-1-1
0x03F79D71B4C25459 : 0b------111111-1111--111-1-111---11-11-1--11----1--1-1-1---1-11--1
0x03F79D71B4C25915 : 0b------111111-1111--111-1-111---11-11-1--11----1--1-11--1---1-1-1
0x03F79D71B4C2A259 : 0b------111111-1111--111-1-111---11-11-1--11----1-1-1---1--1-11--1
0x03F79D71B4C2C895 : 0b------111111-1111--111-1-111---11-11-1--11----1-11--1---1--1-1-1
0x03F79D71B4C2C951 : 0b------111111-1111--111-1-111---11-11-1--11----1-11--1--1-1-1---1
0x03F79D71B4C2CA89 : 0b------111111-1111--111-1-111---11-11-1--11----1-11--1-1-1---1--1
0x03F79D71B4C84A8B : 0b------111111-1111--111-1-111---11-11-1--11--1----1--1-1-1---1-11
0x03F79D71B4C8544B : 0b------111111-1111--111-1-111---11-11-1--11--1----1-1-1---1--1-11
0x03F79D71B4C8950B : 0b------111111-1111--111-1-111---11-11-1--11--1---1--1-1-1----1-11
0x03F79D71B4C89615 : 0b------111111-1111--111-1-111---11-11-1--11--1---1--1-11----1-1-1
0x03F79D71B4C8A84B : 0b------111111-1111--111-1-111---11-11-1--11--1---1-1-1----1--1-11
0x03F79D71B4C8B095 : 0b------111111-1111--111-1-111---11-11-1--11--1---1-11----1--1-1-1
0x03F79D71B4C9508B : 0b------111111-1111--111-1-111---11-11-1--11--1--1-1-1----1---1-11
0x03F79D71B4C9510B : 0b------111111-1111--111-1-111---11-11-1--11--1--1-1-1---1----1-11
0x03F79D71B4C95161 : 0b------111111-1111--111-1-111---11-11-1--11--1--1-1-1---1-11----1
0x03F79D71B4C96115 : 0b------111111-1111--111-1-111---11-11-1--11--1--1-11----1---1-1-1
0x03F79D71B4C96151 : 0b------111111-1111--111-1-111---11-11-1--11--1--1-11----1-1-1---1
0x03F79D71B4CA848B : 0b------111111-1111--111-1-111---11-11-1--11--1-1-1----1--1---1-11
0x03F79D71B4CA890B : 0b------111111-1111--111-1-111---11-11-1--11--1-1-1---1--1----1-11
0x03F79D71B4CA8B09 : 0b------111111-1111--111-1-111---11-11-1--11--1-1-1---1-11----1--1
0x03F79D71B4CB0915 : 0b------111111-1111--111-1-111---11-11-1--11--1-11----1--1---1-1-1
0x03F79D71B4CB0A89 : 0b------111111-1111--111-1-111---11-11-1--11--1-11----1-1-1---1--1

Ці списки довелось вкоротити через обмеженя форуму. (це ok, вирізані куски не містили важливої інфо)

Ідея була така: Починайемо з 0, зразу додайемо це число в список використаних, далі це число зміщемо на 1 (v = (v << 1) | (b & 1);) і будемо пробувати дописувати 0 або 1 в молодший біт, рекурсивно.

            0000
           X    \
       0000      0001
                /    \
            0010      0011
           /   |      |   \
       0100   0101  0110   0111
      /   |   |  |  |  |   |   \
  1000 1001 1010  ..  1101 1110 1111
 X  X  X  |  |  X .. /  |  |  |  |  X
...               ..               ...

Проблема в мойему алґоритмі або в реалізації (яку я покищо не хочу показувати, бо це просто сором), в малій швидкості, через це не вдайеться отримати всі значеня для 64 за прийнятний час (за годину, якщо писати в файл). І файл там буде великий, 0.5 GB, якщо в RAW тупо зкидувати всі числа (цикли біт, без дерева, без індексів).
Тому я шукаю в бітових циклах властивості, які дозволять зтворити інший ефективніший алґоритм, якщо він існує.

На даний момент маю виведено такі властивості

2^(2^(1-1)-1) = 1
2 == 2*(1)
1 // довжина послідовно однакових { 0 або 1 }
1 // кількість послідовних 0
1 // кількість послідовних 1

2^(2^(2-1)-2) = 1
4 == 2*(2)
2 // довжина послідовно однакових { 0 або 1 }
1 // кількість послідовних 0
1 // кількість послідовних 1

2^(2^(3-1)-3) = 2
8 == 2*(3 + 1*1)
3 1 // довжина послідовно однакових { 0 або 1 }
1 1 // кількість послідовних 0
1 1 // кількість послідовних 1

2^(2^(4-1)-4) = 16
16 == 2*(4 + 2*1 + 1*2)
4 2 1 // довжина послідовно однакових { 0 або 1 }
1 1 2 // кількість послідовних 0
1 1 2 // кількість послідовних 1

2^(2^(5-1)-5) = 2048
32 == 2*(5 + 3*1 + 2*2 + 1*4)
5 3 2 1 // довжина послідовно однакових { 0 або 1 }
1 1 2 4 // кількість послідовних 0
1 1 2 4 // кількість послідовних 1

2^(2^(6-1)-6) = 67108864
64 == 2*(6 + 4*1 + 3*2 + 2*4 + 1*8)
6 4 3 2 1 // довжина послідовно однакових { 0 або 1 }
1 1 2 4 8 // кількість послідовних 0
1 1 2 4 8 // кількість послідовних 1

2^(2^(7-1)-7) = 144115188075855872
128 == 2*(7 + 5*1 + 4*2 + 3*4 + 2*8 + 1*16)
7 5 4 3 2  1 // довжина послідовно однакових { 0 або 1 }
1 1 2 4 8 16 // кількість послідовних 0
1 1 2 4 8 16 // кількість послідовних 1

але якщо я почну їх користувати, то доведеться творити додаткові структури даних. Ймовірно час буде потратений, а вигода сумнівна..

8

Re: Послідовність унікальних значень в N біт [бінарний | двійковий код]

Проблема була в реалізації. Початкова ідея була майже правильна, але:

  • починати треба з ..0001, і 2 вузли перед ним (1000.., 00..00) треба позначити як вже використані;

  • якщо тип даних дозволяє швидко зміщати всю послідовність, то це треба користати;

  • якщо всю послідовність можна вмістити в стандартний UInt64, то рекурсія ідеальний інструмент для дерева;

  • варто не брати колекції і не творити обйекти в рекурсії, поки це можливо, бо їх буде багато і потім їх доведеться { деякі розпаковувати, більшість видаляти };

  • найважливіше: дерево [і гілки] зберігати не обовязково, тільки обійти гілки і вернути знайдені послідовності.

Дерево буде майже без змін:

              + 1000
               /    X
         + 0000      0001
          X    \
      0000    [ 0001 ]
              _/    \_
          0010        0011
         /   |        |   \
     0100   0101    0110   0111
    X   |   |   \  /   |   |   \
1000  1001 1010  ..  1101 1110 1111
      X  | |  X  ..  |  | |  | |  X
         ...     ..          ...

Старий код я видалив. Новий код (C#) даю:

public static class DeBruijn {
    public static void ForAll_DeBruijnValues_Do(int bits, Action<ulong> act) {
        if(bits <= 0) return;
        if(bits <= 1) { act((ulong)bits); return; }
        if(6 < bits) throw new NotSupportedException();
        int len = 1 << bits;
        int half = len >> 1;
        int mask = len - 1;
        ulong stop = (ulong.MaxValue << half << half) ^ ulong.MaxValue;
        bits -= 2;
        Action<ulong, ulong> deBruijn = null;
        deBruijn = (ulong u, ulong v) => {
            int w = (int)v & mask;
            ulong n = (1uL << w) | u;
            if(n == u) return;
            if(n == stop) { act(v >> bits); return; }
            deBruijn(n, v <<= 1);
            deBruijn(n, v | 1uL);
        };
        deBruijn((1uL << half) | 1uL, 1uL);
    }
    public static int GetCountOf_DeBruijnValues(int bits) {
        int c = 0;
        ForAll_DeBruijnValues_Do(bits, _ => { ++c; });
        return c;
    }
    public static List<ulong> GetListOf_DeBruijnValues(int bits) {
        int c = 1 << ((1 << (bits - 1)) - bits);
        List<ulong> list = new List<ulong>(c);
        ForAll_DeBruijnValues_Do(bits, (ulong v) => { list.Add(v); });
        return list;
    }
}

Швидкість тут приємно вражає.
Про MaxValue << half << half не питайте, це я був змушений пхати костилі через обмеженя на правий операнд.

  • mask - маска для перетину з v, дозволяє дістати унікальне значеня (w),

  • (ulong u, ulong v) - (використані w, послідовність біт),

  • stop - стан (u), при якому викидиємось з вікна з рекурсії.

9

Re: Послідовність унікальних значень в N біт [бінарний | двійковий код]

Мені треба були додаткові можливості:

  • ґенерити бітові послідовності не тільки за зростаням, а й за зпаданям => +asc/desc;

  • ґенерити не всі послідовності, а тільки перші [або останні] кілька .. => +int take;

  • фільтрувати послідовності за довільною ознакою => +predicate match;

, то я їх додав:

public static class DeBruijn {
    public static void ForAll_DeBruijnValues_Do(
        int bits, Action<ulong> act
        , bool desc = false, int take = int.MaxValue
    ) {
        if(take <= 0) return;
        if(bits <= 0) return;
        if(bits <= 1) { act((ulong)bits); return; }
        if(6 < bits) throw new NotSupportedException();
        int len = 1 << bits;
        int half = len >> 1;
        int mask = len - 1;
        ulong stop = (ulong.MaxValue << half << half) ^ ulong.MaxValue;
        ulong a = desc ? 1uL : 0uL;
        ulong b = desc ? 0uL : 1uL;
        bits -= 2;
        Action<ulong, ulong> deBruijn = null;
        deBruijn = (ulong u, ulong v) => {
            if(take <= 0) return;
            int w = (int)v & mask;
            ulong n = (1uL << w) | u;
            if(n == u) return;
            if(n == stop) {
                act(v >> bits);
                --take;
                return;
            }
            v <<= 1;
            deBruijn(n, v | a);
            deBruijn(n, v | b);
        };
        deBruijn((1uL << half) | 1uL, 1uL);
    }
    public static int GetCountOf_DeBruijnValues(
        int bits, Predicate<ulong> match
    ) {
        int c = 0;
        ForAll_DeBruijnValues_Do(bits, (ulong v) => { if(match(v)) ++c; });
        return c;
    }
    public static List<ulong> GetListOf_DeBruijnValues(
        int bits, Predicate<ulong> match
        , bool desc = false, int take = int.MaxValue
    ) {
        int c = 1 << ((1 << (bits - 1)) - bits);
        List<ulong> list = new List<ulong>(take < c ? take : c);
        ForAll_DeBruijnValues_Do(bits, (ulong v) => { if(match(v)) list.Add(v); }, desc, take);
        return list;
    }
}