Electron nảy trong một dây


46

Hãy tưởng tượng một "dây" có nkhoảng trắng. Hãy tưởng tượng thêm rằng có "electron" trong dây đó. Những electron này chỉ sống trong một đơn vị thời gian. Bất kỳ khoảng trống nào trong dây tiếp giáp với chính xác một electron đều trở thành electron. Trong thuật ngữ Game of Life, đây là B1/S.

Ví dụ, đây là một dây có chiều dài 10, với chu kỳ 62.

nhập mô tả hình ảnh ở đây

Quy tắc

  • Đầu vào ,, nlà một số nguyên dương duy nhất.
  • Đầu ra phải là một số nguyên duy nhất biểu thị chu kỳ của một dây có độ dài n.
  • Trạng thái bắt đầu là một electron duy nhất ở một đầu của dây.
  • Thời kỳ không nhất thiết bao gồm trạng thái bắt đầu. Một số độ dài không bao giờ trở lại trạng thái bắt đầu, nhưng tất cả chúng đều là định kỳ.
  • Một dây tĩnh (nghĩa là một dây không có electron) có chu kỳ 1.
  • Điều kiện biên là không định kỳ. Đó là, dây không phải là hình xuyến theo bất kỳ cách nào.

Các trường hợp thử nghiệm

Đặc biệt cảm ơn orlp đã sản xuất danh sách này. (Tôi đã xác minh nó lên tới n = 27.)

1 1
2 2
3 1
4 6
5 4
6 14
7 1
8 14
9 12
10 62
11 8
12 126
13 28
14 30
15 1
16 30
17 28
18 1022
19 24
20 126
21 124
22 4094
23 16
24 2046
25 252
26 1022
27 56
28 32766
29 60
30 62
31 1
32 62
33 60
34 8190
35 56
36 174762
37 2044
38 8190
39 48
40 2046
41 252
42 254
43 248
44 8190
45 8188

Bạn có thể xem các trường hợp thử nghiệm cho n = 2 đến 21 tại đây với trình giả lập Game-of-Life-esque của tôi: Biến thể của cuộc sống .


EDIT: trình tự ở đây đã được xuất bản là A268754 !


tất cả đều là định kỳ Và giai đoạn này được giới hạn bởi 2^n-1, bởi vì đó là số lượng trạng thái khác không có thể có của "dây"
Luis Mendo

@LuisMendo: Trên thực tế, giới hạn trên ít hơn vì các electron không bao giờ liền kề nhau. Chính xác thì ít hơn bao nhiêu, tôi không biết.
El'endia Starman

The period does not necessarily include the starting state. Some lengths never return to the starting state, but all of them are periodic.Bạn có một ví dụ?
edc65

@ edc65: Một dây có chiều dài 5 là ví dụ nhỏ nhất.
El'endia Starman

1
Mạnh hơn, các electron xen kẽ giữa các vị trí lẻ và chẵn, vì vậy khoảng thời gian nhiều nhất là 2 ^ (n / 2 + 1).
xnor

Câu trả lời:


10

Python 2, 148 142 87 byte

n=input()
p=l=1
t=1
h=2
while t!=h:
 if p==l:t,l,p=h,0,p*2
 h=h/2^h*2%2**n;l+=1
print l

Sử dụng thuật toán phát hiện chu kỳ của Brent và do đó thực sự chạy nhanh.


Tôi cũng đã viết một hình ảnh động bằng Python (cả 2 & 3 đều hoạt động). Nó cần pygletphải chạy. Bạn có thể xem hoạt hình bằng cách chạy:

python -m pip install --user pyglet
curl -s https://gist.githubusercontent.com/orlp/f32d158130259cbae0b0/raw/ | python

(Vui lòng tải xuống ý chính và kiểm tra mã trước khi chạy.) Bạn có thể nhấn phím + và - để tăng / giảm n được hiển thị.


Và cuối cùng, đối với những người thích khám phá chuỗi số này hơn nữa, đây là phiên bản có thể đọc được (điều này đã được sử dụng để tạo các trường hợp thử nghiệm ở trên):

# Brent's cycle detection, modified from wikipedia.
def electron_period(n):
    wire_mask = (1 << n) - 1
    power = lam = 1
    tortoise, hare = 1, 2
    while tortoise != hare:
        if power == lam:
            tortoise = hare
            power *= 2
            lam = 0
        hare = ((hare << 1) ^ (hare >> 1)) & wire_mask
        lam += 1
    return lam

Tôi biết đã hơn một năm, nhưng tôi tự hỏi liệu sử dụng HashLife có làm tăng tốc nó không
ASCII - chỉ

7

Toán học, 127 byte

