Mô phỏng bất kỳ máy tự động di động 1D


14

Các thách thức

Bạn phải viết một chương trình hoàn chỉnh lấy bảy số từ STDIN và in lịch sử hai chiều của máy tự động di động (CA) sang STDOUT. Đây là mã golf.

Định dạng đầu vào Đầu vào sẽ là bảy số nguyên / chuỗi được phân tách bằng dấu phẩy. Số đầu tiên là số của quy tắc theo mã Wolfram (tên tiêu chuẩn cho mỗi quy tắc). Thứ hai là cấu hình bắt đầu ban đầu. Phần thứ ba và thứ tư mô tả mẫu nào và số lần được thêm vào bên trái của cấu hình bắt đầu. như đệm. Thứ năm và thứ sáu làm tương tự cho phía bên phải. Số cuối cùng là số lượng thế hệ để chạy mô phỏng.

Vì vậy, một ví dụ về đầu vào là 90,11,0,4,0,4,5. Điều này sẽ cho chương trình của bạn biết rằng bạn đang chạy quy tắc 90 . Nó cũng sẽ cho chương trình biết rằng bạn muốn cấu hình ban đầu 11với chuỗi được 0nối 4 lần vào cả hai đầu, vì vậy mẫu bắt đầu thực tế là 0000110000. Nó cũng cho biết chương trình của bạn để chạy mô phỏng này trong 5 thế hệ.

Đầu ra Chương trình của bạn sẽ in toàn bộ mảng ô mỗi thế hệ (được phân tách bằng dòng mới), để đầu ra là sơ đồ không gian-thời gian của CA. Đối với mỗi thế hệ, trạng thái của mỗi ô được xác định bởi trạng thái của nó và trạng thái của các ô ở ngay bên trái và bên phải, theo quy tắc được cung cấp làm đầu vào. Các mô phỏng nên bao quanh các cạnh. Điều đầu tiên được in phải là mảng bắt đầu như gen. 0.

Đầu vào 90,11,0,4,0,4,5phải dẫn đến đầu ra sau càng chính xác càng tốt.

0000110000
0001111000
0011001100
0111111110
1100000011
0110000110

Lưu ý rằng trạng thái bắt đầu không được bao gồm trong năm thế hệ. Cũng lưu ý rằng các mô phỏng kết thúc xung quanh các cạnh.

Thêm ví dụ

đầu vào:

184,1100,01,2,01,1,4

đầu ra:

0101110001
1011101000
0111010100
0110101010
0101010101

đầu vào:

0,1011,1,0,0,1,2

đầu ra:

10110
00000
00000

Thông tin thêm về cách thức hoạt động của CA 1D và cách chúng được đánh số


Cũng được thực hiện để bao gồm quy tắc 0 như một trường hợp thử nghiệm.
Peter Taylor

Tôi rất thích quy tắc 90 là một miếng đệm Sierpinki. Đặc biệt vì đó là một phần của thử nghiệm tôi đã làm cho một dự án Codegolf khác .
JoeFish

@JoeFish Chính hình ảnh của bạn đã khiến tôi thử cái này. Tôi muốn đưa ra câu trả lời 8086 - giết 2 con chim - nhưng có lẽ nó sẽ cần các thao tác chuỗi, vì vậy trình giả lập của tôi sẽ không thể chạy nó (chưa).
luser droog

Ai đó đã làm điều đó rồi: pouet.net/prod.php?which=60478
luser droog

Câu trả lời:


5

Golfscript, 77 73 70 ký tự

','/)~\(~:?;~~*@@~*@+\+{1&}/]({[.,{.[3<?256+]{2base}/\~=\(+}*])n@)\+}*

Cảm ơn @Howard, người đã chỉ ra cách lưu 4 ký tự.


Bạn có thể lưu một cái rõ ràng 48--> 1&và tôi cũng nghĩ thêm ba cái nữa. Bạn có thể bỏ qua )trước khối (không tăng bộ đếm) và do đó cũng lưu hai lần bật cuối cùng.
Howard

@ Xin chào, cảm ơn. Những pops ở cuối là hữu ích trong một lần lặp lại trước đó nhưng bạn đã đúng rằng việc loại bỏ chúng có ý nghĩa ngay bây giờ.
Peter Taylor

5

APL (153 ký tự)

