11
\$\begingroup\$

Currently at my work we moved to a new building. It's supposed to be state of the art and has automatic lights, automatic roll-down shutters, and is now known as the most eco-friendly building in this town.
However, it doesn't really work all that well.. The roll-down shutters sometimes go down on cloudy days and up when the sun starts to shine, and the lights sometimes cause disco effects by alternating turning on and off every 5-10 minutes. Also, we don't have any manual way of controlling these roll-down shutters, nor the temperature, BUT we do have a remote for the lights.
These remotes however came without instruction manual and contain little over 20 buttons doing all kind of stuff except for what you seem to want..

PS: I wrote this challenge 1.5 months ago in the Sandbox. Currently we, kinda, know how the remotes work..
One big advantage about this building, it's 30+ degrees Celcius outside, but inside it stays the same 21 room temperature at all time.

So, that was the intro, and the remote control for the lights inspired this challenge.

Challenge:

Let's say we initially have a lamp turned off:

L

Then we push all kind of buttons and output the state of the lamp afterwards.

We use the following numbers for the different functions of the remote control for the lamp. When a minus symbol is in front of that number, we do the opposite.

  • 1 = ON; -1 = OFF.
  • 2 = Increase strength by 25%; -2 = Decrease (dim) strength by 25%.
  • 3 = Increase spread by 50%; -3 = Decrease spread by 50%.
  • 4 = Toggling the type of light.

So, this is all pretty vague, so let's go a little more in depth what each thing means:

So, -1 (OFF) is pretty obvious, and 1 will go to the initial ON-state (50% for 2 and 50% for 3):

   //
  //
L ====
  \\
   \\

2 and -2 is how far the light travels (== is appended for every 25%):

0% (equal to a light bulb that is OFF)
L

25%
L ==

50%
L ====

75%
L ======

100%
L ========

3 and -3 is how far the light spreads:

0%:
L ====

50%:
   //
  //
L ====
  \\
   \\

100%:
|| //
||//
L ====
||\\
|| \\

(NOTE: When 2 and 3 are both at 100%, you'll have this state:

||   //
||  //
|| //
||//
L ========
||\\
|| \\
||  \\
||   \\

4 is to toggle the type of light.

Default:
  //
L ==
  \\

After toggling (note the single space before '/' instead of two):
 /
L --
 \

Input:

You will receive an input containing the possible button-presses. For example:

12-34

Output:

The state of the light lamp after all the buttons of the input are sub-sequential pressed. So with the example input above, we have the following output:

L ------

Challenge rules:

  • The input only contains 1234- (and never a - before the 4).
  • You can never go below 0% or above 100%. If a number would increase/decrease beyond these boundaries you can ignore it.
  • When the lamp is turned off, you can ignore any actions and when turned back on again it resets back to the initial ON-state (50% for both 2 and 3, and default 4). For example: 12-1-341 will just print the initial ON-state mentioned above. (TIP: You can ignore everything before the final 1 of the input - excluding -1.)
  • Trailing spaces equal to the length of the light or a single trailing new line is uninhibited. Adding extra unnecessary new lines isn't however.
  • You are allowed to take the input as a list of integers instead of a single string. So instead of 12-34, you can have [1,2,-3,4] as input.

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code.
  • Also, please add an explanation if necessary.

Test cases:

12-34
L ------

12-1-341
   //
  //
L ====
  \\
   \\

14-3224333-2
||  //
|| //
||//
L ======
||\\
|| \\
||  \\

142-1-314-3-322
L --------

1324-2-3
  /
 /
L ----
 \
  \

134
| /
|/
L ----
|\
| \

1-2-2-214-3-3-3
L ----
\$\endgroup\$
  • 1
    \$\begingroup\$ What's the output for 134? \$\endgroup\$ – PurkkaKoodari Aug 26 '16 at 9:19
  • \$\begingroup\$ @Pietu1998 I've added the test case (and fixed some things regarding spaces after toggle 4). Thanks for asking. \$\endgroup\$ – Kevin Cruijssen Aug 26 '16 at 9:26
  • 1
    \$\begingroup\$ I don't think the spread for the third test case is correct. \$\endgroup\$ – PurkkaKoodari Aug 26 '16 at 9:34
  • 1
    \$\begingroup\$ If the lamp is turned on and 1 is pressed, are the parameters reset? \$\endgroup\$ – PurkkaKoodari Aug 26 '16 at 10:29
  • 2
    \$\begingroup\$ Your office is 21º in this weather? I feel like downvoting you out of envy. \$\endgroup\$ – Neil Aug 26 '16 at 12:35
6
\$\begingroup\$

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

\$\endgroup\$
3
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

Kotlin, 445 bytes

My first Kotlin golf, 38 bytes less than Java :)

