Simulasikan setiap otomat seluler 1D


14

Tantangan

Anda harus menulis program lengkap yang mengambil tujuh angka dari STDIN, dan mencetak sejarah dua dimensi dari automaton seluler (CA) ke STDOUT. Ini golf kode.

Pemformatan Input Input akan terdiri dari tujuh bilangan bulat / string yang dipisahkan oleh koma. Angka pertama adalah jumlah aturan menurut kode Wolfram (nama standar untuk setiap aturan). Yang kedua adalah konfigurasi awal awal. Yang ketiga dan keempat menggambarkan pola apa dan berapa kali harus ditambahkan ke kiri konfigurasi awal. sebagai padding. Yang kelima dan keenam melakukan hal yang sama untuk sisi kanan. Angka terakhir adalah jumlah generasi untuk menjalankan simulasi.

Jadi, contoh inputnya adalah 90,11,0,4,0,4,5. Ini akan memberi tahu program Anda bahwa Anda menjalankan aturan 90 . Itu juga harus memberitahu program bahwa Anda ingin konfigurasi awal 11dengan string 0ditambahkan 4 kali untuk kedua ujungnya, sehingga pola awal yang sebenarnya adalah 0000110000. Ini juga memberi tahu program Anda untuk menjalankan simulasi ini selama 5 generasi.

Output Program Anda harus mencetak seluruh array sel setiap generasi (dipisahkan oleh baris baru), sehingga outputnya adalah diagram ruang-waktu dari CA. Untuk setiap generasi, keadaan setiap sel ditentukan oleh keadaannya dan keadaan sel di sebelah kiri dan kanan langsung, sesuai dengan aturan yang diberikan sebagai input. Simulasi harus membungkus ujung-ujungnya. Hal pertama yang dicetak haruslah array awal sebagai gen. 0.

Input 90,11,0,4,0,4,5harus menghasilkan output berikut setepat mungkin.

0000110000
0001111000
0011001100
0111111110
1100000011
0110000110

Perhatikan bahwa kondisi awal tidak termasuk dalam lima generasi. Perhatikan juga bahwa simulasi membungkus ujung-ujungnya.

Lebih banyak contoh

memasukkan:

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

keluaran:

0101110001
1011101000
0111010100
0110101010
0101010101

memasukkan:

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

keluaran:

10110
00000
00000

Informasi lebih lanjut tentang cara kerja 1D CA dan bagaimana mereka diberi nomor


Dilakukan dengan baik untuk memasukkan aturan 0 sebagai test case.
Peter Taylor

Saya kagum bahwa aturan 90 adalah Gasket Sierpinski. Terutama karena itu adalah bagian dari pengujian yang saya lakukan untuk proyek Codegolf lain .
JoeFish

@ JoFish Gambar Anda yang membuat saya mencoba yang ini. Saya ingin membuat jawaban 8086 - membunuh 2 burung - tetapi mungkin membutuhkan operasi string, jadi emulator saya tidak akan dapat menjalankannya (belum).
luser droog

Seseorang sudah melakukannya: pouet.net/prod.php?which=60478
luser droog

Jawaban:


5

Golfscript, 77 73 70 karakter

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

Terima kasih kepada @Howard, yang menunjukkan cara menyimpan 4 karakter.


Anda dapat menyimpan yang jelas 48--> 1&dan saya pikir juga tiga lagi. Anda dapat menghilangkan )sebelum blok (tidak menambah penghitung) dan karena itu juga menyimpan dua muncul terakhir.
Howard

@ Howard, terima kasih. Pop tersebut pada akhirnya berguna dalam iterasi sebelumnya tetapi Anda benar bahwa menghilangkannya masuk akal sekarang.
Peter Taylor

5

APL (153 karakter)

∇ 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]
∇

Dan dalam bentuk yang kurang mudah dibaca, sedikit lebih pendek:

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

Contoh:

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

