Wireworld hücresel otomatını simüle edin


24

Wireworld , tellerden akan elektronlara benzemek üzere tasarlanmış hücresel bir otomattır . Basit mekaniği, dijital devrelerin yapımına izin verir. Hatta bütün bir bilgisayarın yapımına bile izin verdi .

Göreviniz seçtiğiniz dilde en kısa Wireworld uygulamasını oluşturmaktır.

Izgaradaki her hücre dört durumdan birine sahiptir. Dört durum "boş", "bakır", "elektron başı" veya "elektron kuyruğu" dur.

  • Boş bir hücre her zaman boş bir hücre olarak kalır
  • Bir elektron kafası her zaman bir elektron kuyruğu olacak
  • Bir elektron kuyruğu her zaman bakır olacak
  • Bir bakır hücre, sekiz komşusundan tam olarak bir veya ikisinin elektron başı olması durumunda elektron başı olacaktır, aksi halde bakır kalır

Bu yarışma, En Kısa Yaşam Oyunu yarışmasına benzer bir stilde olacaktır , ancak birkaç değişiklikle olacaktır.

  • Izgara en az 40 x 40 hücre olmalıdır
  • Şebekenin kenarları etrafa sarılmamalıdır (torus değil). Alanın dışındaki hücrelere sürekli olarak "boş" davranın.
  • Kullanıcıların kendi başlangıç ​​yapılandırmalarına girmeleri mümkün olmalıdır.
  • Boş ekranlara bakmak eğlenceli değil. Program simülasyonu çalıştığı gibi görsel olarak göstermelidir.

Bu kod golf, en az bayt kazanıyor.

Yanıtlar:


6

APL, Dyalog (131)

{h t c←1↓⍵∘=¨F←' htc'⋄⎕SM∘←1 1,⍨⊂N←F[1+⊃+/H h(t∨c≠H←c∧S↑1 1↓1 2∊⍨⊃+/+/K∘.⊖(K←2-⍳3)∘.⌽⊂¯1⌽¯1⊖h↑⍨2+S←25 79)ר⍳3]⋄∇N⊣⎕DL÷4}↑{79↑⍞}¨⍳25

Çıktı ⎕SMpencerede görüntülenir . Simülasyon sonsuz çalışır. Izgara 79x25'tir çünkü ⎕SMpencerenin varsayılan boyutu budur . Elektron kafası h, kuyruğu t, bakırdır c. Program klavyeden başlangıç ​​yapılandırmasını 25 satır olarak okur.

Açıklama:

  • ↑{79↑⍞}¨⍳25: 79x25 ızgarasını oku
  • h t c←1↓⍵∘=¨F←' htc': biri mat, biri kuyruklu, diğeri bakır olan üç matris elde edin. Ayrıca dizeyi F'ye ayarlayın ' htc'.

  • ⎕SM∘←1 1,⍨⊂N←F[1+⊃+/... ר⍳3]: "..." kısmı, öğelerin sırasıyla yeni kafaları, kuyrukları ve bakırı gösteren matrisler olduğu üç uzunluklu bir vektördür. Başlar 1, kuyruklar 2 ve bakır 3 ile çarpılır, daha sonra bu matrisleri bir araya toplar ve bir indeks matrisi vererek bir tane ekleriz F. Ngirdi haline aynı biçimde yeni durum haline gelir ve ⎕SMsol üst köşeden başlayarak ekranda gösterilir .

  • ¯1⌽¯1⊖h↑⍨2+S←25 79: hİki satır ve sütun büyütün, sonra bir tane sağa ve bir tane aşağı döndürerek bir boşluklar kenarlığı ekleyin .

  • ⊃+/+/K∘.⊖(K←2-⍳3)∘.⌽⊂: Matrisi sekiz yönde döndürün ve ardından sonuçtaki matrisleri toplayın, her pozisyonda kafa olan komşuların miktarını verin.

  • 1 2∊⍨: Yalnızca 1 veya 2 komşusu olan 1 konumuna ayarlayın.

  • S↑1 1↓: Daha önce eklediğimiz sınırı kaldır.

  • H←c∧: Yeni kafaların hepsi 1 veya 2 kafa komşusu olan bakır hücrelerdir.

  • t∨c≠H: Yeni bakır hücrelerin hepsi eski kuyruklar ve baş olmayan tüm eski bakır hücrelerdir.

  • H h(... ): Yeni başlıklar Hyukarıda hesaplandığı gibidir, yeni kuyruklar eski başlardır ve yeni bakır hücreleri yukarıda hesaplandığı gibidir.

  • ∇N⊣⎕DL÷4: Saniyenin 1 / 4'ünü bekleyin, ardından işlevi tekrar çalıştırın N.


