Van EckシーケンスのN番目の用語


41

Van EckシーケンスのN番目の項を出力します。

Van Eckシーケンスは次のように定義されます:

  • 0で始まります。
  • 最後の用語がその用語の最初の出現である場合、次の用語は0です。
  • 最後の用語が以前に発生した場合、次の用語は、最後に発生したステップの戻り数です。

https://oeis.org/A181391

https://www.youtube.com/watch?v=etMJxB-igrc

https://www.youtube.com/watch?v=8VrnqRU7BVU

シーケンス:0,0,1,0,2,0,2,2,1,6,0,5,0,2、...

テスト:

入力| 出力

  • 1 | 0
  • 8 | 2
  • 19 | 5
  • 27 | 9
  • 52 | 42
  • 64 | 0

編集

1インデックスが優先され、0インデックスが許容されます。既に提出されたソリューションの一部が変更される可能性があります。

N期のみお願いします。

同じ(すでに投稿されている部分を除いて)、コードゴルファーとナンバーマニアウォッチャーにはかなりのオーバーラップがあるようです。


9
職場でnumpherphileのビデオを見て、家に帰ったときにこれを投稿しようとしていました。最初にそこに着いたことを呪ってください。:P
Draco18s

17
1インデックス付けする必要がありますか、または0インデックス付けを使用できますか?
ロビンライダー

6
代わりに無限シーケンスを返すか出力できますか?
ジョーキング

2
...または最初のn用語?
シャギー

@ Draco18s同じように、Numberphileのビデオを見た後、これを見たときに投稿するためにここに来ました。
ゲザケレクセニー

回答:


25

JavaScript(ES6)、 46 41  37バイト

n=>(g=p=>--n?g(g[p]-n|0,g[p]=n):p)(0)

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

どうやって?

完全なシーケンスを保存する必要はありません。シーケンスに現れる各整数の最後の位置を追跡するだけです。その目的のために、再帰関数gの基礎となるオブジェクトを使用します。

与えられた項p、現在の位置との距離のみに関心があるため、シーケンスの実際の絶対位置にg[p]を設定する必要はありません。そのため、入力n現在の値を保存するだけで、コード内でデクリメントカウンタとして使用できます。

したがって、距離はg[p]n与えられます。便利なことに、これがpの最初の出現である場合、NaNと評価されます。これは、予想される0に簡単に変換できます。p0

コメント済み

n => (             // n = input
  g = p =>         // g = recursive function taking p = previous term of the sequence
                   //     g is also used as an object to store the last position of
                   //     each integer found in the sequence
    --n ?          // decrement n; if it's not equal to 0:
      g(           //   do a recursive call:
        g[p] - n   //     subtract n from the last position of p
                   //     if g[p] is undefined, the above expression evaluates to NaN
        | 0,       //     in which case we coerce it to 0 instead
        g[p] = n   //     update g[p] to n
      )            //   end of recursive call
    :              // else:
      p            //   we've reached the requested term: stop recursion and return it
)(0)               // initial call to g with p = 0

18

Pythonの369の 63 62バイト

f=lambda n,l=0,*s:f(n-1,l in s and~s.index(l),l,*s)if n else-l

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

注:OutgolferのErikが述べたように、このコードはPython 2でもうまく機能します。

0インデックス(単に全くひねくれたように、けれども、あなたがそれを行うことができます変更することにより、-1インデックスif nif~n:P)

Pythonの豪華なアンパック「スター演算子」を使用して、nゼロに達するまでシリーズを再帰的に構築します。

この関数は、検索のためにシリーズを逆にする必要を避けるために、逆の順序でシリーズを構築します。さらに、実際にすべての要素の否定を保存します。なぜなら、それらを最後に変換することは無料で(そうでなければ-スペースである必要があります)、の~s.index(l)代わりにを使用して、途中でバイトを節約します-~s.index(l)

Pythonタプルに同じfind機能文字列があった場合(エラーが発生する代わりに、見つからない場合は-1を返す)、51バイトになる可能性がありますが、そのような運はありません...


