What does this button do?
Python 2, 221 bytes
for b in[-1]+input():exec["p=b>0;d=2;s=1;t=2","d+=b/2*(-2<d+b<6)","s+=b/3*(-3<s+b<5)","t=3-t"][abs(b)-1]
i=c=(s>0)*d*p
q='print" |"[s/2]*t+" "*i+t*%r;'
exec('i-=1;'+q%'/')*c
print"L "+" -="[t]*2*d*p
exec(q%'\\'+'i+=1;')*c
This wound up being longer than I expected. The first line calculates the state of the lamp, the rest implement the printing.
Input is given via STDIN in the array form.
See the test cases on ideone
R, 323 320 bytes
z=scan();a=c=1;b=d=2;for(i in 1:sum(1|z)){s=sign(y<-z[i]);switch(y/s,b<-d<-2*(c<-a<-y),b<-b+s,c<-c+s,d<-2-d);b=min(b,4);c=min(c,2);b=b*(b>0);c=c*(c>0)}
s="/";v=if(c>1)"|"else" ";for(i in a*b:-b){if(i)cat(v,if(d)v,rep(" ",abs(i)-1),s,if(d)s,"\n",sep="")else{cat("L ",if(d)rep("==",b)else rep("--",b),"\n",sep="");s="\\"}}
Ungolfed:
z=scan()
reads a line of input (integers separated with spaces)
a=c=1;b=d=2
initialises variables a (on-ness), b (brightness), c (width), d (beam type). d
is either zero or two, which means we can call if(d) later rather than a longer if(d>1) or similar and save a couple of bytes.
while(any(z|1))
A golf-y way of writing while(length(z))
where z is an integer vector.
The rest of the first line handles the input via a switch
statement.
The second line prints out.
It is possible that some of the <-
can be replaced with =
, but I think you get eaten alive by lexical scoping...
Also note that in R, backslashes need to be escaped.
c*(c>0)
is a golf-y way of writing max(c,0)
that saves a character.
If the light isn't on, then since *
has lower precedence than :
, the for(i in a*b:-b)
loop only iterates over 0:0
.
Update; saved 3 bytes by replacing the loop in the first line with a for (rather than while). Note that 1:sum(1|z)
is fewer characters than 1:length(z)
or seq_along(z)
. seq(z)
would work in most cases, but not when z
is of length one. The solution given will not work for input of length zero but I hope that is outside the scope of the competition.
Java 8, 484 483 452 446 440 bytes
z->{int a=1,b=2,c=1,d=0,j,k;for(int i:z){d=i==1?0:i>3?1-d:d;a=i*i==1?i:a;b+=i==1?2-b:i==2&b<4?1:i==-2&b>0?-1:0;c+=i==1?1-c:i==3&c<2?1:i==-3&c>0?-1:0;}String t=d<1?"=":"-",q=d<1?"//":"/",x=d<1?"\\\\":"\\",n="\n",y=" ",w=d<1?y+y:y,g=c>1?d<1?"||":"|":w,r="";if(c>0)for(r+=g,j=b;j-->0;r+=q+n+(j>0?c>1?g:w:""))for(k=j;k-->0;r+=y);for(r+="L ",j=b;j-->0;r+=t+t);r+=n;if(c>0)for(r+=g;++j<b;r+=x+n+(j<b-1?g:""))for(k=j;k-->0;r+=y);return a>0?r:"L";}
Finally.. Ok, my own challenge is a bit harder than I expected.. ;P
This can without a doubt be golfed by using a completely different approach.. I now first determine what to do, and then print it. The printing is actually the hardest of this challenge, imho.
-6 bytes thanks to @ceilingcat.
Explanation:
Try it here.
z->{ // Method with integer-array parameter and String return-type
int a=1, // ON/OFF flag, initially ON
b=2, // Strength, initially 50%
c=1, // Spread, initially 50%
d=0, // Type of light, initially two lines
j,k; // Index-integers
for(int i:z){ // Loop over the input-array
d=i==1?0:i>3?1-d:d; // Determine the new type of light
a=i*i==1?i:a; // Determine if the light is ON/OFF
b+=i==1?2-b:i==2&b<4?1:i==-2&b>0?-1:0;
// Determine the new strength
c+=i==1?1-c:i==3&c<2?1:i==-3&c>0?-1:0;}
// Determine the new spread
String t=d<1?"=":"-", // Horizontal light symbol
q=d<1?"//":"/", // Upper diagonal light symbol
x=d<1?"\\\\":"\\", // Bottom diagonal light symbol
n="\n", // New-line
y=" ", // Space
w=d<1?y+y:y, // One or two spaces?
g=c>1?d<1?"||":"|":w,// Space(s) or vertical light symbol(s)?
r=""; // Result String, starting empty
if(c>0) // Do we have spread >0%?
for(r+=g,j=b;j-->0;r+=q+n+(j>0?c>1?g:w:""))for(k=j;k-->0;r+=y);
// Create upper light part
r+="L "; // Light-bulb
for(j=b;j-->0;r+=t+t); // Horizontal light next to the light-bulb
r+=n;
if(c>0) // Do we have spread >0%?
for(r+=g;++j<b;r+=x+n+(j<b-1?g:""))for(k=j;k-->0;r+=y);
// Create bottom light part
return a>0? // Is the light turned ON?
r // Return the created result-String
: // Else:
"L";} // Return just "L"