Saya yakin ada ruang untuk perbaikan (saya bahkan menemukan beberapa perubahan saat menulis posting ini!), Tetapi beberapa di antaranya bisa melibatkan perubahan mendasar, dan saya tidak tahan lagi menatap APL. Varian APL yang digunakan di sini adalah Dyalog APL .


4

Ruby, 165 159 karakter

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

Sunting: Saya menemukan beberapa tempat untuk peningkatan kecil.

Contoh dijalankan:

> 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

305 Sunting: oops. Lupa itu calloc()butuh dua argumen. Itu meledak pada input yang lebih besar.

301 Sunting: Ah HA! Menggunakan calloc()boo-boo saya untuk menghemat 2 byte lebih banyak dengan menaikkan ukuran blok dari memori yang diminta.

294 Sunting: Rusak 300! Dieliminasi salah satu strcat()dan tweak beberapa loop. Harus menggunakan mengunyah maksimal, yang menyenangkan untuk dikatakan sebagai penggunaan.

292 Sunting: Tidak perlu +2alokasi memori.

Saya menggunakan jawaban luser droog sebagai ide dasar, tetapi mengubah algoritma pembungkusan, serta banyak mengutak-atik dan memfaktorkan konstanta.

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

tangkapan layar1

tangkapan layar2


1
Anda lupa untuk memulainya C,A,! :)
luser droog

untuk banyak memori, bagaimana brk()? lalu di p=s+C+1;suatu tempat.
luser droog

1
+1 lagi untuk digunakan +++!
luser droog

Ha ha! Ubah semua %[01]untuk %s! -9 (... bertahun-tahun kemudian)
luser droog

1
@luserdroog ini tidak berfungsi karena% s serakah dan memakan koma dan digit lainnya juga.
JoeFish

2

C (487 484 418 dengan spasi dihapus)

* Turun 66 dengan bantuan dari 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);
}

naskah

josh @ Z1 ~
$! m
membuat ca
cc ca.c -o ca
ca.c: 1: 1: peringatan: definisi data tidak memiliki tipe atau kelas penyimpanan
ca.c: Dalam fungsi 'utama':
ca.c: 2: 5: peringatan: deklarasi implisit yang tidak kompatibel dari fungsi built-in 'scanf'
ca.c: 3: 7: peringatan: deklarasi implisit yang tidak kompatibel dari fungsi built-in 'malloc'
ca.c: 3: 14: peringatan: deklarasi implisit yang tidak kompatibel dari fungsi bawaan 'strlen'
ca.c: 4: 5: peringatan: deklarasi implisit yang tidak kompatibel dari fungsi bawaan 'strcat'

josh @ Z1 ~
$ echo 90,11,0,4,0,4,5 | ca
-bash: ca: perintah tidak ditemukan

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


Bagus. Anda dapat mencukur beberapa byte dengan membuat intvariabel Anda mendunia dan menghapus #include: r,A,B,C,n,i,j; main(){char *s...
JoeFish

Simpan banyak di forloop Anda :for(;A--;)strcat(s,a);
JoeFish

Dan gunakan kembali Adan Cnanti jadi Anda tidak perlu mendeklarasikan iatau tidak Bsama sekali. p=malloc((C=strlen(s))+1); --C; strcpy(p,s); for(A=0;A<n;A++){Maaf, saya akan berhenti sekarang :)
JoeFish

Oke, saya bohong, satu lagi. Singkirkan 2 bye dengan menghilangkan --C;: p=malloc((C=strlen(s)-1)+2);. Saya pikir kode golf lebih menyenangkan daripada membuat kode itu!
JoeFish

Saya tidak yakin tentang menghapus #includekarena scanfvariadic. Tetapi mungkin tidak apa-apa karena hanya dipanggil sekali. ... Mesin lama saya mati kemarin, dan saya masih menginstal Cygwin. Saya akan memasukkan perubahan itu segera setelah saya bisa mengujinya. Terima kasih!
luser droog
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.