15
\$\begingroup\$

"Y.M.C.A." is a popular disco song by the Village People that has a well-known dance. Write the shortest program to output the capital letters "Y", "M", "C", and "A" synchronized to the song's chorus.

Generally, one letter goes on each line sent to standard output. This primarily is to simplify programs subject to the output buffering of the C standard library (printing a newline flushes the output buffer), so you may omit any or all of these newlines if such omission would make your program shorter.

Your program, which is started at the same time as the music, must output the letter "Y" within 0.125 s of each of these times after starting (in seconds; I determined these from the music video posted on YouTube).

 45.766   49.611   60.889
 64.661  109.816  113.591
124.810  128.687  173.830
177.620  188.950  192.724
204.013  207.739  219.057

The letters "M", "C", and "A" respectively come 0.930 s, 1.395 s, and 1.628 s after each "Y". For testing purposes, these relative times are converted into absolute times by adding them to the time of the preceding "Y".

I have written a test program and corresponding example program in C that assume a newline follows each letter (although this is not a rule of competition). It is written for Linux and will not work on Windows without using Cygwin. If you cannot test your submission using the test program, at least check your submission against the YouTube video.

If your submission requires a special command-line option to behave properly, that command-line option counts when calculating your score. However, any interpreter startup time does not count against you, and the test program can be modified to accommodate that if necessary.

Although I doubt one exists, I must say that using a programming language function or library designed specifically for this task is prohibited.

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

C, 161 154 chars

#define P(d,x)w(d);puts(#x);
w(n){usleep(n<<16);}
y(d){P(d,Y)P(14,M)P(7,C)P(3,A)}
b(){y(664);y(35);y(147);y(35);}
main(){b(b(b(w(34))));y(148);y(33);y(148);}

The tester passes, but only if fflush(stdout); is added after each puts. Since the question clearly states that fflush is not required, I take it as a problem in the tester.

Logic:
w sleeps, the time is given in units of 16.384 65.536 ms. This resolution allows accurate enough timing and small constants (I should perhaps try 100ms).
P waits a while and prints a character.
y prints a YMCA sequence, after an initial delay.
b prints 4 YMCA sequences - this 4*YMCA happens 3 times, with similar enough timing.
main prints the 3*4*YMCA sequences, plus the remaining 3.

\$\endgroup\$
  • \$\begingroup\$ "a problem in the tester" - You're right, as apparently pipes are not "interactive" devices :( I will make it use a PTY (which should be more realistic) instead of a pipe as soon as I get the time to. \$\endgroup\$ – PleaseStand Jul 23 '12 at 17:53
  • \$\begingroup\$ OK, I changed the tester to use a PTY, and your program passes the test. I also found out about a utility called stdbuf that uses some LD_PRELOAD trick to override the default buffering behavior of the C standard I/O library. \$\endgroup\$ – PleaseStand Jul 26 '12 at 21:00
4
\$\begingroup\$

Ruby 180 135 124 118 108 104

[458,k=22,*[97,k,435,k]*2,*[98,k]*2,98].flat_map{|e|[e,9,5,2]}.zip(%w(Y M C A)*15){|a,b|sleep a/1e1;p b}
\$\endgroup\$
  • \$\begingroup\$ I just realized there is nothing in the rules prohibiting double quotes around each letter. However, the submission seems to work perfectly :) \$\endgroup\$ – PleaseStand Jul 22 '12 at 6:19
  • 1
    \$\begingroup\$ The second part of codegolf.stackexchange.com/questions/6695/… is relevant to you too. \$\endgroup\$ – JPvdMerwe Jul 22 '12 at 6:42
  • \$\begingroup\$ @JPvdMerwe Thanks a lot! You'e right. Dropping two decimals does not have any significant effect. Also, after I did that I noticed that if I tweak the values ±0.1 there are some patterns that allow the array to be constructed in less chars. \$\endgroup\$ – Cristian Lupascu Jul 22 '12 at 11:40
  • \$\begingroup\$ Could you do %w(Y M C A)*15 instead of 'Y M C A'.split*15 to generate the letters? Also that each could probably be a map even though you don't need the output. Oh, and you can write 10.0 as 1e1! \$\endgroup\$ – Paul Prestidge Jul 22 '12 at 22:42
  • \$\begingroup\$ @chron Thanks! I thought there was nothing much I could do to golf this code even more, but I was obviously wrong. :-) \$\endgroup\$ – Cristian Lupascu Jul 23 '12 at 6:43
0
\$\begingroup\$

Python2.6 (82)(214)(219)(196)(185)(152)

Fixed. Ran against the video & seems accurate. Saved quiet a few characters by reducing the precision from 3 to 2 in most of the cases(thanks for the tip @JPvdMerwe).

The only problem is that the tester shows a huge discrepancy in the timings. It starts out of sync & tries to come back into sync. In the two test cases it was more than 175 seconds out of sync at the beginning and came back to within 0.342 and 0.451 seconds of being back in sync.

import time;s=time.sleep
for t in[45.8,2.1,9.5,2,43.4,2,9.5,2.1,43.4,2,9.6,2,9.5,2,9.6]*15:
 i=0;s(t)
 while i<4:s([.1,.9,.5,.2][i]);print'YMCA'[i];i+=1
\$\endgroup\$
  • \$\begingroup\$ Can you make it run at each of the fifteen times listed above? It also seems that on my machine, you will need to include the -u command line option in the count. \$\endgroup\$ – PleaseStand Jul 21 '12 at 15:22
  • \$\begingroup\$ @PleaseStand done, now it runs 15 times. I don't know about adding -u, don't need it on mine. I have Python2.6, if that helps \$\endgroup\$ – elssar Jul 21 '12 at 15:42
  • \$\begingroup\$ To clarify, your program should print the first "Y" after approximately 45.766 s, and -u is necessary for the tester program (which uses a pipe), not for output directly to a terminal. \$\endgroup\$ – PleaseStand Jul 21 '12 at 15:50
  • \$\begingroup\$ @PleaseStand Yeah, I was wondering about the timing. Was gonna ask you, but you already answered before I had a chance. And about the tester program, is it a requirement that the program runs on your tester as it is, or will you accept submissions that need to be modified to run on the tester, but run fine standalone? \$\endgroup\$ – elssar Jul 21 '12 at 16:27
  • \$\begingroup\$ Humm, I can pass my code to the tester without having to use any options \$\endgroup\$ – elssar Jul 21 '12 at 16:55
0
\$\begingroup\$

Mathematica, 157

p=Print[Pause@#;#2]&

(#~p~"Y";.93~p~"M";.465~p~"C";.233~p~"A")&/@{45.766,2.217,9.65,2.144,43.527,2.147,9.591,2.249,43.515,2.162,9.702,2.146,9.661,2.098,9.69}

I watched the entire video to confirm the timing. Y M C A.... Y M C A...

It could be shorter with less precision, but then I'd have to watch the video again to confirm that it was not off by more than .125 at the end. lol

\$\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.