fun f(z:IntArray)={var a=1<0;var b=2;var c=1;var d=a
z.map{when(it){1->{a=1>0;b=2;c=1;d=!a}-1->a=1<0;2->if(b<4)b+=1;-2->if(b>0)b-=1;3->if(c<2)c+=1;-3->if(c>0)c-=1;4->d=!d}}
var r="";val l=if(c>1)if(d)"|" else "||" else if(d)" " else "  "
if(c>0)for(i in b downTo 1)r+="${l+" ".repeat(i-1)+if(d)"/" else "//"}\n"
r+="L ${(if(d)"--" else "==").repeat(b)}\n"
if(c>0)for(i in 1..b)r+=l+" ".repeat(i-1)+"${if(d)"\\" else "\\\\"}\n"
if(a)r else "L"}()

With white-space and tests:

fun f(z: IntArray) = {
    var a = false // ON / OFF
    var b = 2 // Strength [0,4]
    var c = 1 // Spread [0,2]
    var d = a // Type

    // Find state to print
    z.map {
        when (it) {
            1 -> {
                a = true
                b = 2
                c = 1
                d = !a
            }
            -1 -> a = false
            2 -> if (b < 4) b += 1
            -2 -> if (b > 0) b -= 1
            3 -> if (c < 2) c += 1
            -3 -> if (c > 0) c -= 1
            4 -> d = !d
        }
    }

    var r = ""
    val l = if (c > 1) if (d) "|" else "||"
    else if (d) " " else "  "

    // Print state
    if (c > 0) for (i in b downTo 1) {
        r += "${l + " ".repeat(i - 1) + if (d) "/" else "//"}\n"
    }
    r += "L ${(if (d) "--" else "==").repeat(b)}\n"
    if (c > 0) for (i in 1..b) {
        r += "${l + " ".repeat(i - 1) + if (d) "\\" else "\\\\"}\n"
    }

    /* return */ if (a) r else "L"
}()

fun main(args: Array<String>) {
    println(f(intArrayOf(1, 2, -3, 4)))
    println(f(intArrayOf(1, 2, -1, -3, 4, 1)))
    println(f(intArrayOf(1, 4, -3, 2, 2, 4, 3, 3, 3, -2)))
    println(f(intArrayOf(1, 4, 2, -1, -3, 1, 4, -3, -3, 2, 2)))
    println(f(intArrayOf(1, 3, 2, 4, -2, -3)))
    println(f(intArrayOf(1, 3, 4)))
    println(f(intArrayOf(1, -2, -2, -2, 1, 4, -3, -3, -3)))
}

Interestingly, rather than define the function normally and print or return the created string, it was shorter to use function assignment (the fun f() = of an evaluated lambda. (Does that description make sense?)

I just wish SE had proper Kotlin syntax highlighting

\$\endgroup\$
2
\$\begingroup\$

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"
\$\endgroup\$
1
\$\begingroup\$

Batch, 552 bytes

@echo off
for %%a in (1 %*) do call:l %%a
set/aw*=o,l*=o
if %w% gtr 0 for /l %%a in (%l%,-1,1)do call:w %%a /
set s=----
if %t%==1 set s=====
call echo L %%s:~-%l%%%%%s:~-%l%%%
if %w% gtr 0 for /l %%a in (1,1,%l%)do call:w %%a \
exit/b
:w
set v= 
set u=%2
if %w%==2 set v=l
if %t%==1 set u=%2%2&set v=%v%%v%
set s=    
call set s=%%s:~-%1%%
echo %v:l=^|%%s:~1%%u%
exit/b
:l
if %1==1 set/ao=w=t=1,l=2
if %1==-1 set/ao=0
if %1==2 set/al+=1-l/4
if %1==-2 set/al-=!!l
if %1==3 set/aw+=1-w/2
if %1==-3 set/aw-=!!w
if %1==4 set/at^=1

Note: set v= contains one trailing space and set s= contains three. This was really awkward, as you can't easily print a variable number of |s in Batch, so you have to use a placeholder and replace it in the echo statement.

\$\endgroup\$
0
\$\begingroup\$

05AB1E, 106 bytes

“/|= 
L“•Wθ¨S9ƒTª»þúÙ•6вèJ¶¡sŽ8ÃS«1¡θΣÄ}.γÄ}ODd*©н8‚ß8αF樚NÈi¨]R®θ8Öi"||//="2ô…|/-S:}®Ås3/©_iθ}®i'|ð:}».∊

Input as a list of integers.

Try it online or verify all test cases.

Explanation:

“/|= 
L“               # Push string "/|=\nL"
  •Wθ¨S9ƒTª»þúÙ• # Push compressed integer 9569494169631511496055972036
   6в            # Converted to Base-6 as list: [5,3,2,2,2,2,2,2,2,2,4,1,1,0,0,4,1,1,3,0,0,4,1,1,3,3,0,0,4,1,1,3,3,3,0,0]
     è           # Index each into the string
      J          # Join everything together

We now have the string:

L ========
||//
|| //
||  //
||   //

Then we'll:

