15
\$\begingroup\$

Disclaimer

While I know there is this particular related question, my question uses two garage doors, a randomizing component, and I'm also basing this on real life events, seeing my son accidentally lowered one of said garage doors whilst I was walking out of the garage last week... Nothing like a blow to the head to get the creative juices flowing! ;)

The Background

Lucas (my 15 month old son) likes to play with the garage remote. There are two buttons on this remote, one for the left garage door, and one for the right garage door. Both buttons work in the same manner; press once to get the door to start opening, press again to stop, press again to start closing, press again to stop again, and so on.

Lucas loves this remote, he'll randomly press one of the buttons, or both, or none at all. If both are pressed, no signal is sent, but a press of one button will send out a signal.

So, the code-golf challenge is divided on two parts:

Part One

Generate a 60 character long string representing Lucas random button presses over a minute. "Random" in this case means "with an equal chance of each input at each tick". The characters are as follows:

  • 0: Lucas has either pressed no button, or has pressed both buttons. Either way, no signal has been sent.
  • 1: The button for the left garage door has been pressed by Lucas
  • 2: The button for the right garage door has been pressed by Lucas

Part Two

Using the string generated in Part One, simulate the opening and closing of the two-car garage using the numbers as triggers for opening, stopping and closing these doors.

My garage doors are pretty quick (see Disclaimer above as to why). Once you press the button it takes four seconds to be fully open or closed.

So, if closed:

  • 0 sec: 0% open (closed); when button is pressed, door starts opening
  • 1 sec: 25% open
  • 2 sec: 50% open
  • 3 sec: 75% open
  • 4 sec: 100% open, door stops

And therefore, if open:

  • 0 sec: 100% open; when button is pressed, door starts closing
  • 1 sec: 75% open
  • 2 sec: 50% open
  • 3 sec: 25% open
  • 4 sec: 0% open (closed), door stops

If a particular door is in motion, a signal to that same door will stop it. The next signal sent to that same door after that will send it moving in the opposite direction. If a door is stopped when it has previously been in motion and is now fully open or fully closed when the "stop" signal is received, the door will register as "stopped" in the fully-open or fully-closed state, ready to move in the opposite direction when it receives a new signal.

With this simulation, both garage doors will be initially in the closed position. So, let's look at a 10 second list of commands and see what happens if Lucas was to perform them on the remote:

2120221120
2: (L:0% stopped, R:0% opening)
1: (L:0% opening, R:25% opening)
2: (L:25% opening, R:50% stopped)
0: (L:50% opening, R:50% stopped)
2: (L:75% opening, R:50% closing)
2: (L:100% stopped, R:25% stopped)
1: (L:100% closing, R:25% stopped)
1: (L:75% stopped, R:25% stopped)
2: (L:75% stopped, R:25% opening)
0: (L:75% stopped, R:50% opening)

Output

The first part of the output requires the display of the 60 character long string of random "0", "1" and "2" characters generated from Part One. eg. 212022112021202211202120221120212022112021202211202120221120

Below this string, is the processing of these "signals" according to the rules mentioned above of how the garage doors will behave with each respective character (on a second by second basis). You should end up with 60 lines as a result below the initial display string.

Each of these processed lines will be in the form of: N: (L:X% XXXXXXX, R:Y% YYYYYYY) where:

  • N is the nth character from the respective random string, which will be in the form of a 0, 1, or 2.
  • X% is the percentage of openness of the left door (there is no zero padding)
  • XXXXXXX is the status of the left door. If the door is not in motion (i.e. not opening or closing) the status "stopped" is enforced, meaning it has been stopped in motion (only possible at 25%, 50% or 75%) or stopped when fully open (100%) or fully closed (0%). Otherwise, the door will either be "opening" or "closing".
  • Y% is the percentage of openness of the right door (there is no zero padding)
  • YYYYYYY is the status of the right door. If the door is not in motion (i.e. not opening or closing) the status "stopped" is enforced, meaning it has been stopped in motion (only possible at 25%, 50% or 75%) or stopped when fully open (100%) or fully closed (0%). Otherwise, the door will either be "opening" or "closing".

