一般化グレーコード


13

入力:配列Ik個の正の整数。整数は100以下で、k≤100です。

出力:あなたのコードを出力しなければならないすべての可能な配列のO長の非負整数のkの制限と0≤O I ≤I I ある配列から次の配列に移動するには、配列の1つの値に1を加算または減算します。コードで同じ配列を2回出力してはいけません。出力される異なる配列の数が非常に多い場合、コードは強制終了されるまで永久に出力を続ける必要があります。

  • Ik個の配列である場合、これはビット幅kのすべてのグレイコードを反復処理する問題です。ただし、最初と最後の要素が1ステップで到達可能である必要はありません。

  • その場合I = [2,1]、出力配列の可能な順序は次のとおりです。(0,0),(0,1),(1,1),(1,0),(2,0),(2,1)

  • その場合I = [2,1,3]、出力配列の可能な順序の1つは(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 2または2 kのように、kに比例する時間が必要です。これは、出力ごとの平均時間ではなく、出力される各配列の最悪の場合の時間であることに注意してください。

64ビット整数でのすべての算術演算は、配列内の値の割り当てと検索および変更だけでなく、それらの読み取りおよび出力と同様に、一定時間で実行できると想定できます。

複雑さが制限されていることの1つの結果は、プログラムの終了時にのみ出力されるソリューションは受け入れられないことです。


1
(モジュロで「1を加算または減算」を実行するI_i+1必要がありますI_iか?から0に到達できますか?)
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バイトのニーモニックに感謝します。

ジェネレーター機能。(私に思い出させてくれたデニスに感謝します、私は機能が存在することを忘れていました)出力を標準出力に出力する必要がある場合、print(t,flush=1)さらに9バイト使用するか、Pythonを呼び出して+1バイト-uprint(t)十分です。

エラー(IndexError)で停止します。この関数を呼び出してプログラムを続行する場合は、キャッチする必要があります。


内側のwhileループはどのくらい実行されますか?
アヌーシュ

せいぜい@Anush kので、各ステップにおいて、ステップiだけ増加1し、後kの工程i==kd[i]、エラーを引き起こします。
user202729

これは非常に良い解決策です。
アヌーシュ

で置き換えること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

Kotlin181 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)
-ovs
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.