Codici Gray generalizzati


13

Input: un array I di k numeri interi positivi. I numeri interi non saranno maggiori di 100 e k ≤ 100 .

Output: il codice deve generare tutti i possibili array O di numeri interi non negativi di lunghezza k con la restrizione che 0 ≤ O i ≤ I i . Per passare da un array al successivo, è possibile aggiungere o sottrarre 1 a un valore nell'array. Il codice non deve generare lo stesso array due volte. Se il numero di matrici diverse da emettere è molto elevato, il codice dovrebbe continuare a essere emesso per sempre fino a quando non viene ucciso.

Esempi

  • Se I è un array di k , allora questo è esattamente il problema di iterare su tutti i codici Gray di larghezza bit k , tranne per il fatto che il primo e l'ultimo elemento non devono essere raggiungibili in un solo passaggio.

  • In I = [2,1]tal caso, un possibile ordinamento degli array di output è(0,0),(0,1),(1,1),(1,0),(2,0),(2,1)

  • In I = [2,1,3]tal caso, un possibile ordinamento degli array di output è (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),....

Questa è una sfida di code-golf, vince l'invio con il codice sorgente con la lunghezza più breve. Non lasciare che le brevi risposte nelle lingue del golf ti scoraggino dal pubblicare una risposta in altre lingue. Prova a trovare la risposta più breve in qualsiasi lingua.

Questa è anche una sfida a complessità limitata. Ogni nuovo array deve essere emesso con il tempo O (k) trascorso dal precedente array in uscita (o dall'inizio del programma per il primo array in uscita). Ciò significa che il tempo di esecuzione per il nuovo array di output (sono ciascuno di lunghezza k ) non deve essere maggiore di O (k) . Cioè dovrebbe richiedere del tempo proporzionale a k e non, ad esempio k 2 o 2 k . Si noti che questo non è il tempo medio per output ma il tempo peggiore per ogni array emesso.

Si può presumere che tutta l'aritmetica su numeri interi a 64 bit può essere eseguita in tempo costante, così come la lettura e la loro emissione, nonché l'assegnazione, la ricerca e la modifica dei valori negli array.

Una conseguenza della complessità limitata è che le soluzioni che escono solo all'uscita dal programma non sono accettabili.


1
(dovrebbe "aggiungere o sottrarre 1" modulo eseguito I_i+1? Puoi raggiungere 0 da I_i?)
user202729

@ user202720 No, non intendevo quello.
Anush,

Come funzionano le complessità quando ne ksono limitate? supponendo che vadano all'infinito con un po 'di larghezza come andare
l4m2

@ l4m2 Ai fini dell'analisi della complessità supponiamo che k vada all'infinito.
Anush,

@Anush, quindi come va la larghezza del bit?
l4m2

Risposte:


4

Python 3 , 116 byte

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]

Provalo online!

Grazie Mnemonic per -1 byte.

Funzione generatore. (grazie Dennis per me ricordare, ho dimenticato esiste la caratteristica) Se l'uscita deve essere stampata su stdout quindi utilizzare print(t,flush=1)per 9 byte aggiuntivi, o se Python viene chiamato con -u, print(t)è sufficiente per +1 byte.

Si interrompe con un errore ( IndexError). Se si desidera chiamare questa funzione e quindi continuare il programma, è necessario prenderlo.


Quanto dura il ciclo while interno?
Anush,

@Anush Nella maggior parte dei kpassaggi, perché ad ogni passaggio iaumenta di 1e dopo i kpassaggi i==ke d[i]provoca un errore.
user202729,

Questa è un'ottima soluzione.
Anush,

È possibile salvare un byte sostituendolo not 0<=con not-1<.

1
Potresti usare al yield tposto di print(t,flush=1)?
Dennis,

2

Stax , 22 byte

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

Esegui ed esegui il debug

Eccone uno grande per mostrare il comportamento asintotico Stampa corsa.

Disimballato, non golfato e commentato, sembra così.

,           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

Esegui questo


1
Misurando in bit la complessità, l'indice di iterazione è O(k)bit, quindi i ktempi di divisione possono richiedere del O(k²)tempo ...
user202729

1

JavaScript (Node.js) , 114 byte

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

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

1

Kotlin , 181 178 byte

Grazie a: Anush ha sottolineato che ho capito male la sfida salvando 2 byte. ovs ha sottolineato un risparmio di 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]}}

Provalo online!


1
Per l'esempio nella domanda con 2 1 3 il tuo codice ha bisogno di 3 2 4 come input sembra.
Anush,

1
while(true)può esserewhile(1<2)
ovs,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.