コラコスキーシーケンスを計算する


54

これは、I / O要件を最近の標準に合わせて調整するための、古い課題の再投稿です。これは、この人気のシーケンスに関するチャレンジに、より多くの言語が参加できるようにするために行われます。再投稿については、このメタ投稿をご覧ください。

Kolakoskiシーケンスは楽しい自己参照シーケンスであり、OEISシーケンスA000002であるという栄誉を持っています(A000001よりも理解と実装がはるかに簡単です)。シーケンスが始まる1のみから成り1秒と2秒と配列エレメント(N)の長さ説明n個のラン番目の1秒または2つの配列中のSです。これにより、シーケンスが一意に定義されます(その下の実行が視覚化されます)。

1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1,2,1,1,2,1,2,2,1,1,2,1,1,2,...
= === === = = === = === === = === === = = === = = === === = === =
1, 2,  2, 1,1, 2, 1, 2,  2, 1, 2,  2, 1,1, 2, 1,1, 2,  2, 1, 2, 1,...

もちろん、あなたの仕事はこのシーケンスを実装することです。次の3つの形式のいずれかを選択できます。

  1. 入力を取るNと出力Nをシーケンスの用語番目Nのいずれかで開始から0または1
  2. 入力取るN及び出力の用語までを含むNシーケンスの用語番目、nは開始のいずれかから0または1(すなわち、いずれかの印刷最初のn又は第n + 1つの観点から)。
  3. シーケンスから値を無期限に出力します。

2番目と3番目のケースでは、合理的で明確なリスト形式を選択できます。要素は定義上常に1桁であるため、要素間に区切り文字がなければ問題ありません。

3番目のケースでは、提出が関数である場合、それらをサポートする言語で無限リストまたはジェネレーターを返すこともできます。

プログラムまたは関数を記述し、入力を受け取り、出力を提供する標準的な方法を使用できます。これらの抜け穴はデフォルトでは禁止されていることに注意してください。

これはであるため、バイト単位で測定された最短の有効な回答が勝ちます。


関連するが、だまされない。
魔法のタコ

問題の一般化ですが、シーケンスの初期部分が修正されているため、おそらく最適化が可能です。
ジュゼッペ

私たちがそれに取り組んでいる間、私は別の一般化も持っています。
マーティンエンダー

回答:


17

ゼリー、7バイト

2Rṁxṁµ¡

これは、最初のn個の用語を出力する完全なプログラムです。

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

使い方

2Rṁxṁµ¡  Main link. Argument: n (integer)

     µ   Combine the preceding links into a monadic chain.
      ¡  Set t = n.  Call the chain n times, updating t with the return value after
         each call. Yield the last value of t.
2R           Set the return value to 2 and take its range. Yields [1, 2].
  ṁ          Mold; cyclically repeat 1 and 2 to match t's length.
             In the first run, ṁ promotes t = n to [1, ..., n].
   x         Repeat the k-th element of the result t[k] times.
             In the first run, x repeats each element t = n times.
    ṁ        Mold; truncate the result to match the length of t.
             In the first run, ṁ promotes t = n to [1, ..., n].                 

実行例

してみましょうN = 5

チェーンの最初の呼び出しは、1、2を周期的に繰り返して長さ5に達し、次に各要素を5回繰り返し、最後に結果を長さ5に切り捨てます。

  1         2         1         2         1
x 5         5         5         5         5
---------------------------------------------------
  1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1

  1 1 1 1 1

これにより、長さ5のリストが生成されます。最初の要素は、コラコスキーシーケンスの最初の要素です。

チェーンの2回目の呼び出しは、1、2を周期的に繰り返して長さ5に達し、k 番目の要素をj回繰り返します。jは前のリストのk 番目の要素で、最後に結果を長さ5に切り捨てます。

   1 2 1 2 1
x  1 1 1 1 1
------------
   1 2 1 2 1

   1 2 1 2 1

これにより、長さ5の別のリストが生成されます。最初の2つの要素は、コラコスキーシーケンスの最初の2つの要素です。

プロセスはさらに3回繰り返されます。

   1 2   1 2   1
x  1 2   1 2   1
----------------
   1 2 2 1 2 2 1

   1 2 2 1 2
   1 2   1   2 1
x  1 2   2   1 2
------------------
   1 2 2 1 1 2 1 1

   1 2 2 1 1
   1 2   1   2 1
x  1 2   2   1 1
----------------
   1 2 2 1 1 2 1

   1 2 2 1 1

これらは、コラコスキシーケンスの最初の5つの要素です。


12

Python 2、51バイト

l=[2]
print 1,2,
for x in l:print x,;l+=x*[l[-1]^3]

無期限に印刷します。l繰り返し処理されているリストを作成します。の各エントリxに対してl、またはのxコピーを、現在の最後の要素の反対側に追加します。12

主な困難は、最初の自己参照フラグメントを扱うことです[1,2,2]。このコードは、イニシャル1,2を出力し、そこから先に進みます。追加の印刷には12バイトかかります。それなしで:

39バイト、最初の2つのエントリがありません:

l=[2]
for x in l:print x;l+=x*[l[-1]^3]

別のアプローチは、最初の2つのエントリを特別に初期化することです。las を初期化し[0,0,2]て、最初の2つのエントリが追加print x or nされないようにしますが、として印刷されnます。

51バイト

l=[0,0,2]
n=1
for x in l:print x or n;l+=x*[n];n^=3

もう1つの修正方法は、を初期化しl=[1]、で代替を手動で追跡しn、印刷を修正することです。

51バイト

n,=l=[1]
for x in l:print(l==[1,1])+x;l+=x*[n];n^=3