Example shown below using 10 "signals" and 10 processed lines

2120221120
2: (L:0% stopped, R:0% opening)
1: (L:0% opening, R:25% opening)
2: (L:25% opening, R:50% stopped)
0: (L:50% opening, R:50% stopped)
2: (L:75% opening, R:50% closing)
2: (L:100% stopped, R:25% stopped)
1: (L:100% closing, R:25% stopped)
1: (L:75% stopped, R:25% stopped)
2: (L:75% stopped, R:25% opening)
0: (L:75% stopped, R:50% opening)

This is code-golf, so the shortest code will be the clear winner. I've made this a little easy by using phrases like "opening", "stopped" and "closing", which are all seven letters... so you may want to work that into your strategy.

Best of luck!

\$\endgroup\$
12
  • \$\begingroup\$ You should define a clearer output format for Part 2. \$\endgroup\$ Aug 28, 2016 at 23:23
  • \$\begingroup\$ @LegionMammal978 What do you feel is missing from the output? \$\endgroup\$ Aug 29, 2016 at 1:12
  • 1
    \$\begingroup\$ I don't at the moment, but I do think it's a neat question--I may tackle it. \$\endgroup\$
    – DLosc
    Aug 29, 2016 at 4:10
  • 1
    \$\begingroup\$ Why isn't the last 1 command stopping the left door at 75% in your example? \$\endgroup\$
    – Arnauld
    Aug 29, 2016 at 14:52
  • 1
    \$\begingroup\$ Should 0,1, and 2 all appear equally in the first part, or should no-press, double-press, left-press, and right-press all appear equally? (meaning, 0 is more likely because it represents two scenarios which cause the same and result...) \$\endgroup\$ Aug 29, 2016 at 15:56

8 Answers 8

5
\$\begingroup\$

Javascript (ES6), 277 275 263 253 250 247 234 bytes

_=>(d=[0,0],l=s='',[...Array(60)].map(_=>(s+=`
${c=Math.random()*3|0}:(`,l+=c,d=d.map((v,i)=>(v=v&8?v&16?v-27?v+1:20:v-9?v-1:0:v,v^=c+~i?0:v&8||24,s+='LR'[i]+`:${(v&7)*25}% `+(v&8?v&16?'opening':'closing':'stopped')+',)'[i],v)))),l+s)

Ungolfed and commented

_ => (
  // Initialize array:
  //   - d = door states as integers
  //     - bits 0 to 2: door opening state (from 0b000 = 0% to 0b100 = 100%)
  //     - bit #3: door in motion (0: no, 1: yes)
  //     - bit #4: door direction (0: closing, 1: opening)
  d = [0, 0],

  // Initialize strings:
  //   - l = list of commands
  //   - s = door states in plain text
  l = s = '',

  // Iterate on an array of 60 entries.
  [...Array(60)].map(_ => (
    // c = new random command (0, 1 or 2)
    // Append new line and new command to s.
    s += `\n${c = Math.random() * 3 | 0}:(`,

    // Append new command to l.
    l += c,

    // For each door ...
    d = d.map((v, i) => (
      // If the door is in motion, update its opening state.
      // Clear the 'in motion' bit if a bound is reached (either closed or fully open).
      v = v & 8 ? v & 16 ? v - 27 ? v + 1 : 20 : v - 9 ? v - 1 : 0 : v,

      // If the current command is intended for this door, update its direction and
      // 'in motion' bit. Direction is changed on the 'stopped => moving' transition.
      v ^= c + ~i ? 0 : v & 8 || 24,

      // Translate the door state in plain text and append it to s
      s +=
        'LR'[i] +
        `:${(v & 7) * 25}% ` +
        (v & 8 ? v & 16 ? 'opening' : 'closing' : 'stopped') +
        ',)'[i],

      // Value to be taken into account by map()
      v
    ))
  )),

  // Final result to be returned
  l + s
)