∇ cellularautomaton
  i               ← ⍞
  s               ← (i=',') / ⍳ ⍴i
  (b a x c)       ← {i[s[⍵]↓⍳s[⍵+1]-1]} ¨ ⍳4
  (z x x l x r n) ← ⍎i
  y               ← ⍎ ¨ ⊃ ,/ (l / ⊂a) , b , r / ⊂c
  (n+1) (⊃⍴,y) ⍴ '01'[1+⊃ ,/ y,{({(z ⊤⍨ 8/2)[8 - 2⊥¨ 3 ,/ (⊃⌽⍵),⍵,⊃⍵]}⍣⍵)y} ¨ ⍳n]
∇

Và ở dạng ít đọc hơn, ngắn hơn một chút:

i←⍞⋄s←(i=',')/⍳⍴i⋄b a x c←{i[s[⍵]↓⍳s[⍵+1]-1]}¨⍳4⋄z x x l x r n←⍎i⋄y←⍎¨⊃,/(l/⊂a),b,r/⊂c⋄'01'[1+⊃,/y,{({(z⊤⍨8/2)[8-2⊥¨3,/(⊃⌽⍵),⍵,⊃⍵]}⍣⍵)y}¨⍳n]⍴⍨(1+n),⊃⍴,y

Thí dụ:

      cellularautomaton
26,00110,01,4,10,6,7
0101010100110101010101010
1000000011100000000000001
0100000110010000000000011
0010001101101000000000110
0101011001000100000001101
0000010110101010000011000
0000100100000001000110100
0001011010000010101100010

Tôi chắc chắn có chỗ để cải thiện (tôi thậm chí đã tìm thấy một vài thay đổi trong khi viết bài này!), Nhưng một số trong đó có thể liên quan đến những thay đổi cơ bản và tôi không thể đứng nhìn chằm chằm vào APL nữa. Biến thể của APL được sử dụng ở đây là Dyalog APL .


4

Ruby, 165 159 ký tự

a=gets.split ?,
b=a.map &:to_i
c=(x=a[2]*b[3]+a[1]+a[4]*b[5]).chars.map &:hex
(0..b[6]).map{puts c*''
c=(1..w=x.size).map{|i|b[0]>>c[i-1]*2+c[i%w]+c[i-2]*4&1}}

Biên tập: Tôi tìm thấy một số nơi cho các cải tiến nhỏ.

Chạy ví dụ:

> 30,1,0,20,0,20,20
00000000000000000000100000000000000000000
00000000000000000001110000000000000000000
00000000000000000011001000000000000000000
00000000000000000110111100000000000000000
00000000000000001100100010000000000000000
00000000000000011011110111000000000000000
00000000000000110010000100100000000000000
00000000000001101111001111110000000000000
00000000000011001000111000001000000000000
00000000000110111101100100011100000000000
00000000001100100001011110110010000000000
00000000011011110011010000101111000000000
00000000110010001110011001101000100000000
00000001101111011001110111001101110000000
00000011001000010111000100111001001000000
00000110111100110100101111100111111100000
00001100100011100111101000011100000010000
00011011110110011100001100110010000111000
00110010000101110010011011101111001100100
01101111001101001111110010001000111011110
11001000111001111000001111011101100010001

3

C, 303 305 301 294 292

304 Chỉnh sửa: Rất tiếc. Quên điều đócalloc() mất hai arg. Nó đã nổ tung trên đầu vào lớn hơn.

301 Chỉnh sửa: Ah HA! Đã sử dụng của tôicalloc() boo-boo để lưu thêm 2 byte bằng cách tăng kích thước khối của bộ nhớ được yêu cầu.

294 Chỉnh sửa: Đã phá vỡ 300! Loại bỏ một trong nhữngstrcat() s và điều chỉnh một vài vòng lặp. Phải sử dụng tối đa munch, đó là nhiều niềm vui để nói như sử dụng.

292 Chỉnh sửa: Không cần +2 phân bổ bộ nhớ.

Tôi đã sử dụng câu trả lời của luser droog làm ý tưởng cơ bản, nhưng đã thay đổi thuật toán gói, cũng như rất nhiều điều chỉnh và bao thanh toán từ các hằng số.

r,A,C,n,j;main(){char*s,*p,*t,a[9],b[9],c[9];scanf("%d,%[01],%[01],%d,%[01],%d,%d",&r,b,a,&A,c,&C,&n);for(s=calloc(A+++C,9);A--;)strcat(s,A?a:b);for(;C--;)strcat(s,c);p=strdup(s);for(C=strlen(s);A++<n;puts(s),t=p,p=s,s=t)for(j=C;j--;)p[j]=(1<<(s[j?j-1:C-1]*4+s[j]*2+s[(j+1)%C])-336)&r?49:48;}

