Nhiệm kỳ thứ n của Van Eck Sequence


41

Xuất ra thuật ngữ thứ N của Chuỗi Van Eck.

Trình tự Van Eck được định nghĩa là:

  • Bắt đầu bằng 0.
  • Nếu thuật ngữ cuối cùng là lần xuất hiện đầu tiên của thuật ngữ đó thì thuật ngữ tiếp theo là 0.
  • Nếu thuật ngữ cuối cùng đã xảy ra trước đó thì thuật ngữ tiếp theo là bao nhiêu bước trở lại là lần xuất hiện gần đây nhất.

https://oeis.org/A181391

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

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

Trình tự: 0,0,1,0,2,0,2,2,1,6,0,5,0,2, ...

Các xét nghiệm:

Đầu vào | Đầu ra

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

BIÊN TẬP

1 chỉ mục được ưu tiên, 0 chỉ mục là chấp nhận được; điều đó có thể thay đổi một số giải pháp đã được gửi.

Chỉ cần thuật ngữ thứ N xin vui lòng.

Tương tự (ngoại trừ việc nhìn thấy nó đã được đăng một phần), có vẻ như người chơi mã và người theo dõi số có một sự trùng lặp khá tốt.


9
Đã xem video numpherphile tại nơi làm việc và sẽ đăng bài này khi tôi về nhà. Nguyền rủa bạn vì đã đến đó trước. : P
Draco18

17
Nó có phải được lập chỉ mục 1 hay chúng ta có thể sử dụng lập chỉ mục 0?
Robin Ryder

6
Thay vào đó chúng ta có thể trả lại hoặc xuất chuỗi vô hạn?
Jo King

2
... Hay những nđiều khoản đầu tiên ?
Xù xì

@ Draco18s Tương tự, tôi đến đây để đăng nó sau khi xem video Numberphile, khi tôi thấy điều này.
Geza Kerecsenyi

Câu trả lời:


25

JavaScript (ES6),  46 41  37 byte

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

Hãy thử trực tuyến!

Làm sao?

Chúng tôi không cần phải lưu trữ đầy đủ trình tự. Chúng ta chỉ cần theo dõi vị trí cuối cùng của mỗi số nguyên xuất hiện trong chuỗi. Chúng tôi sử dụng đối tượng cơ bản của hàm đệ quy cho mục đích đó.g

Đối với một thuật ngữ , chúng ta không cần đặt thành vị trí tuyệt đối thực tế của nó trong chuỗi vì chúng ta chỉ quan tâm đến khoảng cách với vị trí hiện tại. Đó là lý do tại sao chúng ta chỉ có thể lưu trữ giá trị hiện tại của đầu vào , được sử dụng làm bộ đếm giảm dần trong mã.pg[p]n

Do đó, khoảng cách được cho bởi . Thuận tiện, điều này đánh giá NaN nếu đây là lần xuất hiện đầu tiên của , có thể dễ dàng biến thành dự kiến .g[p]np 0p0

Đã bình luận

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 3 , 69 63 62 byte

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

Hãy thử trực tuyến!

Lưu ý: như Erik the Outgolfer đã đề cập, mã này cũng hoạt động tốt trong Python 2.

Được lập chỉ mục 0 (mặc dù, chỉ cần hoàn toàn sai lầm, bạn có thể làm cho nó được lập chỉ mục -1 bằng cách thay đổi if nthành if~n: P)

Làm cho việc sử dụng "toán tử sao" giải nén tuyệt đẹp của Python, để xây dựng đệ quy chuỗi, cho đến khi nđạt đến không.

Hàm xây dựng chuỗi theo thứ tự ngược lại, để tránh phải đảo ngược nó để tìm kiếm. Ngoài ra, nó thực sự lưu trữ các phủ định của tất cả các phần tử, bởi vì chuyển đổi chúng trở lại ở cuối là miễn phí (nếu không -thì phải là một khoảng trắng) và nó tiết kiệm cho chúng ta một byte trên đường đi, bằng cách sử dụng ~s.index(l)thay vì -~s.index(l).

Có thể là 51 byte nếu bộ dữ liệu Python có các findchuỗi chức năng tương tự (trả về -1 nếu không tìm thấy, thay vì tăng lỗi), nhưng không có may mắn như vậy ...


3
Trên thực tế, "toán tử sao" mà bạn đang sử dụng không phải là toán tử giải nén của Python 3, mà là toán tử vararg tồn tại trong Python 2.
Erik the Outgolfer

3
Cái đầu tiên là, nhưng không phải cái thứ hai giải nén scho cuộc gọi đệ quy?
ArBo

1
Tôi đã thử nó trong Python 2 và nó hoạt động.
Erik the Outgolfer

@EriktheOutgolfer hmm, nhưng không phải là lần sử dụng thứ hai giải nén? Hàm không phải hỗ trợ varargs để sử dụng cú pháp như vậy.
ArBo