Demo

let f = 
_=>(d=[0,0],l=s='',[...Array(60)].map(_=>(s+=`
${c=Math.random()*3|0}:(`,l+=c,d=d.map((v,i)=>(v=v&8?v&16?v-27?v+1:20:v-9?v-1:0:v,v^=c+~i?0:v&8||24,s+='LR'[i]+`:${(v&7)*25}% `+(v&8?v&16?'opening':'closing':'stopped')+',)'[i],v)))),l+s)

console.log(f())

\$\endgroup\$
6
  • \$\begingroup\$ Wow, I'm impressed with the one liner and throwing it into console.log at that! Well done! \$\endgroup\$ Aug 29, 2016 at 21:04
  • 1
    \$\begingroup\$ Curiously not working in Firefox, just 4 lines in output, like this 112200001100122021010101012100000010011200201022122021012211 [ "L:25% stopped", "R:25% stopped" ](newlines after comma and brackets) \$\endgroup\$
    – edc65
    Aug 29, 2016 at 21:50
  • \$\begingroup\$ @edc65 - My bad, actually. I misread the instructions about the output format. This is fixed. \$\endgroup\$
    – Arnauld
    Aug 29, 2016 at 22:52
  • \$\begingroup\$ @Arnauld You could also remove the parentheses from v^=(c-i-1?0:v&8||24) to save you two bytes. \$\endgroup\$ Aug 30, 2016 at 3:00
  • \$\begingroup\$ PS @Arnauld, thanks for taking part! \$\endgroup\$ Aug 30, 2016 at 4:58
4
\$\begingroup\$

Python 2, 377 370 361 357 345 335 326 316 312 306 304 bytes

The second indent level is a raw tab (\t), which plays really badly with Markdown, so it's been replaced by two spaces.

from random import*
p=[randint(0,2)for d in[[0]*3]*60]
print`p`[1::3]
v=[-1]*3
c=[0]*3
f=lambda y:str(c[y]*25)+'% '+'csoltpooespnipinengdg'[d[y]+1::3]
for x in p:
 for i in 1,2:
  q=d[i];c[i]+=q
  if(2*-~q==c[i])*q:v[i]=q;d[i]=0
 z=d[x]
 if z:v[x]=z
 d[x]=-v[x]*(z==0);print'%d: (L:%s, R:%s)'%(x,f(1),f(2))

I'm almost certain this can be golfed further.

Ungolfed, with comments:

import random

# Generate the random string - represented as a list of ints
presses = [random.randint(0, 2) for _ in range(60)]
print ''.join(map(str, presses))

# Constants for door states used for easier reading
CLOSING = -1
STOPPED = 0
OPENING = 1

# Variables representing the state of the garage doors
# There's a third element in these so that x[0] resolves to a dummy slot
# (this way, we can avoid a conditional down the road)
prev_states = [CLOSING, CLOSING, 0]
door_states = [STOPPED, STOPPED, 0]
door_pcts = [0, 0, 0]  # delta 1 = 25%

for press in presses:
  # Close/open the door 1 more
  for i in 1, 2:
    if door_states[i] != STOPPED:
      delta_pct, stop_pct = (-1, 0) if door_states[i] == CLOSING else (1, 4)
      door_pcts[i] += delta_pct
      if door_pcts[i] == stop_pct:
        prev_states[i] = door_states[i]
        door_states[i] = STOPPED

  # Handle pressing a button
  # If the press is 0 (no press), the 0th element resolves to a dummy
  # door, thus saving us an expensive conditional

  if door_states[press] == STOPPED:
    door_states[press] = -prev_states[press]
  else:
    prev_states[press] = door_states[press]
    door_states[press] = STOPPED

  # Print the status update
  print '%d: (L:%d%% %s, R:%d%% %s)' % (
    press,
    door_pcts[0]*25,
    ['closing', 'stopped', 'opening'][door_states[0]+1],
    door_pcts[1]*25,
    ['closing', 'stopped', 'opening'][door_states[1]+1],
  )