p@n_:=Tr[#2-#]&@@Position[#,Last@#]&@NestWhileList[1~Table~n~ArrayPad~1*18~CellularAutomaton~#&,{1}~ArrayPad~{1,n},Unequal,All]

Giải trình

Quy tắc 18 :

{0,0,0} -> 0
{0,0,1} -> 1
{0,1,0} -> 0
{0,1,1} -> 0
{1,0,0} -> 1
{1,0,1} -> 0
{1,1,0} -> 0
{1,1,1} -> 0

Các trường hợp thử nghiệm

p/@Range[10]
(* {1,2,1,6,4,14,1,14,12,62} *)

7

Python 2, 68 byte

f=lambda n,k=1,l=[]:k in l and-~l.index(k)or f(n,k/2^k*2%2**n,[k]+l)

Phát hiện chu kỳ có thể tốt hơn, nhưng bước lặp là tốt.

k -> k/2^k*2%2**n

Bằng cách biểu diễn mảng dưới dạng số nhị phân k, việc cập nhật có thể được thực hiện bằng cách lấy XOR của kdịch chuyển một bên trái /2và một bên phải *2, sau đó cắt ngắn thành nbyte như %2**n.


4

Python 3 2, 134 121 118 byte

Q=input()
h=[]
n=[0,1]+Q*[0]
while n not in h:h+=[n];n=[0]+[n[d]^n[d+2] for d in range(Q)]+[0]
print len(h)-h.index(n)

Về cơ bản giống như câu trả lời Pyth của tôi , nhưng đã điều chỉnh nó phần nào vì thiếu một số hàm dựng sẵn trong Python.

Phiên bản bị đánh cắp:

length = input()
history = []
new = [0] + [1] + length*[0]
while new not in history:
    history += [new]
    new = [0] + [new[cell]^new[cell+2] for cell in range(length)] + [0]
print len(history) - history.index(new)

4

Bình thường, 39 36 byte

L++Zmx@bd@bhhdQZ-lJ.uyN.[,Z1ZQ)xJyeJ

Sử dụng chức năng "điểm cố định tích lũy" để lặp lại cho đến khi ngay trước khi cấu hình lặp lại và trả về tất cả các cấu hình trung gian dưới dạng danh sách danh sách. Điều này hoạt động vì các quy tắc là xác định và cấu hình của thế hệ tiếp theo là một chức năng của cấu hình hiện tại. Điều này có nghĩa là một khi cấu hình tương tự xuất hiện trở lại, automata đã hoàn thành một chu kỳ.

Sau khi đạt được điều đó (lần lặp cuối cùng của chu kỳ), nó gọi hàm thế hệ tiếp theo lần cuối cùng trên phần tử cuối cùng của danh sách "lịch sử", để có được cấu hình tiếp theo (là cấu hình bắt đầu của một chu kỳ) và tìm chỉ số của nó trong lịch sử. Bây giờ, giai đoạn chỉ đơn giản là độ dài (1 + chỉ số kết thúc chu kỳ) trừ chỉ số bắt đầu chu kỳ.

Trong mã giả pythonic:

                  Z = 0
                  Q = eval(input())
L                 def y(b):                # generates next-gen from current(param)
  ++Zm                return [Z] + map(    # adds head zero padding
    x@bd@bhhd             lambda d: b[d] ^ b[1+ 1+ d],  # xor the states of adjacent cells
    Q                     range(Q))        # implicit range in map
    Z                     + [Z]            # adds end zero padding
-lJ.uyN.[,Z1ZQ)   J = repeatTilRecur(lambda N,Y:y(N), padRight([Z,1],Z,Q)); print( len(J) -
                  # N:value; Y:iteration count
  JxJyeJ              J.index( y( J[-1] ) ) )

Bộ kiểm tra mất quá nhiều thời gian mà máy chủ sẽ giết nó, vì vậy bạn sẽ cần sử dụng chương trình thông thường và kiểm tra từng cái một hoặc cài đặt Pyth (nếu bạn không có) và sử dụng tập lệnh để kiểm tra.


4

Thạch, 19 18 17 byte

H^Ḥ%®
2*©Ç‘СUµiḢ

Mã này tính đầu tiên 2 n bang, vì vậy nó không đặc biệt nhanh hoặc bộ nhớ hiệu quả ...

Hãy thử trực tuyến! hoặc xác minh 16 trường hợp thử nghiệm đầu tiên .

Phiên bản thay thế, 13 byte (không cạnh tranh)

Các phiên bản Jelly trì hoãn thử thách này có tính năng phát hiện vòng lặp tích hợp, cho phép giải pháp vừa ngắn gọn vừa hiệu quả hơn.

H^Ḥ%®
2*©ÇÐḶL

Điều này xử lý các trường hợp thử nghiệm cuối cùng một cách dễ dàng. Hãy thử trực tuyến!

Làm thế nào nó hoạt động

2*©Ç‘СUµiḢ    Main link. Input: n (integer)

2*             Compute 2 ** n.
  ©            Store the result in the register.
     С        Do the following:
   Ç             Apply the helper link, which updates the state, ...
    ‘            2 ** n + 1 times.
               Collect all 2 ** n + 2 intermediate results in a list.
       U       Upend; reverse the list of results.

        µ      Begin a new, monadic chain. Argument: R (list of results)
          Ḣ    Yield and remove the first element of R (final state).
         i     Find its first index in the remainder or R.
               This is the length of the loop.

H^Ḥ%®        Helper link. Argument: s (state, integer)

H            Halve s. This yields a float, but ^ will cast to integer.
  Ḥ          Double s.
 ^           Compute (s ÷ 2) ^ (s × 2).
    ®        Retrieve the value stored in the register (2 ** n).
   %         Compute ((s ÷ 2) ^ (s × 2)) % (2 ** n).

Lưu ý rằng liên kết của trình trợ giúp được áp dụng cho 2 n trong lần lặp đầu tiên, không mã hóa trạng thái hợp lệ. Tuy nhiên, ((2 n ÷ 2) ^ (2 n × 2))% 2 n = (2 n - 1 + 2 n + 1 )% 2 n = 2 n - 1 , đây là một trong những trạng thái bắt đầu có thể.

Vì chúng tôi lặp 2 n + 1 lần, chúng tôi được đảm bảo gặp trạng thái hai lần, giúp phát hiện vòng lặp thành công.


3

CJam, 41 34 31 27 25 byte

Cảm ơn Dennis vì đã tiết kiệm 3 byte. Mượn ý tưởng từ câu trả lời Jelly của anh ấy đã cứu thêm 4 người nữa.

2ri#_){__4*^2/W$%}*]W%(#)

Kiểm tra nó ở đây.

Giải trình

Tôi biểu diễn dây đơn giản như một số nguyên (có bit chỉ vị trí của các electron) thay vì sử dụng danh sách bit thực tế. Trạng thái được cập nhật thông qua các tính toán bitwise khá đơn giản.

Để tìm khoảng thời gian chúng tôi thu thập tất cả các kết quả trung gian trên ngăn xếp, hãy chạy mô phỏng cho 2 n-1 +1 bước, sau đó xác định khoảng thời gian là số phần tử kể từ lần xuất hiện cuối cùng của trạng thái cuối cùng (cộng 1).

Đây là một sự cố về mã:

2ri#   e# Compute 2^n. This has a 1 in the n+1-th bit and zeroes below it. This is
       e# itself not a valid state but will be turned into 2^(n-1) by the first
       e# update.
_)     e# Duplicate and increment to get number of steps to simulate.
{      e# Repeat that many times...
  __   e#   Duplicate the last state twice.
  4*   e#   Multiply by 4, shifting all bits to the left by two positions.
  ^    e#   XOR - we only keep keep those cells where we have exactly one 1-bit
       e#   between both copies, i.e. those that neighboured a single electron
       e#   but shifted up by one position. We don't need handle the survival rule
       e#   explicitly, since electrons can never be adjacent in the first place.
  2/   e#   Divide by 2 shifting all bits back to the right again.
  W$   e#   Copy the initial number 2^n.
  %    e#   Modulo - this simply sets the first bit to 0.
}*
]      e# Wrap all states in an array.
W%     e# Reverse it.
(      e# Pull off the latest state.
#      e# Find its position in the remainder of the array.
)      e# Increment.