3
実際には、あなたが使用している「スター演算子は、」Pythonの3の開梱作業ではなく、また、Pythonの2に存在する可変引数演算子ではありません
エリックOutgolfer

3
最初のものはありますが、2番目のものsは再帰呼び出しのために展開されていませんか?
ArBo

1
Python 2でテストしましたが、動作します。
エリック・ザ・アウトゴルファー

@EriktheOutgolferうーん、しかし、2番目の使用は展開ではありませんか?関数は、そのような構文を使用するために可変引数をサポートする必要はありません。
ArBo

@ArBo:それと違いはdef func(f, *args): f(*args)ありません; 関数呼び出し内での展開は有効なpy2です。py3-onlyとは、リスト/ dict内包の内部でのアンパック(つまり[1, 2, *s])または変数のアンパックですa, *b = [1,2,3,4]
エーサンキア

9

R、62バイト

function(n){while(sum(F|1)<n)F=c(match(F[1],F[-1],0),F)
+F[1]}

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

リストを逆に作成します。(リストの残り)の(前の値)match最初のインデックスを返し、一致が見つからない場合に返します。F[1]F[-1]0

Fは、ループの最初のパスで初期化されFALSE、強制さ0whileます。


2
matchこの方法でこの問題を構築すると、この問題がどれほど良いかということにwe敬の念を抱きます。本当にきれい。
CriminallyVulgar

2行目のプラス記号はここで何かしますか?私はそれがエッジケースを修正したと仮定しましたが、それを見つけることができません。
CriminallyVulgar

1
@CriminallyVulgarは、それが他に戻るときを強制Fする必要があります。0n==1FALSE
ジュゼッペ

ええ、わかりました。理にかなっています、私は多くの範囲を試しましたが、単一の値ではありませんでした。
CriminallyVulgar

9

Perl 6の47の 42バイト

nwellnhofのおかげで-5バイト

{({+grep(@_[*-1],:k,[R,] @_)[1]}...*)[$_]}

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

シーケンス内の0インデックス付き要素を出力する匿名コードブロック。

説明:

{                                            } # Anonymous codeblock
 (                                      )[$_]  # Return the nth element
                                    ...*       # Of the infinite sequence
  {                            }  # Where each element is
    grep(        :k        )[1]   # The key of the second occurrence
         @_[*-1],                 # Of the most recent element
                   ,[R,] @_       # In the reversed sequence so far
   +     # And numify the Nil to 0 if the element is not found



6

J29 23バイト