なければ(l==[1,1])+、印刷されたシーケンス以外のすべての作品は始まり1,1,2の代わりに1,2,2。この2番目のステップにいることを認識するより良い方法が必要です。

また、別の奇妙な修正も、どういうわけか同じバイト数です:

51バイト

l=[1];q=2
for x in l:print x;l+=x*[l[-1]^3]*q;q=q<2

12

Wumpus13 11バイト

=[=)O?=!00.

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

セパレータなしでシーケンスを無期限に印刷します。

これがどれほど短いかに本当に驚いています。

説明

基本的な考え方は、シーケンスをスタックに保持し、一番下の要素を繰り返し使用して別の実行を生成してから印刷することです。ここでは、スタックをキューとして事実上悪用しています。また、andの代わりにandを使用0して1(出力のみをインクリメント)することで数バイトを節約できます。この方法では、aで明示的にスタックを初期化する必要がなく、論理否定を使用して2つの値を切り替えることができるためです121

     The entire program is run in a loop.
     At the beginning of loop iteration i, a(i)-1 will be at the bottom of the
     stack and the first element of the ith run of values will be on top.
     The caveat is that on the first iteration, the stack is empty, but
     popping from an empty stack produces an implicit zero.
=    Duplicate the top of the stack. Since this is defined as "pop x, push
     x, push x" this will result in 2 zeros when the stack is empty.
     After this we've got two copies of the ith run's value on top of the stack.
[    Pull up a(i)-1 from the bottom of the stack.
=)O  Duplicate, increment to a(i) and print it.
?=   If a(i)-1 is 1 (as opposed to 0), make another copy of the top of the
     stack. We've now got a(i)+1 copies, so one more than the run should be 
     long, but that's great because we can use the additional copy to get 
     the start of the next run.
!    Logical negation which swaps 0 and 1.
00.  Jump back to the beginning of the program.

10

Brachylog30 26 25 23 17 16 14バイト

~a₀{1|2}ᵐḅlᵐ?l

最初のn個の値を出力します。.入力に「出力変数」を使用し、「入力変数」に出力します?オンラインでお試しください!

説明

私はこれがどのように宣言されたかにかなり満足しています。プログラムは基本的に、出力リストとその入力との関係の高レベルな説明です。

~a₀{1|2}ᵐḅlᵐ?l  Input is a number N.
                Output is a term that I'll call T.
~a₀             T is a prefix of a list L.
   {   }ᵐ       Each element of L
    1|2         is either 1 or 2.
         ḅ      If you cut L into blocks of equal elements
          lᵐ    and take the length of each block,
            ?   the result is T.
             l  The length of T is N.

ので{1|2}ᵐ辞書式順序でリストをしようと、出力は1で始まります。


9

、10バイト

