Buzzby Berkeley Robot Hokey Pokey

25

8

Buzzby Berkeley Robot Hokey Pokey

Task

Write a program or function to produce an ASCII art animation depicting a line of robots dancing to the lyrics of the Hokey Pokey (or Cokey, if you prefer) in the style of a Busby Berkeley number!

Example Output

enter image description here

Input

Accepts three arguments (assumed to be valid):

N = number of robots in the line (Min=6)

B = duration of one "beat" in milliseconds (Min=10)

D = delay in ms between successive robots (Min=0)

(In the example output above: N=8, B=380, C=75)

Specifications

  1. N robots are shown in a row upon a stage.

  2. One line of text from "the verse" is shown at a time beneath the stage (centred to within 1 character, and enclosed in quotation marks.)

  3. The robots perform the actions for each line as it is shown until the verse has been repeated 5 times.

  4. An action is performed by depicting a robot using a set of ASCII characters and waiting a specified duration before performing the next action. The duration of an action is measured in "beats". The duration of 1 beat is a number of milliseconds, B.

  5. The first robot starts performing the actions for each line of verse immediately when the line's text is displayed.

  6. Each subsequent robot delays starting its actions until a specific time (D) after the robot to its right (your left!) begins its actions.

  7. Robots' depictions vary by the ASCII characters which represent a robot's "antenna", of which there are 5 possible types, distributed randomly every time the program is run.

  8. Each type of antenna must be used by at least one robot, but the same type must not appear on any robots separated by fewer than 3 other robots. The amounts of any two types of antennae may differ by no more than 1 (e.g. 1xType_4 and 3xType_5's is illegal since 3-1>1 )

Verse and Actions

The whole verse is repeated 5 times, 1 line at a time...

Line  Text                            Action/Beats, 
----  -----------------------------   ------------------------------------
1     You put your ? in               ??/4
2     You take your ? out             AA/4
3     You put your ? in               ??/4
4     And you shake it all about      AA/1, ??/1, AA/1, ??/1
5     You do the Hokey Pokey and...   
      ...you turn yourself around     AA/1, H[1-7]/1
6     That's what it's all about!     AA/4, ZZ/4

For each repetition (R) of the verse, substitute ? and ??...

R   ?=           ??=
--  -----------  ---
1.  right foot   RF 
2.  left foot    LF
3.  right hand   RH
4.  left hand    LH
5.  whole self   WS

Actions and ASCII patterns

Each labelled action is represented by 5 lines of 8 ASCII symbols.
The representation of each action is as follows...

1 |   12     12        12    12        12     12      12   
2 |  ['']   ['']      ['']  ['']      ['']   ['']   \[*-] 
3 | └[__]┘ └[__]┘    └[__]┘┌[__]┘    └[__]┐ ┌[__]┐   [__]\ 
4 |   ||     /<        >\    <\        />    /  \     /|
5 |--------------------------------------------------------
  |\__AA__/\__RF__/\__LF__/\__RH__/\__LH__/\__WS__/\__ZZ__/ 

1 |   12     12_     34_      34      _34     _12     12    
2 |  ['']    [" ]    [ _]    [__]    [_ ]    [ "]    ['']
3 | >[__]<   [_<]    [<.]   <[..]>   [.>]    [>_]   <[__]>
4 |   ||      |\      ||      /|      ||      |\      ||
5 |--------------------------------------------------------
  |\__H1__/\__H2__/\__H3__/\__H4__/\__H5__/\__H6__/\__H7__/

In row 1, replace "1-4" with corresponding symbol for each antenna type...

1 | 1234 1234 1234 1234 1234 
  | \/\/ |┌┐| )||( |||| ┐/\┌ <-- Symbols 1-4 for...
  | 1    2    3    4    5    <-- ...antenna types 1-5

Output

The entire scene must be rendered at least once immediately whenever the content of the scene changes in any way. (I.e. assuming the delay between robots' actions is > 0, the output may be rendered no less than N times per action.)

Ideally, for an animation the console or equivalent output area is cleared before each update is rendered. To provide for languages unable to clear the console, output may also be rendered in a continuous stream, subject to the same requirement described above.

Scoring

Winners are the shortest programs in each language, as well as the shortest overall.

Exception 1 Because clearing the console each render is preferable though not required, bytes used exclusively for this luxurious purpose do not count towards the total bytes. This includes commands to clear the console, and padding output with blank lines to scroll the console contents out of view.

Exception 2 CSS or effectively similar means used exclusively for the purpose of styling the output beyond the minimum requirements do not count towards the total bytes. E.g. *{color:blue;text-align:center;} counts as only 32-10=22 bytes since color:blue; doesn't serve to satisfy any specification, whereas centred text is specified.

Meta

Inspired by (showing my age) the TRS-80 Dancing Demon, Android Nim, and of course Busby Berkeley (and no, I'm not that old).

Bumpy

Posted 2017-05-30T00:34:32.930

Reputation: 489

Great... last thing I need before I am already tired is a challenge to grab my attention. Are the tags on the top necessary? – Matt – 2017-05-30T00:53:29.357

@Matt, well the whole challenge isn't strictly "necessary", but I've removed the duplicate tags. ;-) – Bumpy – 2017-05-30T00:56:10.623

I've removed the maximum limit for input parameter 'D'. It was "D < B/N" to make sure each robot down the line had at least started the action while the first robot was still performing it (to avoid too much chaos), but by error, my own example broke that rule, and it seems to look okay anyway so I've removed the max delay limit. Apologies for that late change. – Bumpy – 2017-05-30T12:57:33.570

I've updated the section on scoring CSS and the like. – Bumpy – 2017-06-01T12:21:00.100

3That is the most adorable thing I've ever seen. – Wossname – 2017-06-06T21:13:40.737

Answers

13

Ladies and Gentlemen, please welcome our lovely

Full Frontend-Stack Dance Group, 1,320 1,378 1,425 1,495 bytes

JavaScript: 1,195 bytes | CSS: 103 bytes | HTML: 22 bytes


This is a cute challenge. It also has lots of special cases. Oh boy, so many special cases. And those antennas …

It will run forever and restart after all actions (left foot, right foot etc.) are completed.

You can try it on jsFiddle or by using the code snippet thingy below:

t=setTimeout
c=l=a=i=0
_=(x,y,z)=>{if(!i)for(;++i<=x;q=~~(Math.random()*10))s.append(document.createElement('pre'))
for(i=l=0,c=a+1;i<33;)(i=>{t($=>{if(4==i){c=0
l=1}if(8==i){c=a+1
l=0}if(12==i|14==i){c=0
l=2}if(13==i|15==i)c=a+1
if(16==i){c=0
l=3}if(16<i&24>i)c=i-10
if(24==i){c=0
l=4}if(28==i)c=6
if(31<i){a=++a%5
_(x,y,z)}for(j=0;j<x;)(j=>{t($=>s.childNodes[j][h]=(-1<[1,3,8,9].indexOf(c)?'  ':2==c||4==c?'    ' :'   ')+(11==c||12==c?'_':'')+['\\/\\/','|┌┐|',')||(','||||','┐/\\┌'][(q+j)%4].substring($=8<c&12>c?2:0,$+2)+(8==c||9==c?'_':'')+'\n'+[`  ['']      
 └[__]┘ 
   ||`,` ['']  
└[__]┘  
  /<`,`   ['']
  └[__]┘
    >\\`,` ['']
┌[__]┘
  <\\`,`   ['']
  └[__]┐
    />`,`  ['']
 ┌[__]┐
  /  \\`,` \\[*-]
  [__]\\
   <\\`,`  ['']
 >[__]<
   ||`,`  [" ]
  [_<]
   |\\`,`  [ _]
  [<.]
   ||`,`  [__]
 <[..]>
   /|`,`  [_ ]
  [.>]
   ||`,`  [ "]
  [>_]
   |\\`,`  ['']
 <[__]>
   ||`][c]+'\n-------',j*z)})(j++)
p[h='innerText']='"'+["You put your $ in","You take your $ out","And you shake it all about","You do the Hokey Pokey and you turn yourself around","That's what it's all about!"][l].replace('$',['right foot','left foot','right hand','left hand','whole self'][a])+'"'},i*y)})(i++)}

// let's dance (not included in the byte count – as if it would make any difference)
_(8, 400, 50)
*{text-align:center}x pre{display:inline-block;width:55px;text-align:left}pre{line-height:16px;margin:0
<x id=s></x><pre id=p>

Tested in Chrome and Firefox on macOS, Windows 10 and Ubuntu


Edits

  • Saved 70 bytes by removing the extra container to hold the antennas. Thanks to Bumpy. Also found some more whitespaces, removed the now unnecessary caching of createElement and removed the long access to .firstChild.
  • Saved 47 bytes – just realized that I actually don't need to call getElementById. This also makes the caching of document unnecessary.
  • Saved 4 bytes by replacing || and && with bitwise & and |. Thanks to TheLethalCoder.
  • Saved 54 bytes by simplifying lots of small things and by optimizing the CSS.

insertusernamehere

Posted 2017-05-30T00:34:32.930

Reputation: 4 551

Bravo!!! The Full Frontend-Stack Dance Group's a hit!! Apologies for the amount of special cases; I chose the antennae combinations specifically to frustrate, but the rest of the symbols were all in service of the animation - I didn't plan it to be SO fiddly. Now, I feel churlish criticising such a brilliant performance, but I think the underscores/antenna are slightly out of whack when they turn around (1 character too far to the left, possibly?) But whatever - it's great! Thanks for taking up my challenge! – Bumpy – 2017-06-01T00:59:28.063

@Bumpy Thanks. You're right, I mixed up some magic numbers. The antennas are now perfectly in order. I also managed to get the same line-height for all figures. Really a fun challenge. – insertusernamehere – 2017-06-01T09:27:30.493

Thanks again, and for your final comment; I'm so glad it amused someone :-) I made a naive implementation just to get the animation, but we took very different approaches to rendering (just 1 element <pre id=O>, then ```O.innerHTML=o````) which your proggy could easily do to save tonnes, and I wouldn't count the CSS anyway (I'll update the question to say so, thx.) But I haven't pondered much on how I'd compress the rest, so it's interesting to see how other people tackle the problem you've set. Thanks again! – Bumpy – 2017-06-01T10:08:28.353

@Bumpy Of course, I added the antennas to the actual elements and saved a whole lot of bytes. Thanks. I was writing the original around 2 o'clock in the morning and I totally overlooked the simplicity. – insertusernamehere – 2017-06-01T11:43:07.700

1Fiddling with dancing robots at 2 o'clock you say? Wonderful, bwahaha! – Bumpy – 2017-06-01T11:56:10.920

1|| and && to | and &? – TheLethalCoder – 2017-06-08T13:00:36.497

1@TheLethalCoder Absolutely. Your suggestion is already in the source and reflected in the edits. Thanks a lot. – insertusernamehere – 2017-06-13T09:18:02.863

5

C#, 1188 1376 1382 bytes after exceptions

Compacted:

namespace System.Threading{using S=String;void H(int n,int b,int d){Console.CursorVisible=false;int t,u=0,v=5,w,x,y,z;S[]i=",That's what it's all about!,,You do the Hokey Pokey and you turn yourself around,And you shake it all about,,You take? out,You put? in".Split(',');i[0]=i[1];i[2]=i[3];i[5]=i[7];for(b=b<d*n?0:b-d*n;v-->0;)for(w=32;w-->0;Thread.Sleep(b))for(t=u,z=0;z++<n;Thread.Sleep(d)){S s="",r=i[w/4].Replace("?"," your "+(v<1?"whole self":(v%2<1?"right ":"left ")+(v/3<1?"hand":"foot")));u="88880000765432109090999900009999"[w];u=u>56?9+v:u-48;for(y=4;y-->0;s+="\n")for(x=0;x<n;x++)s+=S.Format(@"{0}{0}   |\   {0}   /|   {0}   |\   {0}   /|{4} /  \{4}  />{4}<\{4}{4}>\{4}/<{4} └{1}┘  >{1}<   [_<]{4}[<.]   <[..]>   [.>]{4}[>_]   <{1}>   {1}\  ┌{1}┐   └{1}┐┌{1}┘{4}└{1}┘└{1}┘   {2}  {2}   ["" ]{4}[ _]{4}{1}{4}[_ ]{4}[ ""]   {2}  \[*-]   {2}   {2}{2}{4}{2}{2}  {3}{3}  12_{4} 34_{4}  34{4}  _34{4} _12  {3}{3}{3} {3} 12{4} {3} 12{4}", "   ||   ","[__]"," [''] ","   12   ","    ").Substring(y*14+(x<z?u:t)<<3,8).Replace("12",@"\/|┌)|||┐/".Substring(x%5*2,2)).Replace("34",@"\/┐||(||\┌".Substring(x%5*2,2));Console.Clear();Console.Write(s+new S('-',n*8)+"\n"+new S(' ',n*4-r.Length/2)+r);}}}

Slightly nicer formatting and wrapped in an executable program:

namespace System.Threading{
    using S=String;

    //** Not counted towards score: execution wrapper
    class P{
        static void Main(S[]a){
            new P().H(int.Parse(a[0]),int.Parse(a[1]),int.Parse(a[2]));
        }
    //** End not counted towards score

        void H(int n,int b,int d){
            Console.CursorVisible=false;  // Not counted under exception 2
            int t,u=0,v=5,w,x,y,z;
            S[]i=",That's what it's all about!,,You do the Hokey Pokey and you turn yourself around,And you shake it all about,,You take? out,You put? in".Split(',');
            i[0]=i[1];
            i[2]=i[3];
            i[5]=i[7];
            for(b=b<d*n?0:b-d*n;v-->0;)
                for(w=32;w-->0;Thread.Sleep(b))
                    for(t=u,z=0;z++<n;Thread.Sleep(d)){
                        S s="",r=i[w/4].Replace("?"," your "+(v<1?"whole self":(v%2<1?"right ":"left ")+(v/3<1?"hand":"foot")));
                        u="88880000765432109090999900009999"[w];
                        u=u>56?9+v:u-48;
                        for(y=4;y-->0;s+="\n")
                            for(x=0;x<n;x++)
                                s+=S.Format(@"{0}{0}   |\   {0}   /|   {0}   |\   {0}   /|{4} /  \{4}  />{4}<\{4}{4}>\{4}/<{4} └{1}┘  >{1}<   [_<]{4}[<.]   <[..]>   [.>]{4}[>_]   <{1}>   {1}\  ┌{1}┐   └{1}┐┌{1}┘{4}└{1}┘└{1}┘   {2}  {2}   ["" ]{4}[ _]{4}{1}{4}[_ ]{4}[ ""]   {2}  \[*-]   {2}   {2}{2}{4}{2}{2}  {3}{3}  12_{4} 34_{4}  34{4}  _34{4} _12  {3}{3}{3} {3} 12{4} {3} 12{4}", "   ||   ","[__]"," [''] ","   12   ","    ").Substring(y*14+(x<z?u:t)<<3,8).Replace("12",@"\/|┌)|||┐/".Substring(x%5*2,2)).Replace("34",@"\/┐||(||\┌".Substring(x%5*2,2));
                        Console.Clear(); // Not counted under exception 1
                        Console.Write(s+new S('-',n*8)+"\n"+new S(' ',n*4-r.Length/2)+r);
                    }
        }
    } // Not counted towards score: end class
}

Try it online!

  1. Visit this link: tutorialspoint.com
  2. In the Default Term tab at the bottom of the screen, type:
    mono main.exe 8 400 40

Edit 1

Replaced string.Format(i,j) with i.Replace("?",j) saving 6 bytes overall.

Edit 2

Complete revamp with suggestions from the comments.

Hand-E-Food

Posted 2017-05-30T00:34:32.930

Reputation: 7 912

Yay! Is there an easy way to run it online somewhere? – Bumpy – 2017-06-09T12:46:07.083

@Bumpy, added a link in the answer! – Hand-E-Food – 2017-06-10T13:20:31.850

Convert to an anonymous function to save a lot of bytes i.e. Action<int, int, int> or similar. Some of the verbatim strings are unnecessary. creating an array from splitting a string is usually shorter than the array itself. Use Console.Clear() as you said yourself this is [tag:code-golf]. – TheLethalCoder – 2017-06-13T09:21:55.333

Really nice solution. You encouraged me to golf off a few more bytes off of my answer. Maybe you find room to get rid of another 57 bytes. :) – insertusernamehere – 2017-06-13T09:25:05.467

1@insertusernamehere By compiling to a anonymous function and some minor golfing I've got it to under 1300. – TheLethalCoder – 2017-06-13T09:43:20.813

I think you should be able to remove c but I can't see how at the moment. You should also be able to declare i inline if you can combine the same lines together, or work out the index easier. – TheLethalCoder – 2017-06-13T10:15:25.053

Compile to an Action<int, int, int> to save more bytes. "".PadLeft(count) is usually shorter than new string. I'm not sure if there's anything else. – TheLethalCoder – 2017-06-13T14:09:06.900

1@insertusernamehere, done! Your turn! :-D – Hand-E-Food – 2017-06-13T14:11:11.047

1@TheLethalCoder, thanks for that! I got rid of c for a small saving. I knew I'd forgotten a better way than new string(c,n). However, now that I've aliased S=String, new S(c,n) is shorter still. – Hand-E-Food – 2017-06-13T14:14:22.897

0

JavaScript, 948 bytes

Probably poor form to answer your own question, but anyway...

Tried all sorts of ways to compress the text, but most ended up longer than the original with the key+algorithm included. I'm certain there's still a more optimal way to compress it all down, but I have to draw the line somewhere.

Interestingly, the search yielded one or two ideas for some other challenges which I might refine and post later.

<pre id=O/>

f=(N,B,D)=>{Q=c=>(K={},k='~',[...c].map(v=>v<k?K[k=v]='':K[k]+=K[v]||v),K[k])
x=``,A=`//,||,)||(,,/`.split(',').sort(new Date)
r=new Array(N).fill(0),t=i=v=0,n=`\n`,T=setTimeout
C=_=>(w=Q(`ouhand t t's ake Y y all abtokey righlefwhole fooself ,${v+1},,1yr ${x[v*2]+x[v*2+1]}puintt,,Ashi,do the HPaturn yrarnd,,7,8,90123,Twi!,,6,`).split(',')[i++])<'A'?(r.map((_,m)=>T((a,b)=>R(r[N-a]=b),m*D,m,w)),i>22?(v++,i=0):0,v<3?T(C,B*(i<7||i>21?4:1)):0):C(t=w),R=_=>{for(o='',m=4;m--;o+=n){for(w=N;w--;)o+=Q(`┌┐└┘\\/||/${A[w%5]}   [__] [''] ||] _ __ _  [*-][" ][ _][_ ][ "] ┐ ┐><[_<] [<.]<[..]>[.>] [>_]<> /<></>/ //`).substr(r[w]*8+(3-m)*112,8)}
O.innerHTML=o+'-'.repeat(N*8)+' '.repeat(((N*8)-t.length)/2)+t}
C()}

(NB: Contains some characters in the range 1-31 whose representations are a bit odd when posted here)

Watch the full psychedelic dance cycle on CodePen!

Bumpy

Posted 2017-05-30T00:34:32.930

Reputation: 489