¶¡               # Split it by newlines: ["L ========","||//","|| //","||  //","||   //"]
s                # Swap to take the (implicit) input-list
 Ž8Ã             # Push compressed integer 2234
    S            # Converted to a list of digits: [2,2,3,4]
     «           # Append it at the end of the input-list
                 #  i.e. [4,3,3,2,1,3,2,4,-2,-3] → [4,3,3,2,1,3,2,4,-2,-3,2,2,3,4]
 1¡              # Then split on 1
                 #  i.e. [4,3,3,2,1,3,2,4,-2,-3,2,2,3,4]
                 #   → [[4,3,3,2],[3,2,4,-2,-3,2,2,3,4]]
   θ             # Only leave the last inner list
                 #  i.e. [[4,3,3,2],[3,2,4,-2,-3,2,2,3,4]] → [3,2,4,-2,-3,2,2,3,4]
    ΣÄ}          # Sort on the absolute value
                 #  i.e. [3,2,4,-2,-3,2,2,3,4] → [2,-2,2,2,3,-3,3,4,4]
       .γÄ}      # Then group by absolute value
                 #  i.e. [2,-2,2,2,3,-3,3,4,4] → [[2,-2,2,2],[3,-3,3],[4,4]]
           O     # Then take the sum of each group
                 #  i.e. [[2,-2,2,2],[3,-3,3],[4,4]] → [4,3,8]
            Dd   # Duplicate it, and check for each if it's non-negative (>= 0)
                 #  i.e. [4,3,8] → [1,1,1]
              *  # Multiply the two lists
                 #  i.e. [4,3,8] and [1,1,1] → [4,3,8]
               © # And store the result in the register (without popping)
н                # Now take the first value (the strength)
                 #  i.e. [4,3,8] → 4
 8‚              # Pair it with 8
                 #  i.e. 4 → [4,8]
   ß             # Pop and push the minimum of the two
                 #  i.e. [4,8] → 4
    8α           # And then calculate the absolute difference with 8
                 #  i.e. 4 → 4
      F          # Loop that many times:
       ć         #  Extract the head of the string-list
                 #   i.e. ["L ========","||//","|| //","||  //","||   //"] → "L ========"
        ¨        #  Remove the last character
                 #   i.e. "L ========" → "L ======="
         š       #  And prepend it back to the list again
                 #   i.e. ["||//","|| //","||  //","||   //"] and "L ======="
                 #    → ["L =======","||//","|| //","||  //","||   //"]
       NÈi       #  And if the loop-index is even:
          ¨      #   Also remove the last item of the string-list
                 #    i.e. ["L =======","||//","|| //","||  //","||   //"]
                 #     → ["L =======","||//","|| //","||  //"]
      ]          # Close both the if and loop
                 #  i.e. ["L ========","||//","|| //","||  //","||   //"] and 4
                 #   → ["L ====","||//","|| //"]
       R         # Then reverse the list
                 #  i.e. ["L ====","||//","|| //"] → ["|| //","||//","L ===="]
®                # Push the list from the register again
 θ               # Now take the last value (the toggle)
                 #  i.e. [4,3,8] → 8
  8Öi         }  # If it's divisible by 8:
                 #  i.e. 8 → 1 (truthy)
     "||//="     # Push string "||//="
            2ô   # Split into parts of size 2: ["||","//","="]
     …|/-        # Push string "|/-"
         S       # Split into characters: ["|","/","-"]
     :           # And replace all of them in the string-list
                 #  i.e. ["|| //","||//","L ===="] → ["| /","|/","L ----"]
®                # Push the list from the register again
 Ås              # Now take the middle value (the spread)
                 #  i.e. [4,3,8] → 3
   3/            # Divide it by 3
                 #  i.e. 3 → 1
     ©           # Store it in the register (without popping)
      _i }       # If it's exactly 0:
                 #   i.e. 1 → 0 (falsey)
        θ        #  Only leave the last value of the string-list
     ®i    }     # If it's exactly 1 instead:
                 #   i.e. 1 → 1 (truthy)
       '|ð:     '#  Replace all "|" with spaces " "
                 #   i.e. ["| /","|/","L ----"] → ["  /"," /","L ----"]
»                # Then join the string-list by newlines
                 #  i.e. ["  /"," /","L ----"] → "  /\n /\nL ----"
 .∊              # And finally intersect mirror everything vertically
                 # (which automatically converts the slashes)
                 #  i.e. "  /\n /\nL ----" → "  /\n /\nL ----\n \\n  \"
                 # (And output the result implicitly)

See this 05AB1E tip of mine (sections How to compress large integers? and How to compress integer lists?) to understand why •Wθ¨S9ƒTª»þúÙ•6в is [5,3,2,2,2,2,2,2,2,2,4,1,1,0,0,4,1,1,3,0,0,4,1,1,3,3,0,0,4,1,1,3,3,3,0,0]; and Ž8à is 2234.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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