2

JavaScript (ES6) 99 104

n=>eval("a=[...Array(n)];k={};for(a[0]=i=1;!k[a=a.map((v,i)=>v?0:a[i-1]^a[i+1])];k[a]=i++);i-k[a]")

Kiểm tra

f = n=>eval("a=[...Array(n)];k={};for(a[0]=i=1;!k[a=a.map((v,i)=>v?0:a[i-1]^a[i+1])];k[a]=i++);i-k[a]")

console.log = x => O.textContent += x + '\n';

;[...Array(45)].map((_, i) => console.log(++i + ' ' + f(i)))
<pre id=O></pre>


2

Haskell, 170 byte

x!pđưa ra phần tử tại chỉ số p nếu trong giới hạn, khác 0. ntính bước tiếp theo. g iđưa ra ibước thứ. c xcho thời gian, nếu bắt đầu với x. fkết thúc tất cả lại với nhau

n x|l<-length x-1=[mod(x!(p-1)+x!(p+1))2|p<-[0..l],let y!q|q<0=0|q>=l=0|1<2=y!!p]
c x=[i-j|i<-[1..],j<-[0..i-1],let g k=iterate n x!!k,g i==g j]!!0
f n=c$1:map(*0)[2..n]

(Lưu ý: được đăng từ điện thoại có trình thông dịch ôm, không đầy đủ tính năng, do đó có thể có lỗi chính tả.)


