7
\$\begingroup\$

If you're not familiar, Dance Dance Revolution is a rhythm game where you hit four receptors (left, down, up, right) with your feet as arrows scroll up the screen. One of the file formats used to lay out the arrow patterns looks something like this:

1000
0100
0000
0011
,

A 1 represents a tap note. This chart has a left tap, a down tap, an empty line, and an up-right jump, respectively. The comma at the end indicates the end of a measure, and there can be any number of measures in a song.

Now here's an example of a more complicated chart:

1000
0010
0100
0001
0010
0100
2000
0000
,
0010
0001
3100
1001
,

The first measure has eight lines, so each line represents an eighth note, but the second measure only has four lines, all of which are quarter notes. All measures are the same duration; measures containing more lines are simply denser. You can assume that all measures will have lengths that are powers of two greater than or equal to 4. So measures can have 4 lines, 8 lines, 16 lines, and so on.

A 2 indicates the start of a hold arrow and a 3 represents its end. You can assume that each 2 will have a corresponding 3 in the same column, without anything between them other than zeroes and/or measure boundaries.

Your task is to print the stepchart in a more human-readable format. It's probably best if I just give you an example. Here's the expected output for the chart given above:

<
  ^
 v
   >
  ^
 v
<
|
| ^
|
|  >
|
|v

<  >

(If this is confusing to you, perhaps looking at this will help.)

Left, down, up, and right taps are indicated by <, v, ^, and >, respectively. Hold arrows are indicated by pipes that trail beneath the starting taps.

Additionally, the chart needs to be stretched so that each measure is the same length: in the above example, the measures have lengths of 8 and 4, so the output shows all measures as if they contained eighths. If you have a chart where all measures are 4 lines long except for one that's 64 lines, the output needs to render all measures as 64 lines long!

I/O: Assume the chart exists in a file whose name is given as the first argument to the program (e.g. python arrows.py input.txt). Write to standard output. If (and only if) your language of choice doesn't have filesystem access for whatever reason, it's acceptable to load it as a string at the beginning of the program.

Goal: The program with the fewest characters will be accepted a week from now, the 17th of August, around 8:00 EST.

\$\endgroup\$
  • \$\begingroup\$ Can the held steps be exclusive? By that I mean that the location in the file where a '3' is present, there is no '|', but they are present in the previous lines? Also is it necessary to prevent an error if the file name is invalid? \$\endgroup\$ – Kaslai Aug 11 '12 at 5:08
  • \$\begingroup\$ @Aslai, there should be a pipe on the location of the 3 because otherwise, if there were a 2 immediately followed by a 3, it would look identical to a tap note. You don't have to handle invalid input (bad filename, malformed chart data) in any way. \$\endgroup\$ – Fraxtil Aug 11 '12 at 6:54
  • \$\begingroup\$ Can there be more that one hold active at a time? (Common sense suggests there can't be more than two since humans have but two feet.. assuming humans.. and feet...) \$\endgroup\$ – baby-rabbit Aug 13 '12 at 22:14
  • \$\begingroup\$ @baby-rabbit, there can potentially be four active holds simultaneously, although that doesn't show up in actual dance charts too often. :) \$\endgroup\$ – Fraxtil Aug 13 '12 at 23:43
5
\$\begingroup\$

GolfScript 132 129

','/{n/{},}%{},.{,}%.$):§;;{§\/(}%]zip{~:¥;{['0'4*]¥*~}%}%{+}*zip 1:¤;{0:^;{.^2=5@48=!¤*if\48-^or:^;' <v^>|'=}%¤):¤;}%zip{+}*4/n*

Online demo here

\$\endgroup\$
4
\$\begingroup\$

C, 364, 331, 310, 293

#define L(A)for(p=b+9;*p;)if(*p-44){A;t++;p+=5;}else{m=t>m?t:m;p[4-5*t]=t;t=0;p+=2;}
c,j,t,m,x;char b[9999],*p;main(int i,char*v[]){read(open(v[1],0),b+9,9999);L()L(x=t?x:m/p[4];for(j=x*4;j-->0;){i=j%4;b[i]=" |"[b[i+5]];c=p[i]&3;p[i]=0;if(c&&c<3)b[i]="<v^>"[i];if(c>1)b[i+5]=3-c;i?:puts(b);})}

Limits:

  • max input file size of 9990 chars
  • max measure of 128

Run:

./a.out test.dance

output:

<   
  ^ 
 v  
   >
  ^ 
 v  
<   
|   
| ^ 
|   
|  >
|   
|v  

<  >

Ungolfed commented version:

#define L(A)\
  for(p=b+9;*p;)/* loop through file */\
    if(*p-44){     /* line */\
          A;\
          t++;\
          p+=5;       /* 4 steps+linefeed */\
    }else{         /* comma line */\
          m=t>m?t:m;  /* max measure */\
          p[4-5*t]=t; /* store measure in '\n' char of first line */\
          t=0;\
          p+=2;       /* comma+linefeed */\
    }

