Узагальнені коди Грея


13

Введення: Масив I з k додатних цілих чисел. Цілі числа будуть не більше 100 і k ≤ 100 .

Вихід: Ваш код повинен виводити всі можливі масиви O негативних цілих чисел довжини k з обмеженням 0 ≤ O i ≤ I i . Щоб дістатися з одного масиву до іншого, ви можете додати або відняти 1 до одного значення в масиві. Ваш код не повинен виводити один і той же масив двічі. Якщо кількість різних масивів для виведення дуже велика, ваш код повинен просто продовжувати виводити назавжди, поки він не буде вбитий.

Приклади

  • Якщо я - масив k , то це саме проблема ітерації над усіма кодами сірого кольору бітової ширини k , за винятком того, що перший і останній елемент не потребують досягнення в один крок.

  • Якщо I = [2,1]тоді можливе впорядкування вихідних масивів(0,0),(0,1),(1,1),(1,0),(2,0),(2,1)

  • Якщо I = [2,1,3]тоді можливе впорядкування вихідних масивів (0,0,0),(0,0,1),(0,0,2),(0,0,3),(0,1,3),(0,1,2),(0,1,1),(0,1,0),(1,1,0),(1,1,1),(1,1,2),(1,1,3),(2,1,3),(2,1,2),(2,1,1),(2,1,0),....

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

Це також завдання з обмеженою складністю. Кожен новий масив повинен виводитися з часом O (k) з моменту попереднього виведеного масиву (або початку програми для першого виведеного масиву). Це означає, що час роботи на новий вихідний масив (кожен з них має довжину k ) не повинен перевищувати O (k) . Тобто воно повинно зайняти пропорцію часу k, а не, наприклад, k 2 або 2 k . Зауважте, що це не середній час на вихід, але найгірший час для кожного виведеного масиву.

Можна припустити, що всю арифметику на 64 бітових цілих числах можна виконувати в постійний час, як і читання та виведення їх, а також призначення та перегляд та зміну значень у масивах.

Одним із наслідків обмеженої складності є те, що рішення, які виводяться лише при виході з програми, є неприйнятними.


1
(чи слід "додати або відняти 1", виконаний за модулем I_i+1? Ви можете досягти 0 з I_i?)
user202729

@ user202720 Ні, я цього не мав намір.
Ануш

Як працюють складності, коли nі kобмежені? припускаючи, що вони йдуть до нескінченності з шириною бітів, як рухатись
l4m2

@ l4m2 Для аналізу аналізу складності припустимо, що k іде до нескінченності.
Ануш

@Anush, так як ширина біта йде?
l4m2

Відповіді:


4

Python 3 , 116 байт

def f(a):
 l=len(a);t=[0]*l;d=[1]*l
 while 1:
  i=0;yield t
  while not-1<t[i]+d[i]<=a[i]:d[i]*=-1;i+=1
  t[i]+=d[i]

Спробуйте в Інтернеті!

Дякую Мнемоніку за -1 байт.

Функція генератора. (дякую Деннісу за те, що він нагадав, я забув, що функція існує) Якщо вихід повинен бути надрукований до stdout, тоді використовуйте print(t,flush=1)для 9 додаткових байтів, або якщо Python викликається -u, print(t)достатньо +1 байта.

Зупиняється з помилкою ( IndexError). Якщо ви хочете зателефонувати в цю функцію, а потім продовжити програму, вам доведеться її зловити.


Скільки часу працює внутрішня петля?
Ануш

@Anush У більшості kкроків, оскільки кожен крок iзбільшується на 1і після kкроків i==kі d[i]викликає помилку.
користувач202729

Це дуже приємне рішення.
Ануш

Ви можете зберегти байт, замінивши not 0<=на not-1<.

1
Чи можете ви використовувати yield tзамість print(t,flush=1)?
Денніс

2

Стакс , 22 байти

▒)∙ñ╚▀NK♀F☺S(A#P`░]╪Db

Запустіть і налагоджуйте його

Ось великий, щоб показати асимптотичну поведінку .

Розпакований, неозорений та коментований, це виглядає приблизно так.

,           pop from input to main stack
W           run the rest of the program repeatedly until explicitly cancelled
  cJP       copy top of stack and print, delimited by spaces
            get the index to mutate
  i^            iteration index + 1
  x{^|%}I       repeatedly apply divmod using l[k]+1 from input
                get the index of the first value that returns modulus >0
  cU=C      if the result is -1 (no match), then terminate the program
            get the direction to mutate
  s             get the "div" part of the last div operation called "d"
  ^|1           -1 ^ (d+1)
  ~{+}&     increment element in array at the index by the calculated amount

Виконати цей


1
Вимірювання бітової складності, індекс ітерації - це O(k)біти, тому час поділу kможе зайняти O(k²)час ...
user202729

1

JavaScript (Node.js) , 114 байт

a=>{b=a.map(_=>0);c=a.map(_=>1);for(i=0;a[i];b[i]+=c[i]||-1){console.log(b);for(i=0;b[i]==a[i]*c[i];i++)c[i]^=1;}}

Спробуйте в Інтернеті! Безголівки:

function ggray(maxima) {
    var current = Array(maxima.length).fill(0);
    var flag = Array(maxima.length).fill(1);
    for (;;) {
        console.log(current);
        for (var i = 0; ; i++) {
            if (i == maxima.length) return;
            if (current[i] != maxima[i] * flag[i]) break;
            flag[i] = 1 - flag[i];
        }
        if (flag[i]) current[i]++;
        else current[i]--;
    }
}

1

Котлін , 181 178 байт

Завдяки: Ануш зазначив, що я неправильно зрозумів завдання збереження 2 байт. ovs вказала економію в 1 байт.

val p={a:List<Int>->var l=a.size
val v=Array(l,{0})
val i=Array(l,{1})
l-=1
o@while(0<1){println(v)
var p=l
while(v[p]+i[p]!in 0..a[p]){i[p]*=-1
p-=1
if(p<0)break@o}
v[p]+=i[p]}}

Спробуйте в Інтернеті!


1
Для прикладу у запитанні з 2 1 3 ваш код потребує 3 2 4 як вхідний вид.
Ануш

1
while(true)можнаwhile(1<2)
ов
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.