1{(,~#|1+}.i.{.)@]^:[&0

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

実際の作業はpower動詞の反復動詞で行われます^:。これは引数[と同じ回数反復し、定数値0で反復を開始します&0...

  • (#|1+}.i.{.)これが反復するものです。分解する...
  • }.i.{.i.リスト{.の末尾からリストの先頭のインデックスを見つけます}.。これは0から始まるインデックスを返すため、現在のアイテムが1つ前に見つかった場合は0を返します。見つからない場合は、リストの長さ、つまりテールの長さを返します。
  • 1+値に1を追加して、0ベースのインデックス付けを修正します。これは、Ven Eckの「どれくらい前まで」は1ベースであるためです。見つからなかった場合、値は完全なリストの長さになります。
  • #|完全なリストの長さで除算すると、前の手順で計算された値の残りを返します。これにより、「見つかりません」が0に変わりますが、他のすべての値は変更されないことに注意してください。
  • ,~リストの先頭に新しい値を追加します。単に便宜上、最後ではなく正面を使用します。
  • 1{ リストの2番目の項目を返します。これは、そのように短くなっているために1回計算しすぎたためです。

6

Python、51バイト

f=lambda n,i=1:n>i and[f(n,i+1),i][f(n-1)==f(n+~i)]

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

出力Falseのために0。仕様を文字通り実装し、のiような最小の正の整数を探しf(n-1)==f(n-i-1)ます。そのような検索がにつながるならi>=n、前の要素は以前に現れなかったので、私たちは作り出し0ます。

以前の値をリストに保存するなどの合理的なことを行う代わりに、関数は必要なときはいつでも、また時には不要なときに、それらをゼロから再帰的に再計算するだけです。これにより、10以上の入力に対して関数の実行が非常に遅くなります。


5

APL(Dyalog Unicode)19 17 バイトSBCS

NPL、Adam、Richard Park、およびH.PWizが、APLを学び、APLの助けを得るのに最適なThe APL Orchardでこの答えを書いてゴルフをしてくれたことに感謝します。

編集: Adámから-2バイト。

⊃(⊢,⍨≢|1∘↓⍳⊃)⍣⎕-1

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

説明

⊃(⊢,⍨≢|1∘↓⍳⊃)⍣⎕-1

                 -1  We initialize our array of results with -1.
 (           )⍣⎕     repeats the train (in parentheses) our input, ⎕, times.
        1∘↓⍳⊃        We take the index of the head (our last element in the sequence).
                     To signify "element not found", this returns the length of the array.
      ≢|             We take our index modulo the length of the array.
                     This turns our "element not found" from the length of the array to 0.
  ⊢,⍨                And we prepend to our array.
                    Finally, we return the first element of the array,
                     which is the most recently-generated.
                     This is the ⍵-th element of the Van Eck sequence.


4

05AB1E、8 バイト

F¯Rćk>Dˆ

n

説明:

F         # Loop the (implicit) input amount of times:
 ¯        #  Push the global array
  R       #  Reverse it
   ć      #  Extract the head; push the remainder and the head to the stack
    k     #  Get the 0-based index of the head in the remainder (-1 if not found)
     >    #  Increase it by 1 to make it 1-indexed (or 0 if not found)
      Dˆ  #  Add a copy to the global array
          # (after the loop, output the top of the stack implicitly as result,
          #  which is why we need the `D`/duplicate)

1
それは冒とくを検閲する奇妙な方法です!
負の

1
@negativeseven Lol、あなたが何を言っているのかを知るのに数分かかりましたが、あなたはF¯Rćk?;)
Kevin Cruijssen

4

Java、96 80 76バイト

n->{int i,v=0,m[]=new int[n];for(;--n>0;m[v]=n,v=i<1?0:i-n)i=m[v];return v;}

難読化されていない:

Function<Integer, Integer> vanEck =
n -> {

    int i;                  // i is the value of n when v was previously encountered
    int v = 0;              // v is the current element of vanEck sequence
    int[] m = new int[n];   // m[v] is the value of n when v was previously encountered

    while (--n > 0) {       // n is used as a decrementing counter

        i = m[v];
        m[v] = n;
        v = i == 0 ? 0 : i - n;
    }

    return v;
};

2
whileループをforループに変更することで、数バイトを削除できるはずです。
メガトム

1
こんにちは、あなたはの宣言をインライン化することにより、ゴルフより可能性int[]int宣言し、また使用<1の代わりに==0。例:int f(int n){int l[]=new int[n],i=0,j,v=0;while(++i<n){j=l[v];l[v]=i;v=j<1?0:i-j;}return v;}
オリビエグレゴワール

2
そして今、ラムダと、@ MegaTomが言及している合計80バイトのゴルフ:n->{int l[]=new int[n],i=0,j,v=0;for(;++i<n;l[v]=i,v=j<1?0:i-j)j=l[v];return v;}
オリビエグレゴワール


3

、23バイト

≔⁰θF⊖N«≔⊕⌕⮌υθη⊞υθ≔ηθ»Iθ

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

≔⁰θ

最初の項を0に設定します。

F⊖N«

ループn-1時間。(0インデックスが許容される場合、1バイトの節約のために削除できます。)

≔⊕⌕⮌υθη

次の用語は、前の用語の逆のリストにある現在の用語の増分インデックスです。

⊞υθ

現在の用語を以前の用語のリストに追加します。

≔ηθ

現在の用語を次の用語に設定します。

»Iθ

ループの最後に現在の用語を出力します。



2

ゼリー、8 バイト

ẎiḢ$;µ¡Ḣ

nnth

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

どうやって?

ẎiḢ$;µ¡Ḣ - Link: n
     µ¡  - repeat this monadic link n times - i.e. f(f(...f(n)...)):
         - (call the current argument L)
Ẏ        -   tighten (ensures we have a copy of L, so that Ḣ doesn't alter it)
   $     -   last two links as a monad:
  Ḣ      -     head (pop off & yield leftmost of the copy)
 i       -     first index (of that in the rest) or 0 if not found
    ;    -   concatenate with L
       Ḣ - head

ファイナルなしで実際に収集したことに注意してください[a(n), a(n-1), ..., a(2), a(1), n]







2

Pythonの3128の 114 111 102 99バイト

102-> 99バイト、Jonathan Frechのおかげ

f=lambda n,i=1,l=[0]:f(n,i+1,l+[l[i-2::-1].index(l[-1])+1if l[-1]in l[:-1]else 0])if n>i else l[-1]

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


条件を無効にし、-代わりに!=を使用してバイトを保存できます。
ジョナサンフレッチ

また、ゴルフには副作用がないように見えるため、タプルの代わりにリストを使用できます。
ジョナサンフレッチ

@JonathanFrechしかし、デフォルトの引数としてリストがある場合、連続した呼び出しでは正しく機能しませんか?
ルオホラ

なぜそうではないのですか?
ジョナサンフレッチ

1
最も可能性が高いのは、以前のスクリプトがリストを変更したためです。つまり、副作用がありませんでした:example
ジョナサンフレッチ




1

CJam(15バイト)

0a{_(#)\+}qi*0=

オンラインデモ。これは完全なプログラムであり、0インデックスが付けられています。

解剖

0a      e# Push the array [0]
{       e# Loop...
  _(#   e#   Copy the array, pop the first element, and find its index in the array
  )\+   e#   Increment and prepend
}qi*    e# ... n times, where n is read from stdin
0=      e# Take the first element of the array

0

Clojure、69バイト

#((fn f[i c t](if(= i 1)t(f(dec i)(assoc c t i)(-(or(c t)i)i))))%{}0)

悲しいことに、より機能的なアプローチの方が長いようです。


0

DC、94 91 90バイト

プログラム中に入力が行われます。これをファイルに保存し、「dc」を実行して実行します。間違いなく最短ではありませんが、DCでこのような課題を楽しんでいます。入力は、必要に応じて1から始まるインデックスです。

[st1si0swlbxltlwlu1-sulu0!=m]sm[dlt=qSsli1+siz0!=b0siLs]sb[0pq]sf[lisw2Q]sq?2-dsu1>f0dlmxp

Main control macro
[st                         ]sm   save top value as target
[  1si0sw                   ]sm   reset i to 1 and w to 0
[        lbx                ]sm   execute macro b to get next value in w
[           ltlw            ]sm   restore target to the stack and add w to the stack
[               lu1-su      ]sm   decrement the user inputted variable
[                     lu0!=m]sm   if the user inputted variable is not 0 recurse

Next value finder macro
[dlt=q                  ]sb     if the value on the stack is the target, quit
[     Ss                ]sb     save top value to s register
[       li1+si          ]sb     increment i register
[             z0!=b     ]sb     recurse if still more values            
[                  0si  ]sb     set i to 0 (will be saved to w if relevant)
[                     Ls]sb     move top value of s register to stack

[lisw2Q]sq   Load i, save it to w, and then quit this macro and the one that called it

[0pq]sf print 0 and quit the program
```


0

Pyth、18バイト

VQ=Y+?YhxtYhY0Y;hY

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

シーケンスを逆に作成し、最初の要素(シーケンスの最後の要素)を出力します。

VQ                 # for N in range(Q) (Q=input)
  =Y+         Y    # Y.prepend(
        xtY        #   Y[1:].index(    )
           hY      #               Y[0]
       h           #                     +1
     ?Y      0     #                        if Y else 0)
               ;hY # end for loop and print Y[0]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.