@ArBo: Không khác gì def func(f, *args): f(*args); giải nén bên trong các cuộc gọi chức năng là py2 hợp lệ. Chỉ có py3 là giải nén bên trong danh sách / hiểu chính tả (nghĩa là [1, 2, *s]) hoặc giải nén các biến : a, *b = [1,2,3,4].
Ehsan Kia

9

R , 62 byte

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

Hãy thử trực tuyến!

Xây dựng danh sách ngược lại; matchtrả về chỉ mục đầu tiên của F[1](giá trị trước đó) trong F[-1](phần còn lại của danh sách), trả về 0nếu không tìm thấy kết quả khớp.

Fđược khởi tạo FALSEvà được ép buộc 0trên đường chuyền đầu tiên của whilevòng lặp.


2
Tôi lo lắng về matchvấn đề này tốt như thế nào khi bạn xây dựng nó theo cách này. Thực sự sạch sẽ.
CriminallyVulgar

Có cộng với dòng thứ hai làm bất cứ điều gì ở đây? Tôi giả sử nó đã sửa một trường hợp cạnh, nhưng tôi không thể tìm thấy nó cho nó.
CriminallyVulgar

1
@CriminallyVulgar nó nên ép buộc Fđể 0khi n==1khác nó sẽ quay trở lại FALSE.
Giuseppe

À, tôi hiểu rồi. Có ý nghĩa, tôi đã thử rất nhiều phạm vi nhưng không phải là giá trị đơn lẻ.
CriminallyVulgar

9

Perl 6 , 47 42 byte

-5 byte nhờ nwellnhof

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

Hãy thử trực tuyến!

Codeblock ẩn danh xuất ra phần tử 0-index trong chuỗi.

Giải trình:

{                                            } # 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

J , 29 23 byte

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

Hãy thử trực tuyến!

Công việc thực sự được thực hiện trong động từ lặp của động từ lũy thừa ^:, lặp đi lặp lại nhiều lần như đối số [, bắt đầu phép lặp với giá trị không đổi 0 &0...

  • (#|1+}.i.{.)Đây là những gì lặp đi lặp lại. Phá vỡ nó ...
  • }.i.{.Tìm chỉ số của i.người đứng đầu danh sách {.trong phần đuôi của danh sách }.. Điều này sẽ trả về một chỉ mục dựa trên 0, vì vậy nếu mục hiện tại được tìm thấy 1 trước đó thì nó sẽ trả về 0. Nếu không tìm thấy, nó sẽ trả về độ dài của danh sách, tức là độ dài của đuôi.
  • 1+Thêm một vào giá trị để sửa cho lập chỉ mục dựa trên 0, vì "khoảng cách bao xa" của Ven Eck là dựa trên 1. Lưu ý rằng nếu không tìm thấy, giá trị sẽ là độ dài của danh sách đầy đủ.
  • #|Trả lại phần còn lại của giá trị được tính trong bước trước đó, khi chia cho độ dài của danh sách đầy đủ. Lưu ý rằng điều này biến "không tìm thấy" thành 0, nhưng giữ nguyên tất cả các giá trị khác.
  • ,~Nối giá trị mới vào phía trước danh sách. Chúng tôi sử dụng mặt trước chứ không chỉ đơn thuần là thuận tiện.
  • 1{ trả về mục thứ 2 trong danh sách, vì chúng tôi đã tính toán quá nhiều lần vì nó ngắn hơn theo cách đó.

6

Python , 51 byte

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

Hãy thử trực tuyến!

Đầu ra Falsecho 0. Triển khai thông số kỹ thuật theo đúng nghĩa đen, tìm kiếm số nguyên dương thấp nhất isao cho f(n-1)==f(n-i-1). Nếu tìm kiếm như vậy dẫn đến i>=n, phần tử trước đó đã không xuất hiện trước đó và chúng tôi sản xuất 0.

Thay vì làm điều gì đó hợp lý như lưu trữ các giá trị trước đó trong danh sách, hàm chỉ tính toán lại chúng một cách đệ quy từ đầu bất cứ khi nào chúng cần và đôi khi không cần thiết. Điều này làm cho hàm chạy rất chậm đối với các đầu vào trên 10 hoặc hơn.


5

APL (Dyalog Unicode) , 19 17 byte SBCS

Rất cám ơn ngn, Adám, Richard Park và H.PWiz đã giúp đỡ họ viết và đánh golf câu trả lời này trong The APL Orchard , một nơi tuyệt vời để học APL và nhận trợ giúp của APL.

Chỉnh sửa: -2 byte từ Adám.

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

Hãy thử trực tuyến!

Giải trình

⊃(⊢,⍨≢|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 byte

F¯Rćk>Dˆ

n

Giải trình:

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
Đó là một cách kỳ lạ để kiểm duyệt thô tục!
âm bảy

1
@negativeeven Lol, tôi mất vài phút để biết ý của bạn là gì, nhưng tôi đoán bạn đang đề cập đến F¯Rćk? ;)
Kevin Cruijssen

4

Java, 96 80 76 byte

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

Không bị xáo trộn:

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
Bạn sẽ có thể loại bỏ một vài byte bằng cách thay đổi vòng lặp while thành vòng lặp for.
MegaTom

1
Xin chào, bạn có thể chơi golf hơn bằng cách nội tuyến tuyên bố int[]trong intlời tuyên bố, và cũng có thể sử dụng <1thay vì ==0. Ví dụ: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;}
Olivier Grégoire

2
Và bây giờ là một lambda, cũng như môn golf được @MegaTom đề cập với tổng số 80 byte: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;}
Olivier Grégoire

1
Cuối cùng, bạn có thể kiểm tra các mẹo để chơi gôn trong Java .
Olivier Grégoire

3

Than , 23 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

≔⁰θ

Đặt thuật ngữ đầu tiên thành 0.

F⊖N«

Vòng lặp n-1thời gian. (Nếu lập chỉ mục 0 là chấp nhận được, có thể xóa bỏ để lưu 1 byte.)

≔⊕⌕⮌υθη

Thuật ngữ tiếp theo là chỉ số tăng của thuật ngữ hiện tại trong danh sách đảo ngược của các điều khoản trước đó.

⊞υθ

Thêm thuật ngữ hiện tại vào danh sách các điều khoản trước đó.

≔ηθ

Đặt thuật ngữ hiện tại cho thuật ngữ tiếp theo.

»Iθ

In thuật ngữ hiện tại ở cuối vòng lặp.



2

Thạch , 8 byte

ẎiḢ$;µ¡Ḣ

nnth

Hãy thử trực tuyến!

Làm sao?

Ẏ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

Lưu ý rằng không có trận chung kết, chúng tôi thực sự đã thu thập[a(n), a(n-1), ..., a(2), a(1), n]







2

Python 3 , 128 114 111 102 99 byte

102 -> 99 byte, nhờ 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]