Ṡωo↑⁰`Ṙ¢ḣ2

最初のn個の値を返します。 オンラインでお試しください!

説明

Ṡωo↑⁰`Ṙ¢ḣ2  Input is an integer N.
        ḣ2  The range [1,2]
       ¢    Cycle: C = [1,2,1,2,1,2...
 ω          Iterate until fixed point is found:
Ṡ    `Ṙ      Replicate the list C element-wise according to the current list,
  o↑⁰        then take first N elements.

入力20の場合、プロセスは次のようになります。

[1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2...
[1,2,2,1,2,2,1,2,2,1,2,2,1,2,2,1,2,2,1,2]
[1,2,2,1,1,2,1,1,2,2,1,2,2,1,1,2,1,1,2,2]
[1,2,2,1,1,2,1,2,2,1,2,1,1,2,2,1,2,2,1,1]
[1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,1,2]
[1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1]
[1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1]

1
シーケンスを無期限に印刷するバリエーション、同じバイトカウントがありますが、オンラインで試して
レオ

9

ジャワ10、155の 108 105 100 97バイト

v->{var s="122";for(int i=1;;s+=(1+i%2)*(s.charAt(i)>49?11:1))System.out.print(s.charAt(++i-2));}

区切り文字なしで無期限に印刷します。

@Neilからの間接的なヒントの後の-3バイト。@MartinEnderの
おかげで-5バイト。 Java 8をJava 10に変換する-3バイト。

説明:

オンラインで試してください(TIOで60秒後にタイムアウト)。

v->{              // Method with empty unused parameter and no return-type
  var s="122";    //  String, starting at "122"
  for(int i=1;;   //  Loop `i` from 1 upwards indefinitely
      s+=         //    After every iteration: Append the String with:
         (1+i%2)  //     1+`i`modulo-2
         *(s.charAt(i)>49?11:1))
                  //     either once or twice depending on the digit at index `i`
    System.out.print(s.charAt(++i-2));}
                  //   Print the character at index `i-2` of the String
                  //   After we've first increased `i` by 1 with `++i`

1
この見た目がとてもシンプルになったのが気に入っています。
エリックアウトゴルファー

@EriktheOutgolferありがとう!:)チャレンジを読んだとき、どのように開始すればよいかわかりませんでしたが、それから(頭文字のリストを使用[1,2,2]してそこから行きます)155バイトの回答(現在はStringリストの代わりに)。
ケビンクルーイッセン

(3-i)代わりに使用しないのはなぜ(1+i%2)ですか?
エリックアウトゴルファー

1
@EriktheOutgolfer iは1または2ではないため、文字列インデックスです。
マーティンエンダー

7

ゼリー、10バイト

’߀+\<¹SḂ‘

n 番目の項を返します。

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

使い方

’߀+\<¹SḂ‘  Main link. Argument: n (positive integer)

’           Decrement; yield n-1.
 ߀         Recursively map the main link over [1, ..., n-1].
   +\       Take the cumulative sum.
            The k-th sum is the combined length of the first k runs.
     <¹     Compare each sum with n.
       S    Sum the Booleans.
            This counts the number of runs that occur before the n-th term.
            If there's an even number (including 0) of runs, the n-th term is 1.
            If there's an odd number of runs, the n-th term is 2.
        Ḃ   Extract the least significant bit of the count.
         ‘  Increment.

7

Haskell、33バイト

r=r%1
~(x:t)%n=n:[n|x>1]++t%(3-n)

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

ØrjanJohansenは、反論不可能なパターンを使用してプレフィックスを強制的に使用して7バイトを保存しました。


5
遅延させることで7バイト節約できます。オンラインでお試しください!
Ørjanヨハンセン

@ØrjanJohansenそれは驚くべきことであり、怠patternなパターンは私にとって魔法です。独自の回答を投稿したいですか?
xnor

ああ、あなたはほとんどそこにいた。n:式の始めで使用することによりx、最初を生成するためにそこにいることを知る必要はありませんn。しかし、に到達する前に関数がチェックするのを避けるために、パターンは遅延する必要がありますn:
Ørjanヨハンセン

6

Gol> <>8 7バイト

:{:PnKz

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

説明

これは私のWumpusの回答の移植版です。Gol> <>は基本的に Wumpusの回答を移植するために必要なすべての機能を備え言語です(具体的には、スタックの下部にある暗黙のゼロ、「ポップ」、「プッシュ」、「プッシュ」、およびスタック回転コマンドを実装する「重複」) :

  • トロイダルグリッドがあります。つまり、明示的00.に最初に戻る必要はありません。
  • これはK、「ポップN、次の要素をN回複製」であり?=、置き換えることができ、別のバイトを節約します。

したがって、WumpusからGol> <>へのマッピングは次のようになります。

Wumpus   Gol><>
=        :
[        {
=        :
)        P
O        n
?=       K
!        z
00.

6

シェークスピアプログラミング言語594 583 572バイト

-10バイトのEd Wynnに感謝します!

,.Ford,.Puck,.Act I:.Scene I:.[Enter Ford and Puck]Ford:You cat!Open heart!You big cat!Open heart!Puck:Remember you!Remember me!Scene V:.Ford:You is the sum ofI a cat!Puck:Recall!Open heart!Ford:Remember a pig!Is I nicer a cat?If notyou be the sum ofyou a big pig!Scene X:.Puck:Recall!Ford:Is I nicer zero?If soremember I!If solet usScene X!Puck:Is I nicer zero?You is the sum ofI a big cat!If soyou is I!Remember zero!Remember I!Remember you!You be the difference betweena big cat you!Scene L:.Ford:Recall!Is you worse I?If so,let usScene V!Puck:Remember I!Let usScene L!

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

これは、コメントでリンクされた828バイトのソリューションから始まり、そこから少し変わってエドウィンの未解決のソリューションのゴルフ版です。

説明:

,.Ford,.Puck,.Act I:.Scene I:.[Enter Ford and Puck]    Boilerplate, introducing the characters
Ford:You cat!Open heart!You big cat!Open heart!  Print 1,2 as the first two terms of the sequence

Puck:Remember you!Remember me!  Initialise stack as 0, 2
                                Ford's value is currently 0, representing the value to be pushed to the stack

Scene V:.     Start infinite loop
  Ford:You is the sum ofI a cat!         
  Puck:Recall!Open heart!                 Pop the next value in the stack and print it
  Ford:Remember a pig!                    Push -1 as the end of the stack
  Is I nicer a cat?                       If Ford's value is 2
  If notyou be the sum ofyou a big pig! Subtract 2 from Puck's value to represent making 2 only one copy

        #Reverse the stack until it reaches the terminator value 0 or -1
  Scene X:.Puck:Recall!Ford:Is I nicer zero?If soremember I!If solet usScene X!

  Puck:Is I nicer zero?                          Check if the Puck's value is bigger than 0 (only making one copy)
  You is the sum of Ia big cat!                 Set Ford's value to Puck+2 to counter the change
  If soyou is I!                                But undo it if making one copies
  Remember zero!                                 Push 0 as the stack terminator
  Remember I!                                    Push Ford's value, which is 0 or -1 if this is a single copy, or 1 or 2 for a double copy
  Remember you!                                  Push one copy of Puck's value
  You be the difference betweena big cat you!   Map Ford's value from 1,2 to 1,0

  Scene L:.   #Reverse the stack until it reaches the terminator 0 
     Ford:Recall!Is you worse I?If solet us Scene V!
     Puck:Remember I!Let usScene L!

いいね!双子の代わりに単一の子を(-1または0)にすることで、7バイトを節約できます。これには、シーンXの1バイト前(「もしそうなら」が「もしそうでない」になる)と、シーンXループ直後の1バイト(「Is I nicer you」が「Is I nicer zero」になる)がかかります。節約は、「そうでない場合、覚えておいてください!」を置き換えることができるということです 単に「私を覚えて!」1行前。2番目の子または予備のターミネーターを挿入します。(これが、バランスの取れた「私はあなたの方がいいですか?」を変更する必要がある理由です。シーンXの後にFord == 0に依存することはできません。)TIO、587バイト:tinyurl.com/yb9zg4gp
Edウィン

シーンLで最初の「もしそうなら」を削除し、コマンドをシーンVの先頭に移動できます。新しい「フォード:」が必要なため、これにより1バイトしか節約できません。ただし、Fordが自動的にゼロで初期化されることに依存できる限り、シーンIで数バイトを節約します。これに依存する権利はありませんが、動作する可能性があります:TIO、584バイト:tinyurl.com/y9f6vy7u
エドウィン


5

JavaScript、67 66 60 58 52 51 50バイト

まあ、それは私の脳のかゆみをそれがあるべきよりも大きくしました!n0番目のインデックス付きのth項を返します。

s=`122`
x=1
f=n=>s[n]||f(n,s+=s[++x%2]*(s[x]+0-9))

tshが私のかゆい脳を傷つけたおかげで5 + 1バイト節約されました!


試して

以下のスニペットは、最初の50の用語を出力します。


説明

これは、関数のスコープ外でいくつかの変数を宣言し、関数内で変数を変更し、その後の関数呼び出しで再利用できるまれな機会の1つです。

s=`122`       :Initialise variable s as the string "122"
x=1           :Initialise variable x as integer 1
f=n=>         :Named function f taking input as an argument through parameter n
 s[n]         :If s has a character at index n, return it and exit
 ||           :Or
 f(n          :Call f with n again
  ,s+=        :At the same time, append to s
  s[++x%2]    :  Increment x, modulo by 2 and get the character at that index in s
  *           :  Multiplied by (the above gets cast to an integer)
  (s[x]+0-9)  :  Append a 0 to the xth character of s and subtract 9
 )            :  (The above gives "1"+0-9="10"-9=1 or "2"+0-9="20"-9=11)

どうですかn=>(g=s=>s[n]||g(s+(++x%2+1)*(10*s[x]-9)))('122',x=1)
-tsh

ところで、s='122',x=1,g=n=>s[n]||g(n,s+=(++x%2+1)*(10*s[x]-9))有効な提出と見なされますか?
tsh

ありがとう、@ tsh。s[n]||木のために木が見えないという明らかなケースでした!関数は一度しか呼び出せないため、2番目の提案は無効です。sx呼び出しごとに初期化する必要があります。
シャギー

もう一つは限り、再使用可能でないsx(デフォルトで)各呼び出す間の他のコードが触れていません。
tsh

1
いいね!s[x]+0-9はかなりきちんとしたトリックです
-JollyJoker

4

Python(2および3)、65 60バイト

f=lambda n:sum([f(i)*[i%2+1]for i in range(2,n)],[1,2,2])[n]

0から始まるn番目のエントリを返します。

代替(65バイト):

f=lambda n:n>1and sum([f(i)*[i%2+1]for i in range(n)],[])[n]or-~n

3
PPCGへようこそ!
マーティンエンダー

1
あなたは使用することにより、代替バージョンで5つのバイトを保存する(おそらく、私もテストされていなかった)ことができます[1,2,2]に値を出発物質としてsum
ロッド


4

brainfuck、61バイト

+.+.[.[>]>+++>+++<<<[->+>->-<<<]<[[->+<]<]>>--[[>]<,<[<]>+]>]

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

数値を文字コードとして無期限に出力します。わかりやすくするために、ここでは数字で印刷するバージョンを示します(最初の2つの要素は例外で、検証が簡単です)。

使い方:

+.+. Prints the first two elements. These are the self-referential elements
     This also intitialises the tape with the third element, 2
[ Start infinite loop
   . Print current lowest element
   [>]>+++>+++ Move to end of tape and create two 3s
   <<<[->+>->-<<<] Subtract the last element of the tape from these 3s
   <[[->+<]<]>> Move to the beginning of the tape
   --  Subtract two from the first element
       This leaves 2 as 0 and 1 as -1
   [ If the number was 1
     [>]<,  Delete the excess element from the end of the tape
     <[<]>+ Remove the -1
   ]
   > Move to the next element of the list
]

4

05AB1E12 9バイト

Grimyのおかげで3バイト節約

最初のnアイテムを印刷します。

Δ2LÞsÅΓI∍

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

説明

Δ           # repeat until ToS doesn't change
 2LÞ        # push [1,2,1,2 ...]               
    sÅΓ     # run-length encode with previous value (initially input)
       I∍   # extend/shorten to the length specified by input

ランレングス復号化は、今の内蔵なので、これは単に可能です2L[2LÞsÅΓ
グリムミー

あるいはさらに良いです:∞[2LÞsÅΓ
グリムミー

またはΔ2LÞsÅΓI∍、入力nが指定された最初のn項目を印刷するバージョンの場合。
グリムミー

@Grimy:ありがとう!実際に終了するため、最初のnバージョンが好きです:)
Emigna

3

05AB1E、15バイト

ƵLS[DNÌ©èF®É>¸«

オンラインでお試しください! または反復制限付き

説明

ƵLS               # push our initial list [1,2,2]
   [              # for every N in [0 ...
    D             # duplicate current list of numbers
     NÌ©è         # get the N+2'th element from the list
         F        # that many times do
          ®É>     # push ((N+2)%2==1)+1
             ¸«   # append to current list

の代わりに¸«=保存された2バイトでそれらを印刷します。ƵLS[NÌ©èF®É>=、あなたが消費していないなら、だましする必要はない。
魔法のタコ

@MagicOctopusUrn:最初の3つのアイテムは作成しませんが、残念ながら印刷は機能しません
Emigna


3

J、12バイト

nを取り、最初のn項を生成する単一引数関数。オンラインでお試しください!

$(1+2|I.)^:]

古い質問への私の古い答えを精査してください。

I.は、数値の配列を取り、インデックスのリストを出力する動詞です。したがって、配列のk番目の項目がnの場合、インデックスkn回出現します。これを使用して、初期シードからKolakowskiシーケンスをブートストラップします。各手順は次のように進みます。

1 2   2   1 1 2   1 2   2   1   (some prefix)
0 1 1 2 2 3 4 5 5 6 7 7 8 8 9   (use I.)
0 1 1 0 0 1 0 1 1 0 1 1 0 0 1   (mod 2)
1 2 2 1 1 2 1 2 2 1 2 2 1 1 2   (add 1) 

この操作(1+2|I.)を10から繰り返し実行すると、次のようになります。

10
1 1 1 1 1 1 1 1 1 1
1 2 1 2 1 2 1 2 1 2
1 2 2 1 2 2 1 2 2 1 2 2 1 2 2
1 2 2 1 1 2 1 1 2 2 1 2 2 1 1 ...
1 2 2 1 1 2 1 2 2 1 2 1 1 2 2 ...
1 2 2 1 1 2 1 2 2 1 2 2 1 1 2 ...

毎回、より多くの正しい用語を取得し、しばらくすると最初のn個の用語が修正されることに注意してください。落ち着くまでに必要な反復回数を正確に記述することは困難ですが、nでほぼ対数に見えるため、n回実行するだけ^:]で問題ありません()。(詳細については、これらの他のOEISシーケンスを確認してください:世代の長さ部分的な合計。)

それが完了したら、を使用して最初のn項を取得するだけです$$v動詞の構造vはフックの例であり、n引数として指定すると実行されn $ (v n)ます。

以下は、時間とスペースの無駄がはるかに少ない古い13バイトバージョンです($1+2|I.)^:_~。すべてのステップで入力が切り捨てられるため、直線的に何回も実行するのではなく、整定に必要な回数だけ正確に実行できます。


ああ、これは完璧に動作しI.ます。私はいつも、いくつかのゴルフで使用されているコピー機能を見たいと思っていました。
マイル

3

Fueue、30バイト

Fueueは、実行中のプログラムとそのデータが両方とも同じキューにあり、実行がキュー内を循環するキューベースのエソランです。

1)2:[[2:])~)~:~[[1]:~))~:~~]~]

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

上記は、制御コードとして数字の終わりのないリストを出力します。34バイトの場合、実際の数字を出力できます。

49)50:[[50:])~)~:~[[49]:~))~:~~]~]

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

説明の残りの部分では後者のバージョンを使用します。

Fueue要素の概要

Fueueキューには、次の種類の要素を含めることができます。

  • 実行時にUnicodeコードポイントを出力する整数、
  • 角括弧で区切られたサブプログラムブロック。)関数がブロックを解除しない限り、慈悲深く非アクティブです(キューの最後に移動するだけです)。
  • 単一文字関数。適切なタイプの引数が後に続く場合に実行され、そうでない場合は非アクティブのままになります。
    • このプログラムで使用される関数は~:(次の2つの要素を入れ替える)、(次の要素を複製する)、および)(次のブロックのブロックを解除する)だけです。

高レベルの概要

プログラムのメインループでは、キューは次のもので構成されます。

  • 反復される数字を表すブロックのチェーン。
    • 数字1または2は、それぞれブロック[49][50:]で表されます。
  • 自己複製メインループセクションは、数字ブロックをトラバースし、1と2を交互に配置してからブロックを解除します。
    • 脱ブロック桁のブロックは、独自の数字が印刷さdは、次に作成Dので、それは説明の実行のための数字を作成するには、次のブロックのコピーを。

最初の10コマンドの低レベルトレース

Cmds   Explanation              Queue
49     Print '1'.               )50:[[50:])~)~:~[[49]:~))~:~~]~]
)      Inactive, move to end.   50:[[50:])~)~:~[[49]:~))~:~~]~])
50     Print '2'.               :[[50:])~)~:~[[49]:~))~:~~]~])
:[...] Duplicate block.         )[[50:])~)~:~[[49]:~))~:~~]~][[50:])~)~:~[[49]:~))~:~~]~]
)[...] Deblock (rmv. brackets). [[50:])~)~:~[[49]:~))~:~~]~][50:])~)~:~[[49]:~))~:~~]~
[...]  Inactive.                [50:])~)~:~[[49]:~))~:~~]~[[50:])~)~:~[[49]:~))~:~~]~]
[50:]  Inactive.                )~)~:~[[49]:~))~:~~]~[[50:])~)~:~[[49]:~))~:~~]~][50:]
)      Inactive.                ~)~:~[[49]:~))~:~~]~[[50:])~)~:~[[49]:~))~:~~]~][50:])
~)~    Swap ) and ~.            :~[[49]:~))~:~~]~[[50:])~)~:~[[49]:~))~:~~]~][50:])~)
:~     Duplicate ~.             [[49]:~))~:~~]~[[50:])~)~:~[[49]:~))~:~~]~][50:])~)~~

完全なメインループの反復のウォークスルー

オプションの空白がコマンドを分離するために挿入されました。

49 ) 50 :[[50:])~)~:~[[49]:~))~:~~]~]

サイクル1:49印刷し1ます。)非アクティブで、メインループブロックと一緒になるのを待っています。50印刷し2ます。:メインループブロックを複製します(自己複製にはコピーが必要です)。

) [[50:])~)~:~[[49]:~))~:~~]~] [[50:])~)~:~[[49]:~))~:~~]~]

サイクル2:)最初のメインループブロックのブロックを解除し、次のサイクルの実行を開始します。

[50:] ) ~)~ :~ [[49]:~))~:~~] ~[[50:])~)~:~[[49]:~))~:~~]~]

サイクル3:[50:]チェーンで生成された、2まだ非ブロック化されていない最初の数字を表します。以下)は、メインループの残りがそれを通過した後に最終的にそうします。~)~:~は、ゴルフ(スワップとコピーを使用)の1サイクル遅延です~)~~[[49]:~))~:~~]非アクティブです。~次のメインループブロックを[50:]数字ブロックを超えて交換します。

) ~)~ ~[[49]:~))~:~~][50:] [[50:])~)~:~[[49]:~))~:~~]~]

サイクル4:)まだ待機し、~)~生成し~)、桁ブロックを超えて~スワップします。[[49]:~))~:~~][50:]

) ~)[50:] [[49]:~))~:~~] [[50:])~)~:~[[49]:~))~:~~]~]

サイクル5:数字ブロックを超えて~スワップします。)[50:]

)[50:] )[[49]:~))~:~~] [[50:])~)~:~[[49]:~))~:~~]~]

サイクル6:最初)[50:]デジットブロックのブロックを)解除し、次はサブプログラムのブロックを解除し[[49]:~))~:~~]ます。

50 :[49] :~ ) ) ~:~ ~[[50:])~)~:~[[49]:~))~:~~]~]

サイクル7:生成されたばかりの数字ブロックを50印刷し2:複製して[49]、2つ1の実行を作成します。:~))~:~は1サイクルの遅延です~~))~:~残りのメインループブロックを最初のを過ぎてスワップします[49]

[49] ~~) ) ~:[49] [[50:])~)~:~[[49]:~))~:~~]~]

サイクル8:~~))は1サイクルの遅延です)~)。現在通過したを過ぎて~スワップし:ます[49]

[49] ) ~)[49] :[[50:])~)~:~[[49]:~))~:~~]~]

サイクル9:過去の~スワップ。メインループブロックを複製します。)[49]:

[49] )[49] )[[50:])~)~:~[[49]:~))~:~~]~] [[50:])~)~:~[[49]:~))~:~~]~]

サイクル10:最初は、直前に移動し)[49]数字ブロックのブロックを解除し、2番目)は、メインループを再起動して次のループを移動します(上記のキューの先頭に表示)。


よくやった!Fueueをいくつか学習し、HWチャレンジに答えた理由は、実際にこのチャレンジを検討したのですが、キューベースの性質にあまりにも恐れられていたためです。それはFueueにとって本当に素晴らしいスコアです!:)
マーティン・エンダー

3

x86の、41の 37 35 33 28バイト

これが私の最初の「非自明な」x86回答であるため、さまざまなx86命令をいじりながら多くの楽しみがありました。実際にx86-64を最初に学び、プログラムを32ビットに変換するだけで多くのバイトを節約しました。

OEISから使用したアルゴリズムが値を配列にプッシュするため、x86に対応し、スタックに値を保存できます(MIPSにはスタック命令がないことに注意してください)。

現在、プログラムはN値を入力として受け取り、配列のecxアドレスを返しますebp。n番目の要素はシーケンスのn番目の値を表します。スタックに戻って追加の値を計算することは有効であると仮定します(とにかく配列を超えたものはゴミと見なします)。

変更履歴

  • 反復ごとに計算x = 2 - n%2することにより、-4バイトxor

  • whileループの代わりにdo-whileを使用して-2バイト。

  • -2バイトを使用して初期値1、2、2をプッシュする eax

  • n明示的に保存せず、代わりにループN時間を実行することにより、-5バイト

.section .text
.globl main
main:
        mov     $10, %ecx           # N = 10 

start:
        mov     %esp, %ebp          # Save sp
        push    $1
        push    $2                  # x = 2
        pop     %eax       
        push    %eax                # push 2
        push    %eax                # push 2
        mov     %esp, %esi          # sn = stack+3 addr

loop:                               
        xor     $3, %al             # flip x between 1 <-> 2 
        push    %eax                # push x      
                                    # maybe use jump by parity?
        cmp     $2, (%esi)          # if *sn == 2 
        jne     loop1
        push    %eax                # push x

loop1: 
        sub     $4, %esi            # sn += 1
        loop    loop                # --N, do while (N)
end:
        mov     %ebp, %esp          # Restore sp
        ret

Objdump:

00000005 <start>:
   5:   89 e5                   mov    %esp,%ebp
   7:   6a 01                   push   $0x1
   9:   6a 02                   push   $0x2
   b:   58                      pop    %eax
   c:   50                      push   %eax
   d:   50                      push   %eax
   e:   89 e6                   mov    %esp,%esi

00000010 <loop>:
  10:   34 03                   xor    $0x3,%al
  12:   50                      push   %eax
  13:   83 3e 02                cmpl   $0x2,(%esi)
  16:   75 01                   jne    19 <loop1>
  18:   50                      push   %eax

00000019 <loop1>:
  19:   83 ee 04                sub    $0x4,%esi
  1c:   e2 f2                   loop   10 <loop>

0000001e <end>:
  1e:   89 ec                   mov    %ebp,%esp
  20:   c3                      ret 

3

C(gcc)72 71 65 64 62バイト

@ceilingcatのおかげで-9バイト

x,y;f(z){for(x=y=-1;putchar(49-~x%2);y=-~y|z&x/2)x^=z=y&~-~y;}

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

シーケンスの値を無期限に生成します(チャレンジのオプション3)


説明してください!これがどのように機能するのかわかりません。配列はありません!また、数値は小さすぎて1をビットとして含めることができません。
Ørjanヨハンセン

@ØrjanJohansen認めざるを得ない。これがどのように機能するかわからない!:)私はOEIS A000002からPythonの実装を取り、それをCに移植し、それをゴルフしました:)
vazt

ああ、そこに何かあったのではないかと思ったが、Pythonを見つけるのに十分なほどそのページを見ていない。説明へのリンクがありますが、リンクセクションに少し埋もれていました。この方法は、少なくともCにも確実に適合します。
Ørjanヨハンセン

1)PHPの56バイト:for($x=$y=-1;;$y=$y+1|$f&.5*$x^=$f=$y&-$y-2)echo$x&1?:2;。2)50-x%21バイトを保存してください。3)で実行しようとしましたx=y=1; しかし、これまでの操作を正しく行うことができませんでした。あなたはできる?
タイタス


2

JavascriptをES6 - 71の 70 68バイト

(_="122")=>{for(x=1;;_+=(1+x%2)*(_[x]>1?11:1))console.log(_[++x-2])}

ニールのおかげで1ビット節約

Tanks to Shaggy、私の間違いを修正し、1ビット節約しました。

f = (_="122") => {
  for(x=1;x<20;_+=(1+x%2)*(_[x]>1?11:1))
    document.getElementById('content').innerHTML += '   ' + _[++x-2]
}
f()
<div id="content"></div>


これは私のJava 8の回答のポートのように見えますが(のx=0代わりにx=1)、@ Shaggyは確かに正しいです:これは現在の形式では機能しません,i=100;i-->0最初の100アイテムを見るために一時的に追加する必要があります60秒待ってから出力を確認してください)。ただし、なぜ機能しないのかわかりません。JSは私のものではありません。
ケビンクルーッセン

問題は次のとおりである:1.開始x0に代わりの1(@KevinCruijssenが述べたように)と、2.かどうかをチェックするxだけで、これまで1又は2であることができ、文字列内の文字目は、49以上である
シャギー

2
以下は、修正されたソリューションの完全にテストされていない(ただし、完全にはテストされていない)バージョンです。tio.run
Shaggy

(_[x]*10-9)より(_[x]>1?11:1)
-l4m2

2

アップルシード、89バイト

(def K(lambda()(concat(q(1 2))(drop 2(flatten(zip-with repeat-val(cycle(q(1 2)))(K)))))))

K引数をとらない関数を定義し、Kolakoskiシーケンスを無限リストとして返します。オンラインでお試しください!

このアプローチは、totalhumanhumanのHaskell answerに触発されました。私の最初のアプローチはより長くおそらくO(2 ^ n)でした。:^ P

非ゴルフ

(def kolakoski
 (lambda ()
  (concat (list 1 2)
   (drop 2
    (flatten
     (zip-with repeat-val
      (cycle (list 1 2))
      (kolakoski)))))))

戻りリストはで始まります(1 2)。その後、残りの部分を生成するために(内部からの読み取り):

  • (kolakoski)Kolakoskiシーケンスリストを取得するために再帰的に呼び出します(遅延評価のため、リストがまだ完全に生成されていなくてもかまいません)
  • (cycle (list 1 2)) 無限リストを作成します (1 2 1 2 1 2 ...)
  • 関数を使用して、2つの無限リストをまとめて圧縮しますrepeat-val。これが繰り返されます12からcycleKolakoskiリスト内に関連付けられた値に応じて、リストの1つのまたは2つの回。結果:((1) (2 2) (1 1) ...)
  • flatten そのリスト (1 2 2 1 1 ...)
  • 我々はすでにから最初の2つの項を持っている(concat (list 1 2)ので、我々は、drop生成されたリストから、最初の二つの重複を避けるために。

2

スタックス、12 バイト

╦╥2Bïß▄n»-[╒

実行してデバッグする

これは、同じプログラムのASCII表現です。

G@}2R;D{|;^]*m$

xが入力である場合、シーケンスをx回展開します。次に、0 番目のインデックスが付けられたx 番目の要素を出力します。

G }             G jumps to trailing } and returns when done
 @              get xth element in array
   2R           [1, 2]
     ;D         repeat the rest x times
       {     m  map array using block
        |;^]    produces [1] and [2] alternately
            *   repeat array specified number of times
              $ flatten array

無限のストリームとして出力を生成する12バイトのボーナスソリューションを次に示します。[実行]を押して開始します。


2

R、63バイトまたは61バイト

実装1:シーケンスのn 番目の項を出力します。

x=scan()
a=c(1,2,2)
for(n in 3:x)a=c(a,rep(2-n%%2,a[n]))
a[x]

実装2:シーケンスの最初のn項を出力します。

x=scan()
a=c(1,2,2)
for(n in 3:x)a=c(a,rep(2-n%%2,a[n]))
a[1:x]

(違いは最後の行のみです。)

はい、はい、あなたは私のソリューションが非効率であり、必要以上に多くの用語を計算することを不満に思うかもしれませんが、それでも...

更新: 9バイトを削る@Giuseppeに感謝します。


1
a=c(a,rep(2-n%%2,a[n]))2番目のforループの代わりに使用して、いくつかのバイトを削ります。
ジュゼッペ

@Giuseppe実装、ありがとう!
アンドレイKostyrka

ここでは、ゴルフソリューションの非効率性を気にしません。実際、非効率的なアルゴリズムを使用することは、code-golf tag wikiのヒントの1つです。
Ørjanヨハンセン

2

シェークスピアプログラミング言語、575バイト(ただし欠陥)、または653または623バイト

,.Puck,.Ford,.Act I:.Scene X:.[Enter Puck and Ford]Ford:You big cat!Scene L:.Ford:Is I nicer zero?If so,let us Scene V.Is you nicer a big cat?If so,you is the sum of you a big lie.If so,open heart!Open heart!Scene M:.Puck:Remember you!Is I nicer a cat?You big cat.If so,you cat.Ford:Recall!Is you nicer zero?If not,let us Scene X.Is you nicer a big cat?If not,let us Scene M.You is the sum of you a big lie.Scene V:.Ford:Remember you!Is you worse a big big cat?If not, you big cat.Is you as big as a big cat?If not,you zero.You is the sum of I you.Puck:Recall!Let us Scene L.

激しく争われているSPLカテゴリでは、これはJo Kingの現在のエントリ(583バイト)に勝っていますが、欠陥があることを除きます:まず、TIOバージョン(SPL Webサイトの実装)では実行されませんが、Perlでは実行されますversionなので、おそらくそれは重大な欠陥ではありません。ただし、2番目に、最初の2桁は出力されません。Jo Kingのソリューションでその欠陥を許可した場合、その欠陥のあるソリューションは553バイトになり、欠陥のあるソリューションを破ります。

私のソリューションは2つの理由でTIOで失敗します。ポップされたときにゼロを返す空のスタックに依存しようとしています。そして、誰もステージを出ていなくても、「[Ford and Puckを入力してください」」という最初のシーンに進みます。これらはPerlバージョンの単なる警告です。私はこれらのエラーを修正した場合と、最初の2桁に入れて、私は653バイトに達します。

 ,.Puck,.Ford,.Act I:.Scene I:.[Enter Puck and Ford]Ford:You cat!Open heart!You big cat!Open heart!You zero!Scene X:.Ford:Remember you!You big cat!Scene L:.Ford:Is I nicer zero?If so,let us Scene V.Is you nicer a big cat?If so,you is the sum of you a big lie.If so,open heart!Open heart!Scene M:.Puck:Remember you!Is I nicer a cat?You big cat.If so,you cat.Ford:Recall!Is you nicer zero?If not,let us Scene X.Is you nicer a big cat?If not,let us Scene M.You is the sum of you a big lie.Scene V:.Ford:Remember you!Is you worse a big big cat?If not, you big cat.Is you as big as a big cat?If not,you zero.You is the sum of I you.Puck:Recall!Let us Scene L.

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

623バイトを使用して、Perl実装で完全なシーケンスを生成できます。

,.Puck,.Ford,.Act I:.Scene I:.[Enter Puck and Ford]Ford:You cat!Open heart!You big cat!Open heart!Scene L:.Ford:Is I nicer zero?If so,let us Scene V.Is you nicer a big cat?If so,you is the sum of you a big lie.If so,open heart!Open heart!Scene M:.Puck:Remember you!Is I nicer a cat?You big cat.If so,you cat.Ford:Recall!Is you worse a cat?If so,you big cat!If so,let us Scene L.Is you nicer a big cat?If not,let us Scene M.You is the sum of you a big lie.Scene V:.Ford:Remember you!Is you worse a big big cat?If not, you big cat.Is you as big as a big cat?If not,you zero.You is the sum of I you.Puck:Recall!Let us Scene L.

ただし、このソリューションは他の多くのソリューションと比較して高速であり、リスト全体を保存するのではなく対数のメモリを使用することを指摘します。(これはvaztのCソリューションに似ており、それは遠い関係にあります。)これはゴルフにとって違いはありませんが、それでも満足しています。Perlでは約1分で100万桁を生成できます(たとえば、sedとwcにパイプして桁数を取得する場合)。他のソリューションでは数千桁になる場合があります。

説明

変数のシーケンスを順番に保存します:パックのスタック(下から上)、パックの値、フォードの値、フォードのスタック(上から下)。両端のゼロ値(左側のゼロは空のスタックをポップする可能性があります)を除き、各値はその世代で次に生成される数字であり、次の世代にその親から別の子が必要な場合は2が追加されます シーケンスにN個の非ゼロ値がある場合、深さ優先のツリートラバーサルのような方法で、N番目の世代までのすべての子を生成します。N番目の世代の値のみを出力します。N番目の世代が完全に生成されると、保存された値は実際には世代2から(N + 1)の開始値であるため、左に2を追加して再度開始し、今回は(N + 1 )世代。

アウトライン:シーンX:ここに到達すると、これが新しいトラバースの始まりです。パック== 0。オプションでそのゼロをパックのスタックにプッシュし、パック= 2に設定します。シーンL:Ford == 0の場合、印刷世代に到達しています。そうでない場合は、Vに進みます。印刷の場合、パックの値に2が追加されている場合は、2を削除して2回印刷します。そうでない場合は、一度印刷します。シーンM:これは、パックの値を繰り返し切り替えてシーケンスを繰り返すループです。末尾に到達するまで(Puck == 0)、その場合はXに移動するか、別の子が必要な値に到達するまで(Puck> 2)、その場合は余分な2を減算してVに進みます。 V:ここから先に進みます。Puckが2または4の場合、次世代には現在の親からの2つの子が含まれるため、Ford + = 2になります。シーケンスを進めます。Lに移動して、終了を確認します。


1

axo、13バイト

[:|[1+{#;1;-_

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

説明

これは、私のWumpusの答えの代替ソリューションのポートとして始まりました:

2%)[=]&=[O00.

その結果、18バイトになりました。最終的には、上記の13バイトまでゴルフして、axoの動作に合わせて調整しました。この13バイトのバージョンは、Wumpusで11バイトまで改善されたため、実際にはそのバージョンに近づいています。

Wumpusの場合と同じように、反復iでは、スタックの下部にa(i)-1が保持され、上部にi番目の実行の最初の要素が保持されますが、印刷を除き、全体で01を使用しています。

[:    Store a copy of the top of the stack in register A.
|     Pull up a(i)-1 from the bottom of the stack.
[1+{  Print a(i).
#;    If a(i)-1 is 1, push the value in register A.
1;-   Push another copy of that value and subtract it from 1 to swap
      0 and 1 for the next run.
_     Jump back to the beginning of the program.

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