Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Wireworld is a cellular automaton that was designed to be resemble electrons flowing through wires. Its simple mechanics allow the construction of digital circuits. It has even permitted the construction of an entire computer.

Your mission is to create the shortest Wireworld implementation in your language of choice.

Each cell in the grid has one out of four states. The four states are "blank," "copper," "electron head," or "electron tail."

  • A blank cell will always remain a blank cell
  • An electron head will always become an electron tail
  • An electron tail will always become copper
  • A copper cell will become an electron head iff exactly one or two out of its eight neighbors are electron heads, otherwise it will remain copper

This competition will have a similar style to the Shortest Game of Life competition, but with a few changes.

  • The grid must be at least 40 by 40 cells
  • The edges of the grid must NOT wrap around (not a torus). Treat cells outside of the field as being constantly "blank."
  • It must be possible for the users to enter their own starting configuration.
  • Staring at blank screens is not fun. The program must visually display the simulation as it is running.

I will pick the winner as a combination of shortest code, usability, speed, and prettiness. I don't really care too much about prettiness, but usability is pretty important. Just make sure that you keep the code short. Good luck!

share|improve this question
add comment

6 Answers

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

The output is displayed in the ⎕SM window. The simulation runs endlessly. The grid is 79x25 because that's the default size of the ⎕SM window. The electron head is h, tail is t, copper is c. The program reads the starting configuration from the keyboard as 25 lines.

Explanation:

  • ↑{79↑⍞}¨⍳25: read the 79x25 grid
  • h t c←1↓⍵∘=¨F←' htc': get three matrices, one with the heads, one with the tails and one with the copper. Also set F to the string ' htc'.

  • ⎕SM∘←1 1,⍨⊂N←F[1+⊃+/...ר⍳3]: The "..." part is a vector of length three, where the elements are matrices showing the new heads, tails, and copper respectively. The heads are multiplied by 1, the tails by 2, and the copper by 3, then we sum these matrices together and add one, giving a matrix of indices into F. N becomes the new state, in the same format as the input, and it is shown on the ⎕SM screen starting from the top-left corner.

  • ¯1⌽¯1⊖h↑⍨2+S←25 79: Add a border of blanks to h by growing it by two rows and columns, then rotating it one right and one down.

  • ⊃+/+/K∘.⊖(K←2-⍳3)∘.⌽⊂: Rotate the matrix in all eight directions and then sum the resulting matrices together, giving the amount of neighbours that are heads on each position.

  • 1 2∊⍨: Set only those positions to 1 which have 1 or 2 neighbours.

  • S↑1 1↓: Remove the border we added earlier.

  • H←c∧: The new heads are all those copper cells that have 1 or 2 head neighbours.

  • t∨c≠H: The new copper cells are all old tails, and all old copper cells that have not become heads.

  • H h(...): The new heads are H as calculated above, the new tails are the old heads, and the new copper cells are as calculated above.

  • ∇N⊣⎕DL÷4: Wait 1/4th of a second, then run the function again on N.

share|improve this answer
add comment

Python (243 214)

Tried to make a cross between usability and characters. The grid is 40x40. Input is given on stdin. An electron head is h, electron tail is t, copper is c, anything else is blank.

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

The while loop (line 3) uncompressed (will not work if placed in code):

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
share|improve this answer
    
I think you can replace lines 5-7 with a single expression: g[e]='h'if(t=='c')&...else't'if i=='h'else'c'if i=='t'else i. Not sure if that works exactly as is, but something along those lines should work –  Strigoides Jan 4 '13 at 12:47
add comment

Python 371 341 chars

Yeah, it's not that short, but it has an interactive gui!

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()

Instructions:

Click with left mouse button to place wire

Click with right mouse button to clear

Click with middle mouse button to place electron head

Click outside the axes to step the automaton

share|improve this answer
    
(x>0)&(x<3) -> (0<x<3). :) –  beary605 Jan 4 '13 at 17:06
add comment

Python, 234 218 chars

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)

You input the board as three list of complex numbers representing the coordinates of the cells of copper (which must include the heads and tails lists), heads, and tails. Here's an example:

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

Note that we eval the input, so you can use arbitrarily complex expressions for lists of complex numbers.

share|improve this answer
add comment

GolfScript (125 120 105 100 chars)

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

Note that I'm counting the \033 as one character each, because they can be replaced by a literal ESC character. This uses ANSI control codes, so relies on a compatible tty. Also note that frames are printed starting with the input grid.

There is some overlap with Generate a grid of sums, which also uses the Moore neighbourhood.

Encoding: blank space => ; electron head => i; electron tail => `; copper => X.

The pause between iterations is the time required to calculate 4665646656. Changing 6.?.? to another expression allows you to control the speed; the next slowest for the same character count is 7.?.?, which is much slower (the output is 22 times as big, and it's not a linear complexity calculation).

For a test case, I've been using

`iXXXXXXXXX
X   X      
   XXX     
X   X      
i`XX XXXXXX

from the Rosetta Code Wireworld challenge.

share|improve this answer
add comment

C, 355 347 300 294 chars

Edit: realized I don't need feof()

Edit: Saved 47 chars! Removed the Sleep, got rid of almost all braces, combined a lot of operations.

Edit: Last one today, since I broke 300 chars. Changed printf to puts, found a cute little optimization with the first comparison.

C does not lend itself well to this sort of problem, but hey, golfing it is fun. This is a pretty brute-force implementation, but I wanted to see how far I could golf it up.

Input is a text file named i. It contains a representation of the starting state, with * for copper, + for electron head, - for electron tail, spaces for empty cells. I'm using the XOR gate from the wiki page for testing.

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

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;
      }
}
share|improve this answer
    
Could cond?43:42 be written 42+(cond)? And I'm sure r=s[j][i++];*p=r==43?45:r;if(r==45)*p=42; can be reduced to r=s[j][i++];*p=r==43?45:r==45?42:r; if not to r=s[j][i++]-43;*p=!r?45:r==2?42:r; –  Peter Taylor Sep 10 '13 at 13:35
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.