Hãy thử trực tuyến!


Bạn có thể phủ nhận điều kiện của mình và sử dụng -thay vì !=để lưu một byte.
Jonathan Frech

Ngoài ra, vì golf của bạn dường như không có tác dụng phụ, bạn có thể sử dụng danh sách thay vì bộ dữ liệu.
Jonathan Frech

@JonathanFrech Nhưng nếu tôi có một danh sách làm đối số mặc định thì nó sẽ không hoạt động chính xác cho các cuộc gọi liên tiếp?
ruohola

Tại sao không nên?
Jonathan Frech

1
Rất có thể là do tập lệnh trước của bạn đã sửa đổi danh sách, tức là không có tác dụng phụ: ví dụ .
Jonathan Frech


1

Python 3 , 112 byte

a=[0]
for _ in a*int(input()):k=a[-1];a+=k in a[:-1]and[a[::-1].index(k)+~a[-2::-1].index(k)]or[0]
print(-a[-2])

Hãy thử trực tuyến!

-3 byte nhờ vào mypetlion


Dòng thứ hai có thể trở thành for _ in a*int(input()):k=a[-1];a+=k in a[:-1]and[a[::-1].index(k)+~a[-2::-1].index(k)]or[0]để lưu 3 byte.
mypetlion

@mypetlion cảm ơn
HyperNeutrino


1

CJam (15 byte)

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

Bản demo trực tuyến . Đây là một chương trình đầy đủ và được lập chỉ mục 0.

Mổ xẻ

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 byte

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

Đáng buồn là một cách tiếp cận chức năng hơn dường như dài hơn.


0

DC, 94 91 90 byte

Đầu vào được thực hiện trong chương trình. Lưu cái này vào một tập tin và sau đó làm "dc" để chạy. Chắc chắn không phải là ngắn nhất, nhưng tôi có niềm vui với những thử thách như thế này trong dc. Đầu vào là chỉ số dựa trên 1, như ưu tiên.

[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

C ++ (tiếng kêu) , 241 235 234 219 197 189 byte

197 -> 189 byte, nhờ có trần

#import<bits/stdc++.h>
int f(int n,int i=0,std::vector<int>l={0}){return~-n>i?l.push_back(find(begin(l),end(l)-1,l[i])-end(l)+1?find(rbegin(l)+1,rend(l),l[i])-rbegin(l):0),f(n,i+1,l):l[i];}

Hãy thử trực tuyến!


0

Bình thường , 18 byte

VQ=Y+?YhxtYhY0Y;hY

Hãy thử trực tuyến!

Xây dựng trình tự ngược lại và in phần tử đầu tiên (thuật ngữ cuối cùng của trình tự).

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]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.