Saved 4 14 15 bytes thanks to @TheBikingViking!

Saved 6 bytes thanks to @ValueInk!

\$\endgroup\$
11
  • 1
    \$\begingroup\$ You can change range(60) to [0]*60. \$\endgroup\$ Aug 29, 2016 at 20:50
  • 1
    \$\begingroup\$ @TheBikingViking Thanks! I'm editing that in now. \$\endgroup\$
    – Copper
    Aug 29, 2016 at 20:56
  • 2
    \$\begingroup\$ You can do 'p'[1::3] (replace apostrophes with backticks) instead of ''.join(map(str,p)). \$\endgroup\$ Aug 29, 2016 at 21:28
  • 2
    \$\begingroup\$ (4,0)[q<0]==c[i]and q -> ((4,0)[q<0]==c[i])*q \$\endgroup\$ Aug 29, 2016 at 21:39
  • 2
    \$\begingroup\$ @ValueInk That line abuses a bug in Python 2's list comprehensions to set n to that string. n is used on the final line to extract closing, stopped, opening from that string. \$\endgroup\$
    – Copper
    Aug 30, 2016 at 23:22
2
+150
\$\begingroup\$

Pyth, 156 149 145 bytes

jkJmO3U60K=G*]Z3=b*3]_1VJFHS2I&=T@KHq*2hT@XHGTH XbHT XKH0)) XKN*_@XbN|@KN@bNN!@KN%+N": (L:%s, R:%s)"m++*@Gd25"% "%3>"csoltpooespnipinengdg"h@KdS2

A direct translation of my Python answer.

Try it online!

Explanation:

jk                              " print ''.join(map(str,                   "
JmO3U60                         "  J = [randint(0,2) for _ in range(60)])) "
K=G*]Z3                         " K = copy(G = [0] * 3)                    "
=b*3]_1                         " b = [-1] * 3                             "
VJ                              " for N in J:                              "
FHS2                            "  for H in range(1, 3):                   "
I&=T@KH                         "   if ((T = K[H]) and                     "
q*2hT@XHGTH                     "       (2 * (T + 1) == (G[H] += T)[H]):   "
 XbHT                           "    b[H] = T                              "
 XKH0))                         "    K[H] = 0                              "
 XKN*_@XbN|@KN@bNN              "  K[N] = (-(b[N] = K[N] or B[N])[N] *     "
!@KN                            "   (not K[N]))                            "
%+N": (L:%s, R:%s)"             "  print(str(N) + ': (L:%s, R:%s)' %       "
m++                             "   map(lambda d:                          "
*@Gd25                          "    G[d] * 25 +                           "
"% "                            "    '% ' +                                "
%3>"csoltpooespnipinengdg"h@Kd  "    'csoltpooespnipinengdg'[K[d]+1::3]]   "
S2                              "   ), range(1, 3))                        "
\$\endgroup\$
1
  • \$\begingroup\$ Wow! Thanks for this answer, as well as the explanation of the code... I was actually making sense of it by the time I reached the end of it... \$\endgroup\$ Sep 1, 2016 at 12:29
2
\$\begingroup\$

Ruby, 263 261 260 254 bytes

How did JavaScript's answer get so short??? It overtook mine while I was away and still is winning currently...

s=(1..60).map{rand 3}
puts s*''
D=1,2
d=[25]*3;a=[0]*3;m=[p]*3
s.map{|i|D.map{|j|m[j]&&a[j]+=d[j];(0..100)===a[j]+d[j]||i!=j&&(d[j]*=-1;m[j]=p)}
(m[i]^=1)||d[i]*=-1
puts"#{i}: (L%s, R%s)"%D.map{|j|":#{a[j]}% #{%w"stopped opening closing"[m[j]?d[j]:0]}"}}
\$\endgroup\$
2
\$\begingroup\$

C, 420 433 424 374 bytes

