Hofstadterの図と図のシーケンスの生成


16

ゲーデル、エッシャー、バッハ、ダグラス・ホフスタッターは、一般に、図桁のシーケンスと呼ばれる整数配列を導入します。

2, 4, 5, 6, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, ...

チャレンジの一部としてシーケンスの定義を自分で作成することを楽しむこともできますが、それを理解できない場合はOEISでシーケンスA030124として、ウィキペディアで少し明確な定義見つけることができます。

nSTDIN、ARGV、または関数引数を介して指定されたプログラムまたは関数を作成し、n適切なリスト形式でシーケンスの最初の番号のリストをSTDOUTに出力します。

これはコードゴルフで、バイト単位で最短のソリューションが勝ちます。

回答:


6

CJam、38 30 29 21バイト

li_3*,2>\{(_pX+:X-}*;

オンラインでお試しください。

使い方

li                     " Read an integer N from STDIN.              ";
  _3*,2>               " Push S := [ 2 3 ... (N * 3 - 1) ].         ";
        \{        }*   " Do the following N times:                  ";
          (            " Shift an integer I from S.                 ";
           _p          " Print a copy of I, followed by a linefeed. ";
             X+:X      " Execute X += I. (X is initialized to 1.)   ";
                 -     " Remove X from S.                           ";
                    ;  " Discard S from the stack.                  ";

実行例

$ cjam <(echo 'li_3*,2>\{(_pX+:X-}*;') <<< 20
2
4
5
6
8
9
10
11
13
14
15
16
17
19
20
21
22
23
24
25

通訳のURLを入力するときにaditsuのsを逃した
ベータ崩壊14

@BetaDecayその後、なぜそれを修正するために編集しないのですか?)
マーティン・エンダー14

@Martin私は...私は十分に担当者を持っていたとは思いませんでした
ベータ崩壊

2
@BetaDecayあなたはそうしませんが、あなたはまだそれらを提案することができます(受け入れられた場合、あなたに2人の担当者を与えることさえできます)。
マーティンエンダー14

私は、コードの8バイトを追加してゴルフをするのがとても賢いと感じました。そして、私はそれが今... histocrat、matsjoyceとピーター・テイラーからの回答とまったく同じことをしていることが実現
デニス

5

ルビー、54 48

f=->n{x=1
b=*2..n*n
n.times{b-=[x+=p(b.shift)]}}

デモ

編集:メモリに完全な補数シーケンスを保持する必要がないことに気づいたら、もう少しゴルフをしました。仕組みは次のとおりです。x補数シーケンスで計算された最大数を追跡するために使用しb、シーケンスの候補のプールです。n残りの最小要素を出力し、bそれを追加xして補数列の次の数を計算します。次に、候補のプールから両方の数値を削除するため、いずれかのシーケンスにまだ追加されていない最小の数値を常に出力しています。

Rubyのゴルフトリック:Stabby lambda構文はメソッド定義よりも短いです。出力が返り値としてではなくSTDOUTに与えられるという要件は、返り値p(x)xであるという事実を使うきっかけになりました。これは、Anarchy Golfで使用されているRubyバージョンには当てはまらないため、通常覚えていません。


1
どのように機能しますか?
誇りに思ってhaskeller 14

1
FWIWを使用できます2..2*n。私はn*n効果的にやっているので使用しb = [x]^bなければならないのでb、の最大値はの最大値よりも大きくする必要xがありますが、出力シーケンスの可能な最大値b -= [x]b含む必要があります。
ピーターテイラー14

5

Haskell、67 61 60 56 55 53文字

g n=take n$2:4:h
a#(x:s)=[a..x-2]++x#s
h=5#scanl(+)8h

最初のアルゴリズムに戻ります。

このソリューションは、シーケンスの開始要素を合計することにより、補数シーケンスを計算します。次に、補数のシーケンス番号の間のすべての数値としてシーケンスを計算します。

(#)補数シーケンス間の数値を計算する関数です。
hシーケンス自体です。
g質問に答える関数です。

g関数は、hから必要な量の要素を取得するように定義されています。

微妙な点:

h実際には、最初の2つの要素を除いて、図形と図形のシーケンスです。
補数シーケンスではなく、各要素に1が追加された補数シーケンスが計算されます。
これらの2つの微妙さが理由ですscanl(+)8h(1が追加された補完シーケンス(最初の2要素を除く)のコードです)8。これは、補数シーケンスの3番目の要素に1が追加されたものです。
それらが追加されるので、計算は最初の2つの要素が欠落していない理由があるgの中で2:4:h

例:

>g 50
[2,4,5,6,8,9,10,11,13,14,15,16,17,19,20,21,22,23,24,25,27,28,29,30,31,32,33,34,36,37,38,39,40,41,42,43,44,46,47,48,49,50,51,52,53,54,55,57,58,59]

4

GolfScript(24 21バイト)

~.3*,1>\{(\(.p@+\|}*;

オンラインデモ

これはまったく異なって始まりましたが、デニスが若干異なる方向に導くいくつかの提案をする前に、histocratRubyソリューションのGolfScriptポートに収束しました。特に、番号を識別しながら印刷することで、最後に印刷するために配列に番号を集めることを大幅に節約できます。理由は、スタック上の3つ以上のアイテムを心配する必要がないということです。

解剖

~.3*,           # Eval input n, dup, multiply by 3, make list [0 1 ... 3n-1]
1>              # Discard 0, which is part of neither sequence
\{              # Execute n times: stack contains pool of numbers not yet seen
                # in either sequence and the first element of it is the next element of the
                # complement sequence
  (\(           #   Pop two numbers from the start of the pool: stack is
                #     pool[0] pool[2..max] pool[1]
  .p            #   Print pool[1]
  @+            #   Rotate pool[0] to top and add to pool[1]
  \|            #   Place pool[0]+pool[1] at the start of the pool and
                #   (this is the clever bit) remove it from later in the pool
}*
;               # Discard the unused remainder of the pool

あなたが交換した場合^\-、あなたは置き換えることができ).*3*。これはバイトを節約しませんが、実行時間とメモリ使用量を大幅に削減します。-整数を配列の上に置くことで、1バイトを節約できるはずです。ループのバイト数は同じですが、初期化は1バイト短くなります。
デニス14

2
セット組合はさらに良く差よりも動作します:~.3*,1>\{(\(.p@+\|}*;
デニス・

3

J-28文字

n引数として受け取る関数。

($+/\(-.~2+i.)&:>:+/)^:_&2 4

n左引数として関数を実行し、右引数に対して変更が発生しなくなるまで繰り返し実行します。startの引数はリスト2 4です。

関数自体では、部分和+/\と全和を取得し、で+/両方をインクリメントします&:>:。次に、2から全和(2+i.)を超える整数までのすべての整数を生成し-.、部分和を減算()に設定します。これにより、定義により、図の数字列が長くなります。最後に、リストをlengthに短縮または周期的に拡張しますn

結果はに2 4なり3 7、これは2..8離れることから取り除かれ2 4 5 6 8ます。別のラウンドの後、に2 4 5 6 8なり3 7 12 18 26ます

2 4 5 6 8 9 10 11 13 14 15 16 17 19 20 21 22 23 24 25 27

このようにして、図形と図形のシーケンスを繰り返し拡張します。$長さの動作では、シーケンスは、長さに成長するのを待つだけの非自明な文字の保存方法ですn以上、および出力n彼らは変更を停止するとき最初の値を。あまり長く待つ必要もありません。内動詞の4つのアプリケーションから最大46336の用語を取得できます。

kの同じ関数:

  • k2、37文字: {{x#y@&~_lin[y:1+!1+/y;1+\y]}[x]/2 4}
  • k4、36文字: {{x#y@&~(y:2+!1+/y)in\:1+\y}[x]/2 4}

2

Java- 183 158

これは私がこれまでにゴルフをしたことがある中で最も多く、私はそれを誇りに思っています!(ただし、グラフの最上部に近いところはありませんが(Javaであるため))

提案してくれたPeter Taylorに感謝

class f{public static void main(String[]a){int q=1,m=Byte.valueOf(a[0]),w=2,n[]=new int[m*m*2];for(n[q+=w]=1;m-->0;){System.out.println(w);for(;n[++w]>0;);}}}

より大きい -

public class f {
    public static void main(String[] a) {
        int q = 1, m = Byte.valueOf(a[0]), w = 2, n[] = new int[m * m * 2];
        for (n[q += w] = 1; m-- > 0;) {
            System.out.println(w);
            for (; n[++w] > 0;)
                ;
        }
    }
}

その内部forループは非常に印象的に難読化されていますが、数バイト節約できると思います。Byte.valueOf3を節約し、質問は入力の範囲を指定していないので、受け入れられるべきだと思います。ループ外では、mを初期化nするためにのみ使用されるため、完全に削除するk++<mこともできます。として初期化して、以前の初期化子にマージできます。以外の値を保持することはありません、そうかもしれません。初期化子は、最初のループの初期化子部分になります。m-->0kint[] nint n[]n1n[...]!=0n[...]>0for
ピーターテイラー14

そして、あなたが取り除いてu使用するだけ++wなら、n[q]またはを設定する必要はありませんn[w]。バグが1つあります。それは、nwhen の終わりから実行されるという点ですm==2。これは、初期化によって最適に修正されるようですがn=new int[2*m*m]、157バイトにまで減ると思います。
ピーターテイラー14

初期化子が最初のforループの初期化子部分になることについて私が意味したことはfor(int q=1,w=2,m=...,n[]=...;m-->0;){...、セミコロンを節約することでした。
ピーターテイラー14

1

Python 2-77バイト


コード:

n=input();x=1;b=range(2,n*n)
while n:v=b.pop(0);x+=v;print v;b.remove(x);n-=1

入力がstdinから来ることを除いて、@ histocratのソリューションと同じように機能します。



0

ゼリー、15バイト

SƤŻ‘µṀ‘Rḟ
2dz¡ḣ

オンラインでお試しください!

6の入力でのメモリエラー。

使い方

SƤŻ‘µṀ‘Rḟ  Aux. link (monad). Input: part of the desired sequence
SƤŻ‘       Sum of prefixes, then prepend a zero and increment
           This is a list of numbers to exclude from the next iteration
    µ      Re-focus on the above
     Ṁ‘Rḟ  Create range 1..Max + 1, then remove all elements of the above
           +1 is needed to progress from [2] to [2,4]

2dz¡ḣ  Main link (monad). Input: n, number of terms
2dz¡   Starting from 2, apply aux. link n times
    ḣ  Take n elements from the beginning

より効率的なバージョン、16バイト

SƤŻ‘µṀ‘Rḟḣ³
2ÇÐL

オンラインでお試しください!

このJ回答からのアイデアを使用します。反復ごとに必要な長さに切り捨て、フィックスポイントを取得します。(max + 1 S)の代わりに(sum)を使用することを考えましたṀ‘が、その正確性を保証することはできません。


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