Códigos Gray generalizados

13

Entrada: Uma matriz I de k números inteiros positivos. Os números inteiros não serão maiores que 100 e k ≤ 100 .

Saída: Seu código deve gerar todas as matrizes possíveis O de números inteiros não negativos de comprimento k com a restrição de que 0 ≤ O i ≤ I i . Para passar de uma matriz para a próxima, você pode adicionar ou subtrair 1 a um valor na matriz. Seu código não deve gerar a mesma matriz duas vezes. Se o número de matrizes diferentes a serem produzidas for muito grande, seu código deve continuar produzindo para sempre até que seja eliminado.

Exemplos

  • Se eu sou uma matriz de k ones, então este é exatamente o problema de iterar sobre todos os códigos Gray de largura de bit k , exceto que o primeiro e o último elemento não precisam ser alcançáveis ​​em uma única etapa.

  • Se, I = [2,1]então, uma ordem possível das matrizes de saída for(0,0),(0,1),(1,1),(1,0),(2,0),(2,1)

  • Se, I = [2,1,3]então, uma ordem possível das matrizes de saída é (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),....

Este é um desafio do código-golfe, a submissão com o código-fonte com o menor comprimento vence. Não deixe que as respostas curtas nos idiomas do golfe o desanimam de postar uma resposta em outros idiomas. Tente encontrar a resposta mais curta em qualquer idioma.

Este também é um desafio de complexidade restrita. Toda nova matriz deve ser impressa com tempo O (k) decorrido desde a matriz anterior impressa (ou o início do programa para a primeira matriz impressa). Isso significa que o tempo de execução por nova matriz de saída (cada um tem o comprimento k ) não deve ser maior que O (k) . Ou seja, deve levar tempo proporcional a k e não, por exemplo, k 2 ou 2 k . Observe que este não é o tempo médio por saída, mas o pior caso para cada matriz gerada.

Você pode assumir que toda a aritmética em números inteiros de 64 bits pode ser executada em tempo constante, assim como a leitura e a saída, assim como a atribuição e a pesquisa e a alteração e alteração de valores nas matrizes.

Uma conseqüência da complexidade restrita é que soluções que somente saem na saída do programa não são aceitáveis.

Anush
fonte
1
(deve "adicionar ou subtrair 1" modulo realizada I_i+1Pode atingir 0 de? I_i?)
user202729
@ user202720 Não, eu não pretendia isso.
Anush
Como a complexidade funciona quando ne ké limitada? assumindo que eles vão para o infinito com largura pouco como ir
l4m2
@ l4m2 Para os propósitos da análise de complexidade, assuma que k vai para o infinito.
Anush
@ Anush Então, como é que a largura dos bits?
L4m2

Respostas:

4

Python 3 , 116 bytes

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]

Experimente online!

Obrigado Mnemonic por -1 byte.

Função de gerador. (obrigado Dennis por me lembrar, esqueci que o recurso existe). Se a saída for impressa em stdout, use-a print(t,flush=1)por 9 bytes adicionais ou, se Python for chamado com -u, será print(t)suficiente para +1 bytes.

Pára com um erro ( IndexError). Se você quiser chamar esta função e continuar o programa, precisará capturá-la.

user202729
fonte
Por quanto tempo o loop while interno é executado?
Anush
@ Anush Na maioria das ketapas, porque a cada etapa iaumenta as etapas 1após e depois e causa um erro. ki==kd[i]
User202729
Esta é uma solução muito boa.
Anush
Você pode salvar um byte, substituindo not 0<=por not-1<.
1
Você poderia usar em yield tvez de print(t,flush=1)?
Dennis
2

Stax , 22 bytes

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

Execute e depure

Aqui está um grande exemplo para mostrar o comportamento assintótico Pressione Executar.

Descompactado, não jogado e comentado, é assim.

,           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

Execute este

recursivo
fonte
1
Medindo complexidade bit, o índice de iteração é O(k)bits, então divisão kvezes pode levar O(k²)tempo ...
user202729
1

JavaScript (Node.js) , 114 bytes

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;}}

Experimente online! Ungolfed:

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]--;
    }
}
Neil
fonte
1

Kotlin , 181 178 bytes

Obrigado a: Anush apontou que eu não entendi o desafio de economizar 2 bytes. ovs apontou uma economia de 1 byte.

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]}}

Experimente online!

JohnWells
fonte
1
Para o exemplo da pergunta com 2 1 3, seu código precisa de 3 2 4 como entrada.
Anush
1
while(true)pode serwhile(1<2)
ovs 11/05/19