2

MATL , 38 37 36 35 byte

1Oi(`t0Y)5BX+8L)1=vt6#Xut0)=fdt?w}A

Điều này sử dụng một vòng lặp để duy trì tính toán các trạng thái mới cho đến khi trạng thái mới bằng với bất kỳ trạng thái nào trước đó. Mỗi trạng thái là một vectơ của số không và số không. Các vectơ này được lưu trữ dưới dạng các hàng của một mảng 2D đang phát triển.

Tính toán của từng trạng thái mới được thực hiện bằng cách kết hợp trạng thái hiện tại với chuỗi [1,0,1], chỉ giữ phần trung tâm và đặt thành 0bất kỳ mục nào không có 1.

EDIT (ngày 13 tháng 5 năm 2016) Mã trong liên kết sau đã được sửa đổi một chút theo các thay đổi được giới thiệu trong ngôn ngữ sau khi câu trả lời này được viết

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

1Oi(            % create initial vector [1,0,0,...,0], with size equal to input
`               % do...while loop
  t0Y)          %   duplicate. Get last row of array: most recent vector
  5BX+8L)       %   compute new vector by convolving the most recent one
                %   with [1,0,1] and keeping only the central part
  1=            %   set ones to 1, rest to 0
  v             %   append to 2D array
  t6#Xu         %   compute vector of unique numeric labels, so that equal rows
  t0)=f         %   indices of entries whose value equals that of the last entry.
                %   This will contain the index of the last entry and possibly
                %   another index, in which case we've found a repetition
  d             %   this will either be empty (which is falsy) or contain the
                %   period, which is a nonzero number (and thus truthy)
  t?            %   duplicate. If non-empty (and nonzero)
    w           %     swap to put the 2D-array at the top of the stack. This is
                %     falsy, because it contains at least one zero, even in the
                %     n=1 case (the array is initiallized to 0 in that case)
                %     So the loop will terminate, with the period left on the stack
  }             %   else
    A           %     this transforms the empty array at the top of the stack
                %     into a true value, so that the loop will continue
                %   implicitly end if
                % implicitly end loop
                % implicitly display stack contents (period)

1

Perl 6, 81 byte

{my@h=my$w=2;@h.push($w=$w/2+^$w*2%2**$_)while 2>@h.grep($w);[R-] @h.grep($w,:k)}

Mở rộng và vô dụng một chút

-> $n {
    my @history = my $wire = 2;
    while 2 > @history.grep($wire) {
        @history.push($wire = $wire/2 +^ $wire*2 % 2**$n)
    }
    [R-] @history.grep($wire,:k)
}

Một chút giải thích:

  • [op]giảm danh sách bằng cách sử dụng op. Ví dụ [+] @listsẽ tổng hợp@list
  • Rlà một meta-op đảo ngược các đối số được đưa ra cho một op. Ví dụ 1 R- 3sẽ cho kết quả là 2.

1

C ++, 211 byte

Chơi gôn

#include <bitset>
#include <cstdio>
#define B std::bitset<1<<10>
B m,t(1),h(2);int main() {int p,l;for(scanf("%d",&p);p--;m.set(p));
for(p=l=1;t!=h;h=(h>>1^h<<1)&m,l++)p==l?t=h,p*=2,l=0:0;return !printf("%d",l);}

Với khoảng trắng được thêm vào để dễ đọc

#include <bitset>
#include <cstdio>
#define B std::bitset<1<<10>
B m,t(1),h(2);
int main() {    
    int p,l;
    for(scanf("%d",&p);p--;m.set(p));
    for(p=l=1;t!=h;h=(h>>1^h<<1)&m,l++)p==l?t=h,p*=2,l=0:0;    
    return !printf("%d",l);
}

Thực hành tốt cho bitet của C ++; và một nền giáo dục tuyệt vời học về thuật toán phát hiện chu kỳ của Brent (được sử dụng bởi @orlp)


0

Bình thường, 95 byte

J.[ZQ[1)K_1=bYW<K0=NY aN?hJZ?htJ1ZFTr1tlJ aN?@JTZ?x@JhT@JtT1Z) aN?eJZ?@J_2 1Z=JN=KxbJ abJ;-tlbK

Bạn có thể thử nó ở đây .



0

Ruby, 72 byte

Chức năng ẩn danh.

->n{s=[w=1];c=p
(j=s.index w=w*2%2**n^w/2
j ?c=s.size-j:s<<w)while !c
c}
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.