#define F(X,x) X=x==1?X+1:x==2?X-1:X;X=X<0?0:X>4?4:X;x=X==0?0:X==4?3:x
#define G(x) x=x==1?3:x==2?0:x==3?2:x+1
#define H(X,x) X*25,x==0||x==3?"stopped":x==1?"opening":"closing"
c,i,l,r,L,R,x[60];main(){while(i<60)printf("%d",x[i++]=random()%3);while(c<60){if(x[c]==1)G(l);else if(x[c]==2)G(r);printf("\n%d: (L:%d%% %s, R:%d%% %s)",x[c++],H(L,l),H(R,r));F(L,l);F(R,r);}}

Doesn't seed the random generator but does use random for a better distribution. There must be a better way to golf this logic though...

110121100121212100112200222111200020111100022122202112202211002
1: (L:0% opening, R:0% stopped)
1: (L:25% stopped, R:0% stopped)
0: (L:25% stopped, R:0% stopped)
1: (L:25% closing, R:0% stopped)
2: (L:0% stopped, R:0% opening)
1: (L:0% opening, R:25% opening)
1: (L:25% stopped, R:50% opening)
0: (L:25% stopped, R:75% opening)
0: (L:25% stopped, R:100% stopped)
1: (L:25% closing, R:100% stopped)
2: (L:0% stopped, R:100% closing)
1: (L:0% opening, R:75% closing)
2: (L:25% opening, R:50% stopped)
1: (L:50% stopped, R:50% stopped)
2: (L:50% stopped, R:50% opening)
1: (L:50% closing, R:75% opening)
0: (L:25% closing, R:100% stopped)
0: (L:0% stopped, R:100% stopped)
1: (L:0% opening, R:100% stopped)
1: (L:25% stopped, R:100% stopped)
2: (L:25% stopped, R:100% closing)
2: (L:25% stopped, R:75% stopped)
0: (L:25% stopped, R:75% stopped)
0: (L:25% stopped, R:75% stopped)
2: (L:25% stopped, R:75% opening)
2: (L:25% stopped, R:100% closing)
2: (L:25% stopped, R:75% stopped)
1: (L:25% closing, R:75% stopped)
1: (L:0% opening, R:75% stopped)
1: (L:25% stopped, R:75% stopped)
2: (L:25% stopped, R:75% opening)
0: (L:25% stopped, R:100% stopped)
0: (L:25% stopped, R:100% stopped)
0: (L:25% stopped, R:100% stopped)
2: (L:25% stopped, R:100% closing)
0: (L:25% stopped, R:75% closing)
1: (L:25% closing, R:50% closing)
1: (L:0% opening, R:25% closing)
1: (L:25% stopped, R:0% stopped)
1: (L:25% closing, R:0% stopped)
0: (L:0% stopped, R:0% stopped)
0: (L:0% stopped, R:0% stopped)
0: (L:0% stopped, R:0% stopped)
2: (L:0% stopped, R:0% opening)
2: (L:0% stopped, R:25% stopped)
1: (L:0% opening, R:25% stopped)
2: (L:25% opening, R:25% closing)
2: (L:50% opening, R:0% opening)
2: (L:75% opening, R:25% stopped)
0: (L:100% stopped, R:25% stopped)
2: (L:100% stopped, R:25% closing)
1: (L:100% closing, R:0% stopped)
1: (L:75% stopped, R:0% stopped)
2: (L:75% stopped, R:0% opening)
2: (L:75% stopped, R:25% stopped)
0: (L:75% stopped, R:25% stopped)
2: (L:75% stopped, R:25% closing)
2: (L:75% stopped, R:0% opening)
1: (L:75% opening, R:25% opening)
1: (L:100% closing, R:50% opening)

Older version 1:

