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.

Redstone is a material in the game Minecraft, and it is used for many complex contraptions. For this program, you will only need to simulate three items: the redstone wire (noted with R), redstone torch (noted with T), and block (noted with B).

Here are a list of basic rules about how redstone works:

A redstone torch sends power to any adjacent redstone wire.
TRRRR
 ^This redstone wire is powered.

Redstone wire can only hold power for 15 blocks.
TRRRRRRRRRRRRRRRR
                ^This last wire is unpowered, because the torch is >15 blocks away.

A block is said to be powered if a powered redstone wire is found adjacent to it.
TRRRB
    ^This block is powered.

If a block next to a redstone torch is powered, then the torch stops emitting power.
T
R
R
R
B <This block is powered.
T <This redstone torch does not emit power because of the block next to it.
R <This redstone is unpowered because the torch is not providing power.
R

Input will be given in two dimensional arrays up to a size of 64x64, like this:

TRRR
   B
TBRTRR
R
RRRRRRRRR
        R
   RRRRRR

It is guaranteed that the input will not have any "clocks", or redstone powered by a torch pointing to the block that the torch is on. There will only be one redstone circuit in every input.

Your program must change each character to be a 1 or a 0, 1 indicating if this item is powered/emitting power, and a 0 if it is unpowered/not emitting power.

This input should have this output:

1111
   1
100000
1
111111111
        1
   001111

This is a code-golf, so shortest code wins, as always.

share|improve this question
1  
What output do you expect for situations like "TRR\nB B\nRRT"? –  Howard Jan 29 '13 at 6:05
    
111\n0 1\n000 is the output; it seems to be sound within the rules. I will put an input restriction saying you cannot have any situations like TRR B R RRR, where it flashes repeatedly. –  beary605 Jan 29 '13 at 6:22
1  
Can we assume that each input array will contain only one complete circuit running from top to bottom as in your example or do we have to code for multiple separate circuits starting anywhere in the array? –  Graham Jan 29 '13 at 11:32
    
@Graham: There will only be one redstone circuit for each input. –  beary605 Jan 29 '13 at 14:26
    
Knowing the game Minecraft, I think that in your example given the block on line 2 does not stop the adjacent torch from giving power (the redstone doesn't actually connect to the block). Is this an error or a meant simplification? –  tomsmeding Jan 29 '13 at 19:15

2 Answers 2

C, 525

More scope for golfing...

// input - element zero is empty placeholder
char c[9999];
l[999],h;
// index of x,y within c or e
p(x,y){return y<0||y>=h||x<0||x>=l[y+1]-l[y]-1?0:l[y]+x;}

// energy
e[9999];

b,d,n,m,t,q,v,x,y;

// loop across 4 neighbours
o[]={-1,1,0,0};
#define N for(d=0;d<4;d++){i=p(x+o[d],y+o[(d+2)%4]);if

main(int i,char**s){
    //input
    n=read(open(s[1],0),c+1,9999);
    // build line index
    for(l[0]=i=1;i<=n;i++)if(c[i]==10)l[++h]=i+1; 
    //step whilst changes
    while(!m)for(m=1,y=0;y<h;y++)for(x=0;q=p(x,y);x++){
        b=c[q];
        v=0;
        if(b=='T'){
            v=16;
            N(c[i]=='B'&&e[i])v=0;} // extinguish touch if powered block
        }else if(b=='R'){
            N((t=e[i]-1)>v)v=t;} // take 1 less power than neighbours provide
        }else if(b=='B'){
            N(c[i]=='R'&&e[i])v=1;} // power block if active wire
        }
        if(e[q]-v)m=0;
        e[q]=v;
    }
    //output
    for(i=1;i<=n;i++)if(c[i]>32)c[i]=e[i]?49:48;
    puts(c+1);
}
  • Input assumes each line is only terminated by a line feed character (10).
  • Some mucking around to deal with input format to support arbitrary sized arrays - as long as it fits within 9999 chars, and is no more than 999 lines then the input should be fine.
  • Apply the rules until no further changes occur.
  • I've assumed it's ok to apply rules in-place as opposed to flipping between two buffers.

Testing:

Assuming a file called redstone.txt contains:

TRRR
   B
TBRTRR
R
RRRRRRRRR
        R
   RRRRRR

Then ./a.out redstone.txt gives:

1111
   1
100000
1
111111111
        1
   001111
share|improve this answer

Python, 728

This is just a quick pass (ran out of time for now). It can probably use a lot more golfing.

import sys
m=[list(x)for x in sys.stdin.read().split('\n')]
e=enumerate
s=lambda x:set([(r,c)for r,i in e(m)for c,j in e(i)if j==x])
q=set([])
t=s('T')
b=s('B')
n=s('R')
def d(o,r,c,i,h,q):
 if i<0:return 0
 o[(r,c)]=1
 for a,z in[(r+1,c),(r-1,c),(r,c+1),(r,c-1)]:
  if(a,z)in q or((a,z)in b and not(r,c)in n):continue
  if(r,c)in b and(a,z)in t-q:
   x=set([(a,z)])
   q|=x
   o[(a,z)]=0
   return 1
  if(a,z)in h or not (a,z)in o:continue
  h|=set([(a,z)])
  if not d(o,a,z,i-1,h,q):return 1
g=1
while g:
 o=dict(zip(b,[0]*len(b))+zip(n,[0]*len(n))+zip(q,[0]*len(q)))
 g=0
 for x,y in t:
  if not(x,y)in q and d(o,x,y,15,set([]),q):g=1
for a,z in o.keys():m[a][z]=o[(a,z)]
print "\n".join(map(lambda x:"".join(map(str,x)),m))
share|improve this answer
    
Yep, for example, you could use f=set and create a l=lambda x:zip(x,[0]*len(x)). Well, you'd still be over 700 chars. Also, you left a useless space at ... or not (a,z)in o. –  Morwenn Jul 5 '13 at 11:30

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.