r,A,C,n,j;
main(){
    char*s,*p,*t,a[9],b[9],c[9];
    scanf("%d,%[01],%[01],%d,%[01],%d,%d",&r,b,a,&A,c,&C,&n);
    for(s=calloc(A+++C,9);A--;)
        strcat(s,A?a:b);
    for(;C--;)
        strcat(s,c);
    p=strdup(s);
    for(C=strlen(s);A++<n;puts(s),t=p,p=s,s=t)
        for(j=C;j--;)
            p[j]=(1<<(s[j?j-1:C-1]*4+s[j]*2+s[(j+1)%C])-336)&r?49:48;
}

ảnh chụp màn hình1

ảnh chụp màn hình2


1
Bạn quên làm cho nó bắt đầu C,A,! :)
luser droog

cho vô số bộ nhớ, những gì về brk()? rồi p=s+C+1;đâu đó.
kẻ lừa đảo người lái xe

1
+1 lần nữa để sử dụng +++!
luser droog

Haha! Thay đổi tất cả %[01]thành %s! -9 (... nhiều năm sau)
kẻ lừa đảo người lái xe

1
@luserdroog điều này không hoạt động vì% s tham lam và ăn cả dấu phẩy và các chữ số khác.
JoeFish

2

C (487 484 418 với khoảng trắng bị xóa)

* Giảm 66 với sự giúp đỡ từ JoeFish *

C,A,r,n,j;main(){char*s,*p,*t,a[9],b[9],c[9];
    scanf("%d,%[01],%[01],%d,%[01],%d,%d",&r,b,a,&A,c,&C,&n);
    s=malloc(strlen(a)*A+strlen(b)+strlen(c)*C+3);*s=0;
    strcat(s,"0");
    for(;A--;)strcat(s,a);
    strcat(s,b);
    for(;C--;)strcat(s,c);
    strcat(s,"0");
    p=malloc((C=strlen(s)-1)+2);
    for(;n--;){
    *s=s[C-1];
    s[C]=0;
    puts(s+1);
    s[C]=s[1];
    for(j=1;s[j+1];j++)
        p[j]=(1<<(s[j-1]-48)*4+(s[j]-48)*2+s[j+1]-48)&r?49:48;
    t=p;p=s;s=t;
    }
    s[C]=0;
    puts(s+1);
}

bản thảo

ồ @ Z1 ~
$! m
làm ca
cc ca.c -o ca
ca.c: 1: 1: cảnh báo: định nghĩa dữ liệu không có loại hoặc lớp lưu trữ
ca.c: Trong chức năng 'chính':
ca.c: 2: 5: cảnh báo: khai báo ngầm không tương thích của hàm tích hợp 'scanf'
ca.c: 3: 7: cảnh báo: khai báo ngầm không tương thích của hàm tích hợp 'malloc'
ca.c: 3: 14: cảnh báo: khai báo ngầm không tương thích của hàm tích hợp 'strlen'
ca.c: 4: 5: cảnh báo: khai báo ngầm không tương thích của hàm tích hợp 'strcat'

ồ @ Z1 ~
$ vang 90,11,0,4,0,4,5 | ca
-bash: ca: lệnh không tìm thấy

ồ @ Z1 ~
$ vang 90,11,0,4,0,4,5 | ./ca
0000110000
0001111000
0011001100
0111111110
1100000011
0110000110


Đẹp. Bạn có thể cạo khá nhiều byte bằng cách đặt các intbiến của mình thành toàn cục và xóa #include: r,A,B,C,n,i,j; main(){char *s...
JoeFish

Lưu một bó trong các forvòng lặp của bạn :for(;A--;)strcat(s,a);
JoeFish

Và sử dụng lại ACsau này để bạn không phải khai báo ihay Bgì cả. p=malloc((C=strlen(s))+1); --C; strcpy(p,s); for(A=0;A<n;A++){Xin lỗi, tôi sẽ dừng ngay bây giờ :)
JoeFish

Ok, tôi nói dối, một cái nữa. Loại bỏ 2 bye bằng cách loại bỏ --C;: p=malloc((C=strlen(s)-1)+2);. Tôi nghĩ rằng mã golf là thú vị hơn là đến với nó ở nơi đầu tiên!
JoeFish

Tôi không chắc chắn về việc loại bỏ #includescanflà từ khóa . Nhưng nó có thể ổn vì nó chỉ được gọi một lần. ... Máy cũ của tôi đã chết hôm qua và tôi vẫn đang cài đặt Cygwin. Tôi sẽ kết hợp những thay đổi đó ngay khi tôi có thể kiểm tra nó. Cảm ơn!
luser droog
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.