Bence 40'a 40'lık bir ızgara içeriyorsa daha iyi olur.
mbomb007

6

ALPACA, 82 karakter

ALPACA, özellikle hücresel otomatlar için tasarlanmış bir dildir.

o hiçbir şey değildir; c iletkendir; e elektrondur; t elektron kuyruğu.

state o " ";
state c "c" to e when 1 e or 2 e;
state e "e" to t;
state t "t" to c.

Bu dil ne zaman yayınlandı? Dil için herhangi bir bağlantı var mı?
Doktor

@Optimizer İşte başlıyoruz ! Dili ben yapmadım.
DanTheMan,

4
Güzel. Doğru meydan okuma için doğru dil ..
Optimizer

4

GolfScript ( 125 120 105 100 karakter)

n%{.,,{1${.0=,:w[1,*]\+2*>3<}:^~`{zip^''+.4=5%'`X '@{+}*(7&1>'iX'>+=}+w,%}%"\033[H\033[J"@n*+puts 6.?.?}do

Sayıyorum unutmayın \033onlar bir hazır ile değiştirilebilir, çünkü bir karakter her biri ESCkarakteri. Bu, ANSI kontrol kodlarını kullanır, bu nedenle uyumlu bir tty'ye güvenir. Ayrıca karelerin giriş ızgarası ile başlayarak yazdırıldığını unutmayın.

Moore mahallesini de kullanan bir miktar ızgara üretme ile çakışma var .

Kodlama: boşluk => ; elektron kafası => i; elektron kuyruğu => `; bakır => X.

Yinelemeler arasındaki duraklama, 46656 46656'yı hesaplamak için gereken süredir . Değişen 6.?.?hızını kontrol etmek için olanak sağlar başka ifadeye; Aynı karakter sayısı için bir sonraki en yavaş olanıdır 7.?.?, bu daha yavaştır (çıktı 22 kat daha büyüktür ve doğrusal bir karmaşıklık hesaplaması değildir).

Bir test davası için kullanıyorum

`iXXXXXXXXX
X   X      
   XXX     
X   X      
i`XX XXXXXX

Rosetta Code Wireworld mücadelesinden.


3

Python 371 341 karakter

Evet, o kadar kısa değil, ama etkileşimli bir GUI var!

import matplotlib.pylab as l,scipy.ndimage as i
r=round
w=l.zeros((40,40),int)-1
p=l.matshow(w,vmax=2)
c=p.figure.canvas
def h(e):
 try:w[r(e.ydata),r(e.xdata)]=[0,2,-1][e.button-1]
 except:x=i.convolve(w==2,l.ones((3,3)),int,'constant');w[:]=w/2+((w==0)&(x>0)&(x<3))*2
 p.set_data(w);c.draw()
c.mpl_connect('button_press_event',h)
l.show()

Talimatlar:

Kablo yerleştirmek için farenin sol düğmesine tıklayın

Silmek için farenin sağ tuşuyla tıklayın

Elektron kafasını yerleştirmek için farenin orta düğmesine tıklayın

Otomatı basmak için eksenlerin dışına tıklayın


(x>0)&(x<3)-> (0<x<3). :)
beary605

3

Python ( 243 214)

Kullanılabilirlik ve karakterler arasında bir geçiş yapmaya çalıştım. Izgara 40x40. Girdiler stdin'de verilir. Bir elektron kafası h, elektron kuyruğu t, bakır, cbaşka bir şey boş.

import os
f=raw_input()
while 1:f=''.join('h'if(i=='c')&(0<sum(1 for i in[-1,1,-39,-40,-41,39,40,41]if f[e+i:e+i+1]=='h')<3)else't'if i=='h'else'c'if i=='t'else f[e]for e,i in enumerate(f));os.system('cls');print f

While döngüsü (satır 3) sıkıştırılmamış (koda yerleştirilirse çalışmaz):

while 1:
 for e,i in enumerate(f):
  if(i=='c')&(0<sum(1 for i in[-1,1,-39,-40,-41,39,40,41]if f[e+i:e+i+1]=='h')<3):f[e]='h'
  elif i=='h':f[e]='t'
  elif i=='t':f[e]='c'
  else:f[e]=f[e]  #redundant, but Python needs this to run
 os.system('cls') #cls is shorter than clear, so I used that
 print f

Sana satırları değiştirebilirsiniz 5-7 Tek ifadeyle düşünüyorum: g[e]='h'if(t=='c')&...else't'if i=='h'else'c'if i=='t'else i. Bunun tam olarak çalıştığından emin değilim, ama bu satırlar boyunca bir şeyler çalışmalı
Strigoides

2

C, 355 347 300 294 karakter

Düzenleme: ihtiyacım olmadığını farkettim feof()

Düzenleme: Kaydedilen 47 karakter! Uyku kaldırıldı, hemen hemen tüm parantezlerden kurtuldu, birçok işlem birleştirildi.

Düzenleme: Bugün sonuncusu, çünkü 300 karakter kırdım. Değişti printfiçin puts, ilk karşılaştırma ile şirin bir optimizasyon bulundu.

C, bu tür bir soruna kendini iyi borç vermez, ama hey, golf oynamak eğlencelidir. Bu oldukça kaba bir uygulama, ama ne kadar golf oynayabileceğimi görmek istedim.

Giriş, adında bir metin dosyasıdır i. *Bakır, +elektron kafası, -elektron kuyruğu, boş hücreler için boşluklar ile başlangıç ​​durumunun bir gösterimini içerir . Test için wiki sayfasındaki XOR kapısını kullanıyorum.

   ****-+**
  +        ******
   -*******      *
                ****
                *  *****
                ****
   ********      *
  +        ******
   -****+-*

char*p,t[42][42],s[42][42];
main(i,r,c,n,j)
{
  for(p=fopen("i","r");fgets(s[i++]+1,40,p););

  for(;;getch(),memcpy(s,t,1764))
    for(j=1;j<41;puts(s[j++]+1))
      for(i=1;i<41;)
      {
        p=t[j]+i;
        r=s[j][i++];
        *p=r==43?45:r;
        if(r==45)
          *p=42;
        if(r==42)
          for(r=-1,n=0;r<2;++r,*p=n&&n<3?43:42)
            for(c=-2;c<1;)
              n+=s[j+r][i+c++]==43;
      }
}

Could cond?43:42yazılabilir 42+(cond)? Ve eğer olmasaydı r=s[j][i++];*p=r==43?45:r;if(r==45)*p=42;düşürülebilir eminimr=s[j][i++];*p=r==43?45:r==45?42:r;r=s[j][i++]-43;*p=!r?45:r==2?42:r;
Peter Taylor

1

Python, 234 218 karakter

import time
I=input
C=I()
H=I()
T=I()
R=range(40)
while 1:
 for y in R:print''.join(' CHT'[(C+H+2*T).count(x+y*1j)]for x in R)
 H,T=[c for c in C if 0<sum(1 for h in H if abs(c-h)<2)<3and c not in H+T],H;time.sleep(.1)

Tahtaya, bakır hücrelerinin koordinatlarını (kafa ve kuyruk listelerini içermesi gereken), kafa ve kuyrukları temsil eden üç karmaşık sayı listesi olarak girersiniz. İşte bir örnek:

[3+2j+x for x in range(8)] + [3+4j+x for x in range(8)] + [11+3j+x for x in range(6)] + [2+3j]
[3+2j]
[2+3j]

evalGirdi yaptığımıza dikkat edin, böylece karmaşık sayılar listesi için rastgele karmaşık ifadeler kullanabilirsiniz.


1

QBasic, 309 bayt

Uyarı: golflü versiyon kullanıcı dostu değildir: tuhaf bir giriş metoduna sahiptir, sonsuz bir döngü olarak çalışır ve herhangi bir gecikme yoktur (bu nedenle, bazı sistemlerde çok hızlı çalışır). QBasic ortamınızdaki bir programı nasıl sonlandıracağınızı biliyorsanız sadece çalıştırın. Ungolfed versiyonu tavsiye edilir (aşağıya bakınız).

INPUT w,h
SCREEN 9
FOR y=1TO h
FOR x=1TO w
PSET(x,y),VAL(INPUT$(1))
NEXT
NEXT
DO
FOR y=1TO h
FOR x=1TO w
SCREEN,,0
c=POINT(x,y)
d=c
IF c=7THEN d=1
IF c=1THEN d=6
IF c=6THEN
n=0
FOR v=y-1TO y+1
FOR u=x-1TO x+1
n=n-(POINT(u,v)=7)
NEXT
NEXT
d=7+(n=0OR n>2)
END IF
SCREEN,,1,0
PSET(x,y),d
NEXT
NEXT
PCOPY 1,0
LOOP

Çalıştırmak için, giriş isteminde yapılandırmanızın genişliğini wve yüksekliğini belirtin h. 1 Ardından w*h, hücreler için tek basamaklı kodlar yazın (önce soldan sağa, sonra yukarıdan aşağıya hareket)

  • 0 = boş
  • 6 = tel
  • 7 = sinyal kafası
  • 1 = sinyal kuyruğu

Tüm hücrelere girdikten sonra, simülasyon başlayacaktır (ve programı öldürene kadar sonsuza kadar devam edecektir).

Ungolfed

Daha kullanıcı dostu bir versiyon. Düzeni değiştirmek için DATA, sonunda ifadeleri değiştirin .

Kod POINT, bir pikselin renk değerini ekrandan okuyan işlevden yararlanır . Bu, hücreleri ayrı ayrı dizi olarak saklamamız gerekmediği anlamına gelir. Tüm hücrelerin eşzamanlı olarak güncelleştirildiğinden emin olmak için güncellemeleri ikinci bir "sayfada" yaparız. İfadenin bir sürümünü kullanarak etkin sayfayı değiştirebilir ve SCREENifadeyi kullanarak bir sayfanın içeriğini diğerine kopyalayabiliriz PCOPY.

SCREEN 9

EMPTY = 0 ' Black
HEAD = 7  ' Light gray
TAIL = 1  ' Blue
WIRE = 6  ' Brown/orange

' First two data values are the width and height
READ w, h
' The rest are the initial configuration, row by row
' Read them and plot the appropriately colored pixels
FOR y = 1 TO h
  FOR x = 1 TO w
    READ state$
    IF state$ = "" THEN value = EMPTY
    IF state$ = "H" THEN value = HEAD
    IF state$ = "T" THEN value = TAIL
    IF state$ = "W" THEN value = WIRE
    PSET (x, y), value
  NEXT x
NEXT y

' Loop the simulation until user presses a key
DO UNTIL INKEY$ <> ""
  ' Store current time for delay purposes
  t# = TIMER

  FOR y = 1 TO h
    FOR x = 1 TO w
      ' Active page = display page = 0
      SCREEN , , 0
      ' Get the color value of the pixel at x,y
      oldVal = POINT(x, y)
      IF oldVal = EMPTY THEN
        newVal = EMPTY
      ELSEIF oldVal = HEAD THEN
        newVal = TAIL
      ELSEIF oldVal = TAIL THEN
        newVal = WIRE
      ELSEIF oldVal = WIRE THEN
        neighbors = 0
        FOR ny = y - 1 TO y + 1
          FOR nx = x - 1 TO x + 1
            IF POINT(nx, ny) = HEAD THEN neighbors = neighbors + 1
          NEXT nx
        NEXT ny
        IF neighbors = 1 OR neighbors = 2 THEN
          newVal = HEAD
        ELSE
          newVal = WIRE
        END IF
      END IF
      ' Active page = 1, display page = 0
      SCREEN , , 1, 0
      ' Plot the new value on page 1
      PSET (x, y), newVal
    NEXT x
  NEXT y

  ' Copy page 1 to page 0
  PCOPY 1, 0

  ' Delay
  WHILE TIMER >= t# AND t# + 0.2 > TIMER
  WEND
LOOP

DATA 8,5
DATA T,H,W,W,W,W,W,W
DATA W, , , ,W, , , 
DATA  , , ,W,W,W, , 
DATA W, , , ,W, , , 
DATA H,T,W,W, ,W,W,W

1 Genişlik ve yükseklik için maksimum değerler, hangi ekran modunun kullanıldığına bağlıdır. İçinde SCREEN 9, genişlik 638'e kadar olabilir ve 348'e kadar yükseklik olabilir. SCREEN 7Daha küçük bir çözünürlüğe sahiptir (maksimum 1988'e göre yapılandırma boyutu 318), ancak pikseller daha büyük ve böylece daha kolay görünür (DOS QBasic veya DOSBox emülatöründe - ne yazık ki sadece QB64 daha küçük bir pencere verir).

Örnek çalışma

Archive.org'daki , Ungolfed versiyon, ekran modu 7:

QBasic'deki Wireworld

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.