c,i,l,r,L,R,x[60];main(){while(i<60)printf("%d",x[i++]=random()%3);while(c<60){if(x[c]==1)l=l==1?3:l==2?0:l==3?2:l+1;else if(x[c]==2)r=r==1?3:r==2?0:r==3?2:r+1;printf("\n%d: (L:%d%% %s, R:%d%% %s)",x[c++],L*25,l==0||l==3?"stopped":l==1?"opening":"closing",R*25,r==0||r==3?"stopped":r==1?"opening":"closing");L=l==1?L+1:l==2?L-1:L;R=r==1?R+1:r==2?R-1:R;L=L<0?0:L>4?4:L;R=R<0?0:R>4?4:R;l=L==0?0:L==4?3:l;r=R==0?0:R==4?3:r;}}

Older version 2:

c,i,l,r,L,R,x[60];g(){while(i<60)printf("%d",x[i++]=random()%3);}main(){g();while(c<60){if(x[c]==1)l=l==1?3:l==2?0:l==3?2:l+1;else if(x[c]==2)r=r==1?3:r==2?0:r==3?2:r+1;printf("%d: (L:%d%% %s, R:%d%% %s)\n",x[c++],L*25,l==0||l==3?"stopped":l==1?"opening":"closing",R*25,r==0||r==3?"stopped":r==1?"opening":"closing");L=l==1?L+1:l==2?L-1:L;R=r==1?R+1:r==2?R-1:R;L=L<0?0:L>4?4:L;R=R<0?0:R>4?4:R;l=L==0?0:L==4?3:l;r=R==0?0:R==4?3:r;}}
\$\endgroup\$
1
2
\$\begingroup\$

PHP, 254 247 246 245 235 230 226 bytes

beating ES again!