c,j,t,m,x;char b[9999],*p; // b[0..4] output, b[5..8]=hold, b[9..9999]=file
main(int i,char*v[]){
    read(open(v[1],0),b+9,9999);
    // pass 1 - determine max measure
    L()
    // pass 2 - process steps and output
    L(x=t?x:m/p[4]; // repeats per line (first line p[4] is measure)
      for(j=x*4;j-->0;){ // 4 steps per repeat
          i=j%4;         // the step
          b[i]=" |"[b[i+5]];
          c=p[i]&3;      // step type 0,1,2,3
          p[i]=0;        // reset step to 0 for future iterations
          if(c&&c<3)b[i]="<v^>"[i];
          if(c>1)b[i+5]=3-c; // set/reset hold
          i?:puts(b);    // every 4th step
      }
    )
}
\$\endgroup\$
  • \$\begingroup\$ Good game, sir. \$\endgroup\$ – Kaslai Aug 12 '12 at 2:11
3
\$\begingroup\$

C - 466 460 438 bytes

#define C while(fgets(b,6,f))
p[9]={'>^v<',0,'||||',0,'    '},Y,M,T,R,E,*W,Q,i;char b[9];main(int n,char*v[]){int*f=fopen(v[1],"r");W=malloc(4e5);C if(*b!=44)++T;else{W[++Q-1]=T;Y=T>Y?T:Y;T=0;}fseek(f,0,0);Q=0;C{if(*b!=44){R=0;M=E;for(i=0;i<4;++i){R|=(b[i]>48&&b[i]<51)*255<<i*8;E|=b[i]==50?255<<i*8:0;E&=~(b[i]==51?255<<i*8:0);}p[6]=*p&R|(~R^M)&p[4]|(M&R^M)&p[2];puts(p+6);p[6]=p[4]&~E|p[2]&E;for(i=0;i<Y/W[Q]-1;++i)puts(p+6);}else++Q;}}

The output from this, using the given input file, is:

<
  ^
 v
   >
  ^
 v
<
|
| ^
|
|  >
|
|v

<  >

Should be fairly compliant to most compilers.

\$\endgroup\$
  • \$\begingroup\$ I count 466 chars here, guess it's a typo. You can save 12 bytes by using multi-character character constants: p[9]={'>^v<',0,'||||',0,'    '} \$\endgroup\$ – schnaader Aug 11 '12 at 15:51
  • \$\begingroup\$ Aha, I forgot about multicharacter char literals. I also fixed it up according to my comment on the main question. Hooray for bitwise manipulation! \$\endgroup\$ – Kaslai Aug 12 '12 at 0:56
3
\$\begingroup\$

PHP 274 chars

My first code golf. All comments are welcome.

<?php
    $i = '1000 0010 0100 0001 0010 0100 2000 0000 0010 0001 3100 1001 ,';
    $f=explode(' ', $i);$a=array("<","v","^",">");$t=-1;foreach($f as$n){if($n==',')return;else{$j=str_split($n);$o=0;foreach($j as$h){switch($h){case 2:$t=$o;case 1:$h=$a[$o];break;case 0:$h=" ";if($t>=0&&$t==$o){$h="|";}break;case 3:$t=4;$h="|";break;}echo$h;$o++;}echo"\n";}}
?>

Should I count the <?php ?> tags?

Thank you.

\$\endgroup\$
  • \$\begingroup\$ Whenever I golf with my friend who uses PHP, he has a <? tag but no php or ?>. The official PHP parser handles this, but it's out of spec. But hey, this is codegolf, where undefined behavior rules the school. \$\endgroup\$ – Kaslai Aug 14 '12 at 19:23
2
\$\begingroup\$

Mathematica 283 chars

The following works with measures of 2^(2 n) lines.

v = Import["a.xls"]; 
g@p_ := 2~Log~p; t = Transpose; l = Length; s = Sequence;
r_~h~o_ := t[Flatten[
    Riffle[#, x, {2, -1, 2}] /. x -> s @@ ConstantArray[{0, 0, 0, 0}, 
          2^(g@Max[l /@ v] - g@l@#) - 1] & /@ v, 1]][[r]] 
    /. {a___, 2, b__, 3, c___} :>  {a, 2, s @@ Cases[{b}, 0 :> "|"], "|", c} 
    /. {0 -> " "} /. {1 | 2 -> o};
t@{1~h~"<", 2~h~"v", 3~h~"^", 4~h~">"} // Grid

Data file, imported as v, is structured as follows:

{{{1,0,0,0},{0,0,1,0},{0,1,0,0},{0,0,0,1},{0,0,1,0},{0,1,0,0},{2,0,0,0},{0,0,0,0}},{{0,0,1,0},{0,0,0,1},{3,1,0,0},{1,0,0,1}}};
\$\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.