广义格雷码


13

输入:k个正整数组成的数组I。整数将不大于100且k≤100

输出:您的代码必须输出所有可能的阵列ö长度的非负整数的ķ其限制是0≤ö ≤我。要从一个数组到下一个数组,您可以在数组中的一个值上加上或减去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 22 k。注意,这不是每个输出的平均时间,而是每个输出阵列的最坏情况时间。

您可以假定对64位整数的所有算术可以在恒定时间内执行,就可以读取和输出它们,以及赋值,查找和更改数组中的值。

限制复杂度的结果之一是仅在程序退出时输出的解决方案是不可接受的。


1
(应该对模进行“加法或减法1” I_i+1?可以从0达到0 I_i吗?)
user202729

@ user202720不,我不打算这样做。
阿努什

nk受限制时,复杂性如何工作?假设他们使用位宽达到无限大
l4m2

@ 14m2为了进行复杂度分析,假定k变为无穷大。
阿努什

@Anush那么位宽怎么走?
l4m2

Answers:


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是否调用-uprint(t)就足够为1个字节。

停止并显示错误(IndexError)。如果要调用此函数然后继续执行程序,则必须捕获它。


内部while循环运行多长时间?
阿努什

@Anush在大多数k步骤中,因为在每个步骤i通过增加1和后k的步骤i==kd[i]将导致错误。
user202729

这是一个非常好的解决方案。
阿努什

您可以将替换not 0<=为来保存一个字节not-1<

1
您能yield t代替使用print(t,flush=1)吗?
丹尼斯

2

Stax,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 '18

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字节

感谢:Anush指出我误解了保存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)
ovs '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.