for($t=60;$t--;)$s.=rand()%3;echo$s;for(;++$t<60;print"
$c: ($o[1], $o[2])")for($i=3;--$i;$o[$i]='.LR'[$i].':'.$d[$i]*25 .'% '.[opening,stopped,closing][abs($z-1)])if(((1&$z=&$r[$i])&&!(3&$d[$i]+=2-$z))|$i&$c=$s[$t])$z=++$z%4;

golfed down from these 311 (the first complete version, already had some golfing):

<?for($i=60;$i--;)$s.=rand(0,2);echo$s;$d=$r=[0,0];$n=[L,R];$p=[stopped,opening,stopped,closing];for($t=-1;++$t<60;print"
$c: (".join(', ',$x).")")for($m=$c=$s[$t],$i=-1;$i++<1;){if($r[$i]&1)if(!($d[$i]+=2-$r[$i])||4==$d[$i])$m|=$i+1;if($m&$i+1)$r[$i]=(1+$r[$i])%4;$x[$i]="$n[$i]:".($d[$i]*25)."% ".$p[$r[$i]];}

breakdown

for($t=60;$t--;)$s.=rand()%3;   // part 1               also initializes $t to -1
echo$s;
for(
    ;
    ++$t<60;
    print"\n$c: ($o[1], $o[2])" // print output
)
    for($i=3;--$i;  // loop $i from 2 to 1 (door number)
        // generate output
        $o[$i]='.LR'[$i].':'.$d[$i]*25 .'% '
        .[opening,stopped,closing][abs($z-1)]           // map 0123 to 1012
    )
        if(((1&$z=&$r[$i])  // if door in motion        ... and reference the array item
            &&!(3&              // 2. if end position   "&&" needed for short circuit
            $d[$i]+=2-$z        // 1. move door         2-$z maps 1,3 to 1,-1 = delta
            )
        )|$i&$c=$s[$t])     // 3. or if button $i pressed   "|" needed for no short circuit
            $z=++$z%4;          // rotate direction     ++$z%4 maps 0,1,2,3 to 1,2,3,0
        // generate output (loop post condition)
    // print output (loop post condition)
\$\endgroup\$
1
  • \$\begingroup\$ @Arnauld: got you! :) \$\endgroup\$
    – Titus
    Sep 12, 2016 at 21:22
1
\$\begingroup\$

Java 8 lambda, 500 characters

I did my best, here is what I came up with:

()->{String r="";int i=0,l=0,m=0,n=1,o=1,p=0,q=0;for(;i++<60;)r+=(int)(Math.random()*3);for(char s:r.toCharArray()){l+=p;m+=q;if(l>99&p>0){l=100;p=25*(((n=++n%4)-1)%2);}if(l<1&p<0){l=0;p=25*(((n=++n%4)-1)%2);}if(m>99&q>0){m=100;q=25*(((o=++o%4)-1)%2);}if(m<1&q<0){m=0;q=25*(((o=++o%4)-1)%2);}if(s<49);else if(s>49)q=25*(((o=++o%4)-1)%2);else p=25*(((n=++n%4)-1)%2);r+="\n"+s+": (L:"+l+"% "+(p<0?"closing":p>0?"opening":"stopped")+", R:"+m+"% "+(q<0?"closing":q>0?"opening":"stopped")+")";}return r;}

Ungolfed into a complete class:

public class Q91479 {

    public static String movedDoorsCombined() {
        String result = "";
        int i = 0, leftDoor = 0, rightDoor = 0, stepLeft = 1, stepRight = 1, changeLeft = 0, changeRight = 0;

        for (; i++ < 60;) {
            result += (int) (Math.random() * 3);
        }

        for (char step : result.toCharArray()) {
            // update stats
            leftDoor += changeLeft;
            rightDoor += changeRight;

            if (leftDoor > 99 & changeLeft > 0) {
                leftDoor = 100;
                changeLeft = 25 * (((stepLeft = ++stepLeft % 4) - 1) % 2);
            }
            if (leftDoor < 1 & changeLeft < 0) {
                leftDoor = 0;
                changeLeft = 25 * (((stepLeft = ++stepLeft % 4) - 1) % 2);
            }
            if (rightDoor > 99 & changeRight > 0) {
                rightDoor = 100;
                changeRight = 25 * (((stepRight = ++stepRight % 4) - 1) % 2);
            }
            if (rightDoor < 1 & changeRight < 0) {
                rightDoor = 0;
                changeRight = 25 * (((stepRight = ++stepRight % 4) - 1) % 2);
            }

            if (step < 49) {
                // 0
            }
            else if (step > 49) {
                // right
                changeRight = 25 * (((stepRight = ++stepRight % 4) - 1) % 2);
            }
            else {
                // left
                changeLeft = 25 * (((stepLeft = ++stepLeft % 4) - 1) % 2);
            }
            result += "\n" + step + ": (L:" + leftDoor + "% "
                        + (changeLeft < 0 ? "closing" : changeLeft > 0 ? "opening" : "stopped")
                        + ", R:" + rightDoor + "% "
                        + (changeRight < 0 ? "closing" : changeRight > 0 ? "opening" : "stopped")
                        + ")";
        }
        return result;
    }
}

Pretty straight forward. The stepLeft/stepRight variables circle from 0-3. Doing some simple maths changeLeft/changeRight hold the respective relative changes per step, which will be added to leftDoor/rightDoor. Many if statements for catching when the door has to stop on it's own.

Feel free to help me shorten this, I think there's a lot to do.

\$\endgroup\$
1
\$\begingroup\$

Haskell (lambdabot) - 409 bytes

p=(cycle[0,1,0,-1],0)
t(d:q,s)=(if d/=0&&(s+d<1||3<s+d)then q else d:q,s+d)
k i(a,b)=[o i,": (L:",j a,", ","R:",j b,")"]>>=id
j(d:_,s)=o(round$(fromIntegral s/4)*100)++"% "++words"closing stopped opening"!!(d+1)
s=scanl$ \(a,b)i->i(t a,t b)
main=do b<-(fmap(round.(*(2::Float))).take 60<$>randoms)<$>getStdGen;putStrLn.unlines$(o=<<b):(zipWith k b.w.s(p,p)$([id,f$f w,second$f w]!!)<$>b)
o=show;f=first;w=tail
\$\endgroup\$
1
  • \$\begingroup\$ Please add all the necessary imports, e.g. for randoms to your code (and byte count). If there's an interpreter that imports by default, refer to it in the language name. \$\endgroup\$
    – nimi
    Sep 7, 2016 at 23:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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