Mô phỏng hệ thống thẻ tuần hoàn


14

Một hệ thống thẻ tuần hoàn là một mô hình tính toán nhỏ, hoàn chỉnh Turing bao gồm một bảng chữ cái hai ký hiệu (tôi sẽ sử dụng {0,1}), một danh sách các sản phẩm tuần hoàn hữu hạn, không trống bao gồm hai biểu tượng đó và một từ không liên kết cũng bao gồm hai biểu tượng đó.

Ở mỗi bước:

  • yếu tố đầu tiên trong từ bị loại bỏ
  • nếu đó là sản xuất0 hiện tại bị bỏ qua
  • nếu đó là sản phẩm1 hiện tại được nối vào cuối từ .
  • sản xuất tiếp theo trở nên tích cực. Nếu đây là sản phẩm cuối cùng, hãy quay lại sản phẩm đầu tiên.

Hệ thống tạm dừng khi từ trở nên trống rỗng.

Một ví dụ (từ Wikipedia):

Productions: (010, 000, 1111)
Initial word: 11001

Generation  Production   Word (before)            Word (after)
   0           010           11001             →     1001010       
   1           000            1001010          →      001010000
   2           1111            001010000       →       01010000
   3           010              01010000       →        1010000
   4           000               1010000       →         010000000
   5           1111               010000000    →          10000000
   6           010                 10000000    →           0000000010
   7           000                  0000000010 →            000000010
   8           1111                  000000010 →             00000010
   9           010                    00000010 →              0000010

Nhiệm vụ của bạn, nếu bạn chọn chấp nhận nó, là viết một chương trình hoặc chức năng:

  • một danh sách các sản phẩm,
  • từ ban đầu, và
  • một thế hệ,

và in hoặc trả lại từ ở thế hệ đó.

Ví dụ,

cyclic_tag(
      prod=[[0,1,0],[0,0,0],[1,1,1,1]], 
      word=[1,1,0,0,1], 
      gen=4) => [1,0,1,0,0,0,0]

Chi tiết thực hiện:

  • Bảng chữ cái không quan trọng. Bạn có thể sử dụng 01, TrueFalse, TNIL, AB, hoặc thậm chí 10, hoặc bất cứ điều gì khác mà bạn có thể nghĩ ra, miễn là bạn là phù hợp. Tất cả đầu vào và đầu ra phải sử dụng cùng một bảng chữ cái và bạn phải cho biết bạn đang sử dụng để làm 0gì và để làm gì 1.

  • Độ dài của từ phải không bị ràng buộc về mặt lý thuyết. Đó là, bạn không thể mã hóa độ dài từ tối đa. Nếu tôi chạy chương trình của bạn trên một máy tính lý tưởng với dung lượng bộ nhớ vô hạn, về mặt lý thuyết, chương trình của bạn phải có khả năng sử dụng nó. (Bạn có thể bỏ qua các giới hạn của trình thông dịch / biên dịch viên.)

  • Nếu hệ thống đã cho dừng trước khi đạt được thế hệ đã cho, bạn phải trả lại hoặc in từ trống.

  • Sản phẩm trống tồn tại và bạn phải có khả năng xử lý nó. Nếu bạn viết một chương trình đầy đủ, I / O của bạn cũng phải có khả năng xử lý nó.

Chỉnh sửa : Ban đầu tôi dự định thế hệ 0sẽ là từ đầu vào và thế hệ 1là kết quả của bước đầu tiên. Tức là tôi đã có ý định trả lại cột trước . Tuy nhiên , vì tôi chưa đủ rõ ràng trong việc nêu rõ điều này, tôi sẽ chấp nhận cả hai lựa chọn ; đối với mỗi thế hệ, bạn có thể trả về giá trị ở cột trước hoặc cột sau . Bạn phải nói rằng bạn đang theo dõi cột sau , nếu bạn đang làm như vậy. Bạn cũng phải nhất quán trong cột bạn chọn.

Tôi sẽ trao giải mã nhỏ nhất một tuần kể từ bây giờ (27/10/2014).


Ừm, bạn có chắc rằng đầu ra của bạn trong ví dụ là chính xác? Dựa trên ví dụ khác mà bạn đã đưa ra, tôi nghĩ đó là gen 5 ...
FryAmTheEggman

Chúng ta có thể lấy đầu vào theo một thứ tự khác nhau?
Martin Ender

1
@FryAmTheEggman: Đúng vậy, ý tôi là cột 'trước'. Nếu nhiều người mắc lỗi này, tôi sẽ thay đổi câu hỏi của mình để chấp nhận. Tôi thừa nhận tôi đã không rõ ràng.
marinus

@ MartinBüttner: miễn là bạn chỉ định đơn hàng, không thành vấn đề.
marinus

Câu trả lời:


4

GolfScript (17 đến 19 byte tùy thuộc vào định dạng đầu vào và định dạng đầu ra được chấp nhận)

18 byte:

~.@*<{\1,or(@*+}/`

Đưa đầu vào trong biểu mẫu [1 1 0 0 1] [[0 1 0] [0 0 0] [1 1 1 1]] 4và đưa ra đầu ra trong biểu mẫu [1 0 1 0 0 0 0]. (Có thể là 17 byte mà không có lần cuối `nếu đầu ra 1010000là chấp nhận được).

Bản demo trực tuyến

19 byte:

~.@*<{\0`or(1&@*+}/

Đưa đầu vào theo mẫu "11001" ["010" "000" "1111"] 4.

Bản demo trực tuyến

Mổ xẻ

~        # Evaluate input: stack: word productions gen
.@*<     # Produce a list of the right number of productions with suitable repetition
{        # For each of those productions:
  \      #   Bring the word to the top
  0`or   #   Ensure that we don't get an error if the word is empty
  (1&    #   Pop the first char from the word and evaluate it
  @*     #   Repeat the production that many times
  +      #   Concatenate 0 or 1 copies of the production to the rest of the word
}/       # Endforeach

Tín dụng cho giải pháp CJam của Martin Büttner cho ý tưởng tạo ra danh sách các sản phẩm bằng cách lặp lại và cắt ngắn.


Bạn bị ràng buộc với giải pháp CJam mà bạn trích dẫn, vì vậy tôi đã chọn câu trả lời đó. Nếu bạn cạo một byte khác, tôi sẽ xem xét lại :)
mar

@marinus, bạn có chấp nhận phiên bản 17 byte mà tôi đề cập đến trong văn bản câu trả lời của tôi không?
Peter Taylor

Không thấy điều đó, nhưng nó có vẻ hợp lệ. Bạn có lẽ nên đánh dấu nó một chút rõ ràng hơn.
bến tàu

5

Haskell, 55 53 51

(t:w)%p|t=w++p|0<1=w
x%_=x
e w=(!!).scanl(%)w.cycle

điều này sử dụng Truenhư 1Falsenhư 0. chạy ví dụ:

*Main> let t=True ; f=False
*Main> e [t,f,t] [[f,f,f],[t,t,t]] 4
[False,False,False,False,False]

3

CJam, 31 30 28 27 24 18 byte

{_@*<{\_0a?(@*+}/}

Điều này xác định một khối (thứ gần nhất với funcioN), dự kiến ​​đầu vào sẽ nằm trên ngăn xếp như thế này

[1 1 0 0 1] [[0 1 0] [0 0 0] [1 1 1 1]] 9

Nó sẽ tương tự để lại một mảng 0s và 1s trên ngăn xếp.

Kiểm tra nó ở đây. Dán đầu vào một dòng đầu tiên, mã trên dòng thứ ba và nối thêm một ~để thực sự đánh giá khối. Ví dụ

[1 1 0 0 1] [[0 1 0] [0 0 0] [1 1 1 1]] 9
{_@*<{\_0a?(@*+}/}~

Nếu đầu ra không phải có dạng giống như đầu vào

Giải trình:

_@*<{\_0a?(@*+}/
_@               "Duplicate the generation and pull the productions to the top.";
  *<             "Repeat the productions N times and take the first N elements.";
    {         }/ "For each element in that list, run this block.";
     \           "Swap production and current word W.";
      _0a?       "W = (W != []) ? W : [0]. This is to ensure we can unshift an element.";
          (      "Unshift the first 0 or 1 from the word.";
           @     "Rotate the stack, pulling the production to the top.";
            *    "Repeat it 0 or 1 times.";
             +   "Append to the word.";

Trạng thái cuối cùng của từ được để lại trên ngăn xếp.

Cảm ơn Peter Taylor đã khiến tôi xem lại điều này.


1
l~{_,g{('1=@(:Pa+@@P*+}*}*\;28 và vẫn là phạm vi để cải thiện (đặc biệt là (:Pphần), nhưng thời gian cho bữa trưa
Trình tối ưu hóa

@Optimizer Ah, ý kiến ​​hay đấy. Cảm ơn bạn. Và vâng, điều đó :Pcũng làm tôi khó chịu: D
Martin Ender

l~{_,g{(si@(:Pa+@@P*+}*}*\;: 27 và sau khi xem xét nó, :Pthực sự hiệu quả: P
Trình tối ưu hóa

_,gcũng có thể được thay thế bằng _!!nhưng byte tương tự.
Tối ưu hóa

@Optimizer Tôi cũng có thể sử dụng _{...}{}?.
Martin Ender

2

Mathicala, 84 80 77 ký tự

f[_,w_,_]=w;f[p_,{x_,y___},n_/;n>0]:=f[RotateLeft@p,Flatten@{y,p~Take~x},n-1]

Thí dụ:

f[{{0, 1, 0}, {0, 0, 0}, {1, 1, 1, 1}}, {1, 1, 0, 0, 1}, 4]

{1, 0, 1, 0, 0, 0, 0}


2

Số 22

Yêu cầu cả 3 đối số làm đầu vào riêng biệt.

#Vvw=z+tz*@Q%NlQshz)zq

Đưa ra các đối số như:

11001
["010","000","1111"]
4

Giải trình:

                        : Implicit: z = input(); Q=eval(input())
#                       : Loop until an exception is thrown
 Vvw               )    : for N in range(eval(input()))
    =z                  : assign to z
      +tz               : the sum of the tail of z and
         *@Q%NlQ        : Q[N%len(Q)] times
                shz     : the numeric value of the first character in z
                    zq  : print z then throw exception

Con trăn 2 - 61 67 91 105 124

c=lambda p,w,g:g*w and c(p[1:]+p[:1],w[1:]+w[0]*p[0],g-1)or w

Khá Joe - Câu trả lời cơ bản. Giả sử sản xuất trống là [[]].

Cảm ơn @xnor, vì đã chỉ ra rằng chơi golf lúc 2 giờ sáng là một quyết định tồi.

Xin chân thành cảm ơn @xnor, người mà tôi dường như nợ 50% số điểm của mình.

Mẫu vật:

>>> c([[0,1,0],[0,0,0],[1,1,1,1]],[1,1,0,0,1],4)
[1, 0, 1, 0, 0, 0, 0]

1
Chắc chắn nó ngắn hơn để sử dụng lambda và chỉ viết g and wcho x? Ngoài ra, tôi nghĩ g*wnên làm việc để đưa ra một giá trị trung thực khi cả hai đều gkhác không và wkhông trống rỗng.
xnor

Ngoài ra, tôi không hiểu nội tâm if x else w. Không phải xlúc nào cũng đúng vì mã này chỉ chạy if x, hoặc tôi thiếu thứ gì?
xnor

@xnor Chắc chắn, bạn hoàn toàn chính xác :)
FryAmTheEggman

1
Một số môn đánh gôn khác với and/ ortrick và xoay pthay vì tăng dần n:c=lambda p,w,g:g*w and c(p[1:]+p[:1],w[1:]+w[0]*p[0],g-1)or w
xnor

@xnor Cảm ơn :) Ngoài ra, bây giờ bạn đã biến nó thành hàm của 3 biến, tôi nghĩ tôi dịch nó sang Pyth ...
FryAmTheEggman

1

Javascript ES6 - 88 byte

f=(p,w,g,n)=>g?w.replace(/(.)(.*)/,(_,a,b)=>f(p,a*1?b+p[(n=n||0)%p.length]:b,g-1,n+1)):w

Trông rất giống với câu trả lời của Fry vừa xuất hiện trong trình duyệt của tôi. (Không sao chép, tôi thề một cách long trọng.)

Tuy nhiên, có vẻ như anh ta đã đi theo con đường mảng trong khi tôi đã đi theo chuỗi / regex.

Mở rộng:

f = (p,w,g,n) =>
    g ?
        w.replace( /(.)(.*)/, (_,a,b) =>
            f( p, a*1 ? b + p[(n=n||0)%p.length] : b, g-1, n+1 )
        )
    :
        w

Đầu ra mẫu

f(['010','000','1111'],'11001',4)
"1010000"

Bây giờ hãy xem các ngôn ngữ golf đến và tàn sát cả hai chúng tôi. : D


Tôi thực sự đã xóa bài viết của mình vì tôi nhận được câu trả lời khác nhau cho hai ví dụ. Bạn đã thử ví dụ nơi anh ấy đi từng thế hệ? Nó dường như bị tắt bởi một ví dụ so với ví dụ cuộc gọi đầy đủ mà anh ấy đã đưa ra ...
FryAmTheEggman

Và đừng lo lắng, tôi tin rằng bạn đã không sao chép tôi: P
FryAmTheEggman

@FryAmTheEggman: Mine liên tục tạo cột "trước" cho thế hệ được đánh số. Điều này phù hợp với ví dụ trong OP và có vẻ hợp lý rằng "thế hệ 0" sẽ chỉ trả về đầu vào mà không xử lý nó, phù hợp với cách giải thích này. Ngẫu nhiên, tôi đã thêm từ chối trách nhiệm "sao chép" vì các giải pháp tương tự nhau một cách phi thường ở một số khía cạnh. Chúng tôi đã sử dụng cùng tên đối số, cùng cấu trúc đệ quy cơ bản và thậm chí chúng tôi đã thêm cùng một đối số thứ tư ảo , n. Những bộ óc vĩ đại, nhỉ? : D
COTO

Ok, tôi đoán nếu một trong hai chúng tôi sai, cả hai chúng tôi đều sai! Đoàn kết chúng tôi đứng.
FryAmTheEggman

@FryAmTheEggman: Bạn không sai về ông Peppe. ;)
COTO
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.