Daft Punk - experiment in efficiency

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

noy2222
Posts: 4
Joined: Wed Apr 10, 2013 6:18 pm UTC

Daft Punk - experiment in efficiency

Postby noy2222 » Wed Apr 10, 2013 6:35 pm UTC

A while ago I've made a script in C to present the lyrics to Better, Faster, Stronger.
As oppose to just printfing the lines, I've attempted to use the song's repetitiveness to try and make a script that's efficient as possible with as little repetition or useless ifs as possible.
Every now and again I came back to it and removed more lines and characters.
This is my current version - pastebin(dot)com/izPwP6JG and its compiled result - tinyurl(dot)com/bru8w3w

Spoiler:

Code: Select all

#include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    int main()
    {
        for(int i=1;i<17;i++)
        {
                         printf("Work it ");
                         if((i>2)&&(i!=12))
                                printf("harder\n");                 
                         else
                                printf("\n");
                         getch();
                         if(i!=15)
                         {       
                                   printf("Make it ");
                                   if((((i>2)&&(i<8))||((i==9)||(i==12)))||(((i==14)||(i==16))))
                                           printf("better\n");
                                   else
                                           printf("\n");                         
                                   getch();
                         }
                         if((i==11)||(i==13))
                                printf("Just do it ");
                         else
                                printf("Do it ");
                         if(i>2)
                                printf("faster\n");
                         else
                                printf("\n");
                         getch();
                         if(i!=15)
                         {
                                  printf("Makes us ");
                                  if (((i<3)||(i==8))||((i==10)||(i==15)))
                                            printf("\n");                       
                                  else
                                            printf("stronger\n");
                                  getch();
                         }
                         if (i<3)
                         {
                                 printf("Harder\n");
                                 getch();
                                 printf("Better\n");
                                 getch();
                                 printf("Faster\n");
                                 getch();
                                 printf("Stronger\n");
                                 getch();
                         }
                         if (i==1)
                         {
                                 printf("More than\n");
                                 getch();
                                 printf("Hour\n");
                                 getch();
                                 printf("Our\n");
                                 getch();
                                 printf("Never\n");
                                 getch();
                                 printf("Ever\n");
                                 getch();
                                 printf("After\n");
                                 getch();
                                 printf("Work is\n");
                                 getch();
                                 printf("Over\n");
                                 getch();
                         }
                         if (i>2)
                         {
                                 if ((i==11)||(i==13))
                                    printf("Than ever\n");
                                 else
                                     printf("More than ever\n");
                                 getch();
                                 if(i!=15)
                                 {
                                           printf("Hour after\n");
                                           getch();
                                 }
                                 printf("Our work is\n");
                                 getch();
                                 printf("Never over\n");
                                 getch();
                         }   
                         system("cls");         
           }   
    }


So my question is - is it possible to produce the same output by removing any characters (aside from preceding spaces) or calling for additional custom functions (I imagine a shorter call for getch(); would be economic, but that's cheating)?
Last edited by phlip on Thu Apr 11, 2013 3:18 am UTC, edited 1 time in total.
Reason: Added [code] tags

Divinas
Posts: 57
Joined: Wed Aug 26, 2009 7:04 am UTC

Re: Daft Punk - experiment in efficiency

Postby Divinas » Thu Apr 11, 2013 10:30 am UTC

Here's my idea. It can be made shorter with some trivial changes. The output may not be exactly as yours, but the idea is pretty much the same, and can be easily made to match yours exactly (I didn't walk through the entire lyrics to make sure it works exactly as yours does). An online char counter says I have 2089 chars.

Spoiler:

Code: Select all

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

char* words[] = {"VERSE", "DELAY", "Do", "Over", "After", "Faster", "Hour", "Stronger", "Makes", "Is", "Never", "Harder", "It", "Us", "Better", "Make", "Gonna", "Work", "Ever", "Than", "More"};
int lyrics[] = {17, 12, 1, 15, 12, 1, 2, 12, 1, 8, 13, 1, 11, 1, 14, 1, 5, 1, 7, 1, 0, 20, 19, 1, 6, 1, 6, 1, 10, 1, 18, 1, 4, 1, 17, 9, 1, 3, 1, 0, 17, 12, 1, 15, 12, 1, 2, 12, 1, 8, 13, 1, 11, 1, 14, 1, 5, 1, 7, 1, 0, 17, 12, 11, 1, 15, 12, 14, 1, 2, 12, 5, 1, 8, 13, 7, 1, 0, 20, 19, 18, 1, 6, 4, 6, 1, 17, 9, 10, 3, 1, 0, 17, 12, 11, 1, 15, 12, 14, 1, 2, 12, 5, 1, 8, 13, 7, 1, 0, 20, 19, 18, 1, 6, 4, 6, 1, 17, 9, 10, 3, 1, 0, 17, 12, 11, 15, 12, 14, 1, 2, 12, 5, 8, 13, 7, 1, 20, 19, 18, 6, 4, 6, 1, 17, 9, 10, 3, 1, 0, 17, 12, 11, 15, 12, 14, 1, 2, 12, 5, 8, 13, 7, 1, 20, 19, 18, 6, 4, 6, 1, 17, 9, 10, 3, 1, 0, 17, 12, 11, 15, 12, 14, 1, 2, 12, 5, 8, 13, 7, 1, 20, 19, 18, 6, 4, 6, 1, 17, 9, 10, 3, 1, 0, 17, 12, 11, 15, 12, 14, 1, 2, 12, 5, 8, 13, 7, 1, 20, 19, 18, 6, 4, 6, 1, 17, 9, 10, 3, 1, 0, 17, 12, 11, 15, 12, 14, 1, 2, 12, 5, 8, 13, 7, 1, 20, 19, 18, 6, 4, 6, 1, 17, 9, 10, 3, 1, 0, 16, 17, 12, 11, 15, 12, 1, 16, 2, 12, 5, 8, 13, 1, 20, 19, 18, 6, 4, 6, 1, 17, 9, 10, 3, 1, 0, 17, 12, 11, 15, 12, 14, 1, 2, 12, 5, 8, 13, 7, 1, 20, 19, 18, 6, 4, 6, 1, 17, 9, 10, 3, 1, 0, 17, 12, 11, 15, 12, 14, 1, 2, 12, 5, 8, 13, 7, 1, 20, 19, 18, 6, 4, 6, 1, 17, 9, 10, 3, 1, 0, 17, 12, 11, 15, 12, 14, 1, 2, 12, 5, 8, 13, 7, 1, 20, 19, 18, 6, 4, 6, 1, 17, 9, 10, 3, 1, 0, 17, 12, 11, 1, 2, 12, 5, 1, 20, 19, 18, 6, 1, 17, 9, 10, 3, 1, 0, 17, 12, 11, 15, 12, 14, 1, 2, 12, 5, 8, 13, 7, 1, 20, 19, 18, 6, 4, 6, 1, 17, 9, 10, 3};

int main()
{
    int lyricsCount = sizeof(lyrics) / sizeof(int);
    for (int i = 0; i < lyricsCount; ++i)
    {
        if (lyrics[i] == 1)
        {
            printf("\n");
            getch();
        }
        else if (lyrics[i] == 0)
        {
            getch();
            system("cls");
        }
        else
            printf("%s ", words[lyrics[i]]);
    }
}

noy2222
Posts: 4
Joined: Wed Apr 10, 2013 6:18 pm UTC

Re: Daft Punk - experiment in efficiency

Postby noy2222 » Thu Apr 11, 2013 12:24 pm UTC

While your solution is pretty awesome, it is longer than mine.
Almost twice the characters.

User avatar
Xenomortis
Not actually a special flower.
Posts: 1448
Joined: Thu Oct 11, 2012 8:47 am UTC

Re: Daft Punk - experiment in efficiency

Postby Xenomortis » Thu Apr 11, 2013 12:33 pm UTC

Stripping out all the spaces gives it at about 30% more.
Some of the spaces are syntactically significant, but most are not.
Image

CLD
be at least somewhat witty
Posts: 44
Joined: Sat Oct 06, 2012 12:11 pm UTC

Re: Daft Punk - experiment in efficiency

Postby CLD » Thu Apr 11, 2013 12:35 pm UTC

Code: Select all

Print from lyrics.com/Stronger


Or something like that. :)
Spoiler:
Satea Murua
Episode 1 - Silent Square
Turn 2 taken - Uly, B, Rfuinbeg, Miryllastasia, Jalvier Chaussier, Shyl
Turn 2 waiting - Esteban Bernardo

Divinas
Posts: 57
Joined: Wed Aug 26, 2009 7:04 am UTC

Re: Daft Punk - experiment in efficiency

Postby Divinas » Thu Apr 11, 2013 12:40 pm UTC

Ok, the char count with whitespaces stripped is 1444 for mine and 1058 for yours. Challenge accepted, I have a few ideas :)

Ben-oni
Posts: 278
Joined: Mon Sep 26, 2011 4:56 am UTC

Re: Daft Punk - experiment in efficiency

Postby Ben-oni » Thu Apr 11, 2013 5:08 pm UTC

Oooh, are we playing golf?

Slight optimization:

Code: Select all

#include <stdio.h>
char* w[] = {"", "", "Do", "Over", "After", "Faster", "Hour", "Stronger", "Makes", "Is", "Never", "Harder", "It", "Us", "Better", "Make", "Gonna", "Work", "Ever", "Than", "More"};
const char* s = "rmbpmbcmbinblbobfbhbautbgbgbkbsbebrjbdbarmbpmbcmbinblbobfbhbarmlbpmobcmfbinhbautsbgegbrjkdbarmlbpmobcmfbinhbautsbgegbrjkdbarmlpmobcmfinhbutsgegbrjkdbarmlpmobcmfinhbutsgegbrjkdbarmlpmobcmfinhbutsgegbrjkdbarmlpmobcmfinhbutsgegbrjkdbarmlpmobcmfinhbutsgegbrjkdbaqrmlpmbqcmfinbutsgegbrjkdbarmlpmobcmfinhbutsgegbrjkdbarmlpmobcmfinhbutsgegbrjkdbarmlpmobcmfinhbutsgegbrjkdbarmlbcmfbutsgbrjkdbarmlpmobcmfinhbutsgegbrjkd";
void main() {
   while (*s!=0) {
      int x = (*(s++) - 'a');
      if (!x)
         puts("");
      else if (x-1)
         printf("%s ", w[x]);
      else
         puts("");
   }
}

User avatar
Xenomortis
Not actually a special flower.
Posts: 1448
Joined: Thu Oct 11, 2012 8:47 am UTC

Re: Daft Punk - experiment in efficiency

Postby Xenomortis » Thu Apr 11, 2013 8:07 pm UTC

Less than 1000 characters I think.
I might make the obvious improvements.

Also, it's amazing how much inconsistent differing sources are on the lyrics.

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char* w[] = {"","Do", "Over", "After", "Faster", "Hour", "Stronger", "Makes",
        "Is", "Never", "Harder", "It", "Us", "Better", "Make", "Gonna", "Work", "Ever", "Than", "More","Our"};
    int p1[] = {16,11,0,14,11,0,1,11,0,7,12,0,10,0,13,0,4,0,6,-2};
    int p2[] = {19,18,0,5,0,20,0,9,0,17,0,3,0,16,8,0,2,-2};
    int p3[] = {16,11,10,0,14,11,13,0,1,11,4,0,7,12,6,-2};
    int p4[] = {19,18,17,0,5,3,0,20,16,8,0,9,2,-2};
    int p5[] = {16,11,10,14,11,0,1,11,4,7,12,0,19,18,17,5,0,20,16,8,-2};
    int p6[] = {16,11,10,0,1,11,4,0,19,18,17,0,20,16,8,9,2,-2};
    int* s[] = {p1,p2,p1,p3,p4,p3,p4,p3,p4,p3,p4,p3,p4,p3,p4,p5,p5,p3,p4,p5,p5,p3,p4,p6,p3,p4};
    for(int i=0;i<26;i++){
        int j=0;
        int n;
        do{
            n = s[i][j];
            printf(n>0?"%s ":"\n",w[n]);
            j++;
        }while(n>-2);
    }
    return 0;
}


(Yes, I stole the array of the poster above me)


Edit:
int[]'s are now char[]'s

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char* w[] = {"","Do", "Over", "After", "Faster", "Hour", "Stronger", "Makes",
        "Is", "Never", "Harder", "It", "Us", "Better", "Make", "Gonna", "Work", "Ever", "Than", "More","Our"};
    char a[] ="pk`nk`ak`gl`j`m`d`f.";
    char b[] ="sr`e`t`i`q`c`ph`b.";
    char c[]="pkj`nkm`akd`glf.";
    char d[]="srq`ec`tph`ib.";
    char e[] ="pkjnk`akdgl`srqe`tph.";
    char f[]="pkj`akd`srq`tphib.";
    char* s[] = {a,b,a,c,d,c,d,c,d,c,d,c,d,c,d,e,e,c,d,e,e,c,d,f,c,d};
    for(int i=0;i<26;i++){
        int n,j = 0;
        do{
            n=s[i][j++]-96;
            printf(n>0?"%s ":"\n",w[n]);
        }while(n>-2);
    }
    return 0;
}


A couple of obvious changes would cut the count by a little bit. Currently around 700; Ben-oni's solution is about 800.
Image

noy2222
Posts: 4
Joined: Wed Apr 10, 2013 6:18 pm UTC

Re: Daft Punk - experiment in efficiency

Postby noy2222 » Thu Apr 11, 2013 10:53 pm UTC

if we're doing a proper competition, the output in all codes should be the same.
To clarify:

Spoiler:
<1>
Work it
<Pause>
Make it
<Pause>
Do it
<Pause>
Makes us
<Pause>
Harder
<Pause>
Better
<Pause>
Faster
<Pause>
Stronger
<Pause>
More than
<Pause>
Hour
<Pause>
Our
<Pause>
Never
<Pause>
Ever
<Pause>
After
<Pause>
Work is
<Pause>
Over
<Pause>
<Clear screen>

<2>
Work it
<Pause>
Make it
<Pause>
Do it
<Pause>
Makes us
<Pause>
Harder
<Pause>
Better
<Pause>
Faster
<Pause>
Stronger
<Pause>
<Clear screen>

<3>
Work it harder
<Pause>
Make it better
<Pause>
Do it faster
<Pause>
Makes us stronger
<Pause>
More than ever
<Pause>
Hour after
<Pause>
Our work is
<Pause>
Never over
<Pause>
<Clear screen>

<4>
Work it harder
<Pause>
Make it better
<Pause>
Do it faster
<Pause>
Makes us stronger
<Pause>
More than ever
<Pause>
Hour after
<Pause>
Our work is
<Pause>
Never over
<Pause>
<Clear screen>

<5>
Work it harder
<Pause>
Make it better
<Pause>
Do it faster
<Pause>
Makes us stronger
<Pause>
More than ever
<Pause>
Hour after
<Pause>
Our work is
<Pause>
Never over
<Pause>
<Clear screen>

<6>
Work it harder
<Pause>
Make it better
<Pause>
Do it faster
<Pause>
Makes us stronger
<Pause>
More than ever
<Pause>
Hour after
<Pause>
Our work is
<Pause>
Never over
<Pause>
<Clear screen>

<7>
Work it harder
<Pause>
Make it better
<Pause>
Do it faster
<Pause>
Makes us stronger
<Pause>
More than ever
<Pause>
Hour after
<Pause>
Our work is
<Pause>
Never over
<Pause>
<Clear screen>

<8>
Work it harder
<Pause>
Make it
<Pause>
Do it faster
<Pause>
Makes us
<Pause>
More than ever
<Pause>
Hour after
<Pause>
Our work is
<Pause>
Never over
<Pause>
<Clear screen>

<9>
Work it harder
<Pause>
Make it better
<Pause>
Do it faster
<Pause>
Makes us stronger
<Pause>
More than ever
<Pause>
Hour after
<Pause>
Our work is
<Pause>
Never over
<Pause>
<Clear screen>

<10>
Work it harder
<Pause>
Make it
<Pause>
Do it faster
<Pause>
Makes us
<Pause>
More than ever
<Pause>
Hour after
<Pause>
Our work is
<Pause>
Never over
<Pause>
<Clear screen>

<11>
Work it harder
<Pause>
Make it
<Pause>
Just do it faster
<Pause>
Makes us stronger
<Pause>
Than ever
<Pause>
Hour after
<Pause>
Our work is
<Pause>
Never over
<Pause>
<Clear screen>

<12>
Work it
<Pause>
Make it better
<Pause>
Do it faster
<Pause>
Makes us stronger
<Pause>
More than ever
<Pause>
Hour after
<Pause>
Our work is
<Pause>
Never over
<Pause>
<Clear screen>

<13>
Work it harder
<Pause>
Make it
<Pause>
Just do it faster
<Pause>
Makes us stronger
<Pause>
Than ever
<Pause>
Hour after
<Pause>
Our work is
<Pause>
Never over
<Pause>
<Clear screen>

<14>
Work it harder
<Pause>
Make it better
<Pause>
Do it faster
<Pause>
Makes us stronger
<Pause>
More than ever
<Pause>
Hour after
<Pause>
Our work is
<Pause>
Never over
<Pause>
<Clear screen>

<15>
Work it harder
<Pause>
Do it faster
<Pause>
More than ever
<Pause>
Our work is
<Pause>
Never over
<Pause>
<Clear screen>

<16>
Work it harder
<Pause>
Make it better
<Pause>
Do it faster
<Pause>
Makes us stronger
<Pause>
More than ever
<Pause>
Hour after
<Pause>
Our work is
<Pause>
Never over
<Pause>

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Daft Punk - experiment in efficiency

Postby EvanED » Thu Apr 11, 2013 11:23 pm UTC

I don't suppose you'll let me cheat and output EVERYTHING IN CAPITAL LETTERS, huh? Edit Oh I just thought of a different way to get what I want. I'll work toward that maybe.

Xenomortis wrote:

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char* w[] = {"","Do", "Over", "After", "Faster", "Hour", "Stronger", "Makes",
        "Is", "Never", "Harder", "It", "Us", "Better", "Make", "Gonna", "Work", "Ever", "Than", "More","Our"};
    char a[] ="pk`nk`ak`gl`j`m`d`f.";
    char b[] ="sr`e`t`i`q`c`ph`b.";
    char c[]="pkj`nkm`akd`glf.";
    char d[]="srq`ec`tph`ib.";
    char e[] ="pkjnk`akdgl`srqe`tph.";
    char f[]="pkj`akd`srq`tphib.";
    char* s[] = {a,b,a,c,d,c,d,c,d,c,d,c,d,c,d,e,e,c,d,e,e,c,d,f,c,d};
    for(int i=0;i<26;i++){
        int n,j = 0;
        do{
            n=s[i][j++]-96;
            printf(n>0?"%s ":"\n",w[n]);
        }while(n>-2);
    }
    return 0;
}

Sheesh, why have so many "char" keywords? :-p You can also make a-f into char pointers instead of char arrays.
Spoiler:

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char
   * w[] = {"","Do", "Over", "After", "Faster", "Hour", "Stronger", "Makes",
        "Is", "Never", "Harder", "It", "Us", "Better", "Make", "Gonna", "Work", "Ever", "Than", "More","Our"},
        *a ="pk`nk`ak`gl`j`m`d`f.",
        *b ="sr`e`t`i`q`c`ph`b.",
        *c="pkj`nkm`akd`glf.",
        *d="srq`ec`tph`ib.",
        *e ="pkjnk`akdgl`srqe`tph.",
        *f="pkj`akd`srq`tphib.",
        * s[] = {a,b,a,c,d,c,d,c,d,c,d,c,d,c,d,e,e,c,d,e,e,c,d,f,c,d};
    for(int i=0;i<26;i++){
        int n,j = 0;
        do{
            n=s[i][j++]-96;
            printf(n>0?"%s ":"\n",w[n]);
        }while(n>-2);
    }
    return 0;
}

Getting rid of the chars removes 28 non-whitespace characters, and changing arrays to ptrs removes 6 more.

OK, let's see if we can get rid of all those commas in "s". Here's one step in the transformation (adds 19 characters to define p, adds 6 characters to use p on line 18, removes one character changing [] to * for s, removes 25 commas; net gain: 1 character):
Spoiler:

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char
      * w[] = {"","Do", "Over", "After", "Faster", "Hour", "Stronger", "Makes",
        "Is", "Never", "Harder", "It", "Us", "Better", "Make", "Gonna", "Work", "Ever", "Than", "More","Our"},
      *a ="pk`nk`ak`gl`j`m`d`f.",
      *b ="sr`e`t`i`q`c`ph`b.",
        *c="pkj`nkm`akd`glf.",
        *d="srq`ec`tph`ib.",
        *e ="pkjnk`akdgl`srqe`tph.",
        *f="pkj`akd`srq`tphib.",
      *p[] = {a, b, c, d, e, f },
        *s = "abacdcdcdcdcdcdeecdeecdfcd";
    for(int i=0;i<26;i++){
        int n,j = 0;
        do{
            n=p[s[i]-97][j++]-96;
            printf(n>0?"%s ":"\n",w[n]);
        }while(n>-2);
    }
    return 0;
}


But now we can get rid of the explicit definition of p as well as a through f:

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char
        * w[] = {"","Do", "Over", "After", "Faster", "Hour", "Stronger", "Makes",
                "Is", "Never", "Harder", "It", "Us", "Better", "Make", "Gonna", "Work", "Ever", "Than", "More","Our"},
        *p[] = { "pk`nk`ak`gl`j`m`d`f.",
                 "sr`e`t`i`q`c`ph`b.",
                 "pkj`nkm`akd`glf.",
                 "srq`ec`tph`ib.",
                 "pkjnk`akdgl`srqe`tph.",
                 "pkj`akd`srq`tphib." },
        *s = "abacdcdcdcdcdcdeecdeecdfcd";
    for(int i=0;i<26;i++){
        int n,j = 0;
        do{
            n=p[s[i]-97][j++]-96;
            printf(n>0?"%s ":"\n",w[n]);
        }while(n>-2);
    }
    return 0;
}

That saves, if I did it right, 30 more characters.

Net savings: 65 non-whitespace characters. 19 more would come if I removed argv & argc.

Edit again: Not sure if I'm making it eventually better, or not. :-)
Spoiler:
I'm trying to combine the words into one big character array to avoid the need to keep opening and closing strings and put commas there. Intermediate steps. Make one big char array, and address using offsets. To stay within the base ASCII character set, I have to double the "index" which means I have to insert padding on even-length strings (odd-length with the terminating null). Here it is with my big translation comment, and sorry for the bad-form tabs:

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char
        *w =
         "\0 "         // `  2   0    0   32  space 
         "Do\0 "         // a  4   2    1   33  !
         "Over\0 "      // b  6   6    3   35  #
         "After\0"      // c  6   12   6   38  &
         "Faster\0 "      // d  8   18   9   41  )
         "Hour\0 "      // e  6   26   13  45  -
         "Stronger\0 "   // f  10  32   16  48  0
         "Makes\0"      // g  6   42   21  53  5
            "Is\0 "         // h  4   48   24  56  8
         "Never\0"      // i  6   52   26  58  :
         "Harder\0 "      // j  8   58   29  61  =
         "It\0 "         // k  4   66   33  65  A
         "Us\0 "         // l  4   70   35  67  C
         "Better\0 "      // m  8   78   39  71  G
         "Make\0 "      // n  6   82   41  73  I
         "Gonna\0"      // o  6   88   44  76  L
         "Work\0 "      // p  6   94   47  79  O
         "Ever\0 "      // q  6   100  50  82  R
         "Than\0 "      // r  6   106  53  85  U
         "More\0 "      // s  6   112  56  88  X
         "Our\0",      // t  4   118  59  91  [
        *p[] = { "OA IA !A 5C = E ) 0.",
             "XU - [ : R & O8 #.",
                 "OA= IAE !A) 5C0.",
             "XUR -& [O8 :#.",
                 "OA=IA !A)5C XUR- [O8.",
             "OA= !A) XUR [O8:#." },
        *s = "abacdcdcdcdcdcdeecdeecdfcd";
         int i;
    for( i=0;i<26;i++){
        int n,j = 0;
        do{
            n=p[s[i]-97][j++]-32;
            printf(n!=14 && n!=0?"%s ":"\n",w+n*2);
        }while(n!=14);
    }
    return 0;
}


But I want to be able to spell \0 with one character, so I'll do a transformation:

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char
        w[] =
         "  "         // `  2   0    0   32  space 
         "dO  "         // a  4   2    1   33  !
         "oVER  "      // b  6   6    3   35  #
         "aFTER "      // c  6   12   6   38  &
         "fASTER  "      // d  8   18   9   41  )
         "hOUR  "      // e  6   26   13  45  -
         "sTRONGER  "   // f  10  32   16  48  0
         "mAKES "      // g  6   42   21  53  5
            "iS  "         // h  4   48   24  56  8
         "nEVER "      // i  6   52   26  58  :
         "hARDER  "      // j  8   58   29  61  =
         "iT  "         // k  4   66   33  65  A
         "uS  "         // l  4   70   35  67  C
         "bETTER  "      // m  8   78   39  71  G
         "mAKE  "      // n  6   82   41  73  I
         "gONNA "      // o  6   88   44  76  L
         "wORK  "      // p  6   94   47  79  O
         "eVER  "      // q  6   100  50  82  R
         "tHAN  "      // r  6   106  53  85  U
         "mORE  "      // s  6   112  56  88  X
         "oUR ",          // t  4   118  59  91  [
        *p[] = { "OA IA !A 5C = E ) 0.",
             "XU - [ : R & O8 #.",
                 "OA= IAE !A) 5C0.",
             "XUR -& [O8 :#.",
                 "OA=IA !A)5C XUR- [O8.",
             "OA= !A) XUR [O8:#." },
        *s = "abacdcdcdcdcdcdeecdeecdfcd";
   int i;
   for(i=0;i<122;++i) {
      w[i] ^= 32;
   }
    for( i=0;i<26;i++){
        int n,j = 0;
        do{
            n=p[s[i]-97][j++]-32;
            printf(n!=14 && n!=0?"%s ":"\n",w+n*2);
        }while(n!=14);
    }
    return 0;
}


Then, so I can remove the first string, I will just re-use a null that's elsewhere:

Code: Select all

        *p[] = { "OA%IA%!A%5C%=%E%)%0.",
             "XU%-%[%:%R%&%O8%#.",
                 "OA=%IAE%!A)%5C0.",
             "XUR%-&%[O8%:#.",
                 "OA=IA%!A)5C%XUR-%[O8.",
             "OA=%!A)%XUR%[O8:#." },
along with changing n!=0 elsewhere to n!=5

Then this drops the first string, which will save a couple characters (or would if I didn't now have " in my program :-); I may have screwed up the encoding but I'm too lazy to fix it)

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char
        w[] =
         "dO  "         // a  4   2    1   33   
         "oVER  "      // b  6   6    3   35  \"
         "aFTER "      // c  6   12   6   38  %
         "fASTER  "      // d  8   18   9   41  (
         "hOUR  "      // e  6   26   13  45  ,
         "sTRONGER  "   // f  10  32   16  48  0
         "mAKES "      // g  6   42   21  53  /
            "iS  "         // h  4   48   24  56  7
         "nEVER "      // i  6   52   26  58  9
         "hARDER  "      // j  8   58   29  61  <
         "iT  "         // k  4   66   33  65  @
         "uS  "         // l  4   70   35  67  B
         "bETTER  "      // m  8   78   39  71  F
         "mAKE  "      // n  6   82   41  73  H
         "gONNA "      // o  6   88   44  76  K
         "wORK  "      // p  6   94   47  79  N
         "eVER  "      // q  6   100  50  82  Q
         "tHAN  "      // r  6   106  53  85  T
         "mORE  "      // s  6   112  56  88  W
         "oUR ",          // t  4   118  59  91  \\ .
        *p[] = { "N@$H@$ @$4B$<$D$($/}",
             "WT$,$Z$9$Q$%$N7$\"}",
                 "N@<$H@D$ @($4B/}",
             "WTQ$,%$ZN7$9\"}",
                 "N@<H@$@(4B$WTQ,$ZN7}",
             "N@<$@($WTQ$ZN79\"}" },
        *s = "abacdcdcdcdcdcdeecdeecdfcd";
   int i;
   for(i=0;i<120;++i) {
      w[i] ^= 32;
   }
    for( i=0;i<26;i++){
        int n,j = 0;
        do{
            n=p[s[i]-97][j++]-32;
            printf(n!=4&&n!=93?"%s ":"\n",w+n*2);
        }while(n!=93);
    }
    return 0;
}


Code: Select all

#include <stdio.h>
int main()
{
    char
        w[] = "oVER  dO  aFTER fASTER  hOUR  sTRONGER  mAKES iS  nEVER hARDER  iT  uS  bETTER  mAKE  gONNA wORK  eVER  tHAN  mORE  oUR ",
      *p[] = { "N@$H@$#@$4B$<$D$($/}",
             "WT$,$Z$9$Q$%$N7$ }",
             "N@<$H@D$#@($4B/}",
             "WTQ$,%$ZN7$9 }",
                 "N@<H@$@(4B$WTQ,$ZN7}",
             "N@<$@($WTQ$ZN79 }" },
        *s = "abacdcdcdcdcdcdeecdeecdfcd",
      i;
   for(i=0;i<120;++i) w[i] ^= 32;
    for( i=0;i<26;i++){
        int n,j = 0;
        do{
            n=p[s[i]-97][j++]-32;
            printf(n!=4&&n!=93?"%s ":"\n",w+n*2);
        }while(n!=93);
    }
    return 0;
}

422 non-whitespace characters, though I may have deleted a couple words accidentally. That would add a couple back in. Also, 34 whitespace characters in the string are semantically significant. So really it's like ~460. Should be possible to save ~15 more by combining the p array into one string and referencing it with offsets, using the same trick as above.

User avatar
Xenomortis
Not actually a special flower.
Posts: 1448
Joined: Thu Oct 11, 2012 8:47 am UTC

Re: Daft Punk - experiment in efficiency

Postby Xenomortis » Fri Apr 12, 2013 8:11 am UTC

Oh, the word "Gonna" is not actually used in my program.
I noticed when I was doing the find-replace on the numbers in my original int array, but couldn't be bothered to remove it (since it was only 6 characters and I was looking for bigger savings).
:lol:

Of course, my program doesn't conform to the "spec" provided, but then neither did the OP's.
Image

troyp
Posts: 557
Joined: Thu May 22, 2008 9:20 pm UTC
Location: Lismore, NSW

Re: Daft Punk - experiment in efficiency

Postby troyp » Fri Apr 12, 2013 12:30 pm UTC

How long would a golfed Huffman decoder in C be? Can you just map substrings to ints/chars (as people are doing), then frequency encode the whole text at coding time, then have the program decode it?

You could represent a binary tree as a string to save room. Most chars would index the array of substrings, but one would be used as a prefix (or postfix) cons operation.
Spoiler:
So one possible tree for "abracadabra" where the substrings are individual letters would be (symbolically) "*a**br*cd" which represents the tree (a.((b.r).(c.d))).
Here the letters would actually be represented by character indices into an array of chars/substrings (in this case the indices could be the letters themselves, I guess, except that would mean a space-wasting sparse array) and the * would be some char index that is set aside to represent a cons operation on the next two subtrees (chars or conses).

Apart from the encoded string, the array and the huffman-tree-string, you'd need a decoding function and the main routine to loop through the encoded string and decode it. The decoding function should be quite simple. Traversing the tree would just start at the initial * and then take one step for left and two steps for right, with the proviso that when you pass a * you have to take an extra two steps to account for its operands.

So how concisely could that be done in C? I don't have much golfing experience, let alone in C, but it looks to me like that might work out shorter (just based on golfed C snippets I've seen).

Divinas
Posts: 57
Joined: Wed Aug 26, 2009 7:04 am UTC

Re: Daft Punk - experiment in efficiency

Postby Divinas » Fri Apr 12, 2013 12:44 pm UTC

What troyp is mentioning is exactly what my idea was. However so far I'm unable to make it concise enough for it to be better than the other solutions. I'm experimenting with some macro magic, which might be fruitful and make it work.. maybe.
I think we really should agree if we'll just print out the whole text, or do as the OP and insert system("cls") and getch() at the proper times.

User avatar
Xenomortis
Not actually a special flower.
Posts: 1448
Joined: Thu Oct 11, 2012 8:47 am UTC

Re: Daft Punk - experiment in efficiency

Postby Xenomortis » Fri Apr 12, 2013 12:54 pm UTC

I vote for the omission of getch() and system("cls"); it makes testing and verifying the end result a real pain.
(which is why I didn't include it in my versions)
Image

User avatar
PM 2Ring
Posts: 3713
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Daft Punk - experiment in efficiency

Postby PM 2Ring » Sat Apr 13, 2013 8:06 am UTC

Xenomortis wrote:I vote for the omission of getch() and system("cls"); it makes testing and verifying the end result a real pain.
(which is why I didn't include it in my versions)


Agreed. And it'd be nice if we could avoid those non-standard constructions...

But the OP wants the program to pause and do screen clearing. How about a compromise: print a line containing the string "<Pause>" or "<Clear screen>" (or maybe something a little more compact) at the appropriate points?

noy2222
Posts: 4
Joined: Wed Apr 10, 2013 6:18 pm UTC

Re: Daft Punk - experiment in efficiency

Postby noy2222 » Sat Apr 13, 2013 11:13 am UTC

I feel that the challenge needs proper crotches, the ultimate goal is to follow the song as oppose to just print the lyrics.
You would need to print the lyrics line by line with the correct capitalisation (since there are no proper nouns, just at the beginning of every sentence), pause after every line and clear the screen at the end of each of the first 15 sections (excluding the last one, of course. Each section starts with a "work it").
For the purposes of testing, feel free to simply printf("<pause>/n"); and printf("<clearscreen>\n"); each would be count for 8 and 14 characters (respectively).
Make sure to include conio.h and stdlib.h even if you're not using them.
The lyrics for quick reference:

Spoiler:
<1>
Work it
Make it
Do it
Makes us
Harder
Better
Faster
Stronger
More than
Hour
Our
Never
Ever
After
Work is
Over
<2>
Work it
Make it
Do it
Makes us
Harder
Better
Faster
Stronger
<3>
Work it harder
Make it better
Do it faster
Makes us stronger
More than ever
Hour after
Our work is
Never over
<4>
Work it harder
Make it better
Do it faster
Makes us stronger
More than ever
Hour after
Our work is
Never over
<5>
Work it harder
Make it better
Do it faster
Makes us stronger
More than ever
Hour after
Our work is
Never over
<6>
Work it harder
Make it better
Do it faster
Makes us stronger
More than ever
Hour after
Our work is
Never over
<7>
Work it harder
Make it better
Do it faster
Makes us stronger
More than ever
Hour after
Our work is
Never over
<8>
Work it harder
Make it
Do it faster
Makes us
More than ever
Hour after
Our work is
Never over
<9>
Work it harder
Make it better
Do it faster
Makes us stronger
More than ever
Hour after
Our work is
Never over
<10>
Work it harder
Make it
Do it faster
Makes us
More than ever
Hour after
Our work is
Never over
<11>
Work it harder
Make it
Just do it faster
Makes us stronger
Than ever
Hour after
Our work is
Never over
<12>
Work it
Make it better
Do it faster
Makes us stronger
More than ever
Hour after
Our work is
Never over
<13>
Work it harder
Make it
Just do it faster
Makes us stronger
Than ever
Hour after
Our work is
Never over
<14>
Work it harder
Make it better
Do it faster
Makes us stronger
More than ever
Hour after
Our work is
Never over
<15>
Work it harder
Do it faster
More than ever
Our work is
Never over
<16>
Work it harder
Make it better
Do it faster
Makes us stronger
More than ever
Hour after
Our work is
Never over


Fantastic work so far guys.

User avatar
PM 2Ring
Posts: 3713
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Daft Punk - experiment in efficiency

Postby PM 2Ring » Sun Apr 14, 2013 7:16 am UTC

noy2222 wrote:Make sure to include conio.h and stdlib.h even if you're not using them.

Um, some of us don't have conio.h on our systems. And not all headers named conio.h contain getch().
Also, many of us don't have a standard command called cls, either, so system("cls"); doesn't work for us.

BTW, if you declare main() to return an int (as you should), you really ought to have an explicit return statement somewhere... Windows may let you get away with that sort of thing, but it's not exactly standard C. :)

Derek
Posts: 2181
Joined: Wed Aug 18, 2010 4:15 am UTC

Re: Daft Punk - experiment in efficiency

Postby Derek » Sat Apr 20, 2013 9:13 pm UTC

EvanED wrote:I don't suppose you'll let me cheat and output EVERYTHING IN CAPITAL LETTERS, huh? Edit Oh I just thought of a different way to get what I want. I'll work toward that maybe.

Xenomortis wrote:

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char* w[] = {"","Do", "Over", "After", "Faster", "Hour", "Stronger", "Makes",
        "Is", "Never", "Harder", "It", "Us", "Better", "Make", "Gonna", "Work", "Ever", "Than", "More","Our"};
    char a[] ="pk`nk`ak`gl`j`m`d`f.";
    char b[] ="sr`e`t`i`q`c`ph`b.";
    char c[]="pkj`nkm`akd`glf.";
    char d[]="srq`ec`tph`ib.";
    char e[] ="pkjnk`akdgl`srqe`tph.";
    char f[]="pkj`akd`srq`tphib.";
    char* s[] = {a,b,a,c,d,c,d,c,d,c,d,c,d,c,d,e,e,c,d,e,e,c,d,f,c,d};
    for(int i=0;i<26;i++){
        int n,j = 0;
        do{
            n=s[i][j++]-96;
            printf(n>0?"%s ":"\n",w[n]);
        }while(n>-2);
    }
    return 0;
}

Sheesh, why have so many "char" keywords? :-p You can also make a-f into char pointers instead of char arrays.
Spoiler:

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char
   * w[] = {"","Do", "Over", "After", "Faster", "Hour", "Stronger", "Makes",
        "Is", "Never", "Harder", "It", "Us", "Better", "Make", "Gonna", "Work", "Ever", "Than", "More","Our"},
        *a ="pk`nk`ak`gl`j`m`d`f.",
        *b ="sr`e`t`i`q`c`ph`b.",
        *c="pkj`nkm`akd`glf.",
        *d="srq`ec`tph`ib.",
        *e ="pkjnk`akdgl`srqe`tph.",
        *f="pkj`akd`srq`tphib.",
        * s[] = {a,b,a,c,d,c,d,c,d,c,d,c,d,c,d,e,e,c,d,e,e,c,d,f,c,d};
    for(int i=0;i<26;i++){
        int n,j = 0;
        do{
            n=s[i][j++]-96;
            printf(n>0?"%s ":"\n",w[n]);
        }while(n>-2);
    }
    return 0;
}

Getting rid of the chars removes 28 non-whitespace characters, and changing arrays to ptrs removes 6 more.

OK, let's see if we can get rid of all those commas in "s". Here's one step in the transformation (adds 19 characters to define p, adds 6 characters to use p on line 18, removes one character changing [] to * for s, removes 25 commas; net gain: 1 character):
Spoiler:

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char
      * w[] = {"","Do", "Over", "After", "Faster", "Hour", "Stronger", "Makes",
        "Is", "Never", "Harder", "It", "Us", "Better", "Make", "Gonna", "Work", "Ever", "Than", "More","Our"},
      *a ="pk`nk`ak`gl`j`m`d`f.",
      *b ="sr`e`t`i`q`c`ph`b.",
        *c="pkj`nkm`akd`glf.",
        *d="srq`ec`tph`ib.",
        *e ="pkjnk`akdgl`srqe`tph.",
        *f="pkj`akd`srq`tphib.",
      *p[] = {a, b, c, d, e, f },
        *s = "abacdcdcdcdcdcdeecdeecdfcd";
    for(int i=0;i<26;i++){
        int n,j = 0;
        do{
            n=p[s[i]-97][j++]-96;
            printf(n>0?"%s ":"\n",w[n]);
        }while(n>-2);
    }
    return 0;
}


But now we can get rid of the explicit definition of p as well as a through f:

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char
        * w[] = {"","Do", "Over", "After", "Faster", "Hour", "Stronger", "Makes",
                "Is", "Never", "Harder", "It", "Us", "Better", "Make", "Gonna", "Work", "Ever", "Than", "More","Our"},
        *p[] = { "pk`nk`ak`gl`j`m`d`f.",
                 "sr`e`t`i`q`c`ph`b.",
                 "pkj`nkm`akd`glf.",
                 "srq`ec`tph`ib.",
                 "pkjnk`akdgl`srqe`tph.",
                 "pkj`akd`srq`tphib." },
        *s = "abacdcdcdcdcdcdeecdeecdfcd";
    for(int i=0;i<26;i++){
        int n,j = 0;
        do{
            n=p[s[i]-97][j++]-96;
            printf(n>0?"%s ":"\n",w[n]);
        }while(n>-2);
    }
    return 0;
}

That saves, if I did it right, 30 more characters.

Net savings: 65 non-whitespace characters. 19 more would come if I removed argv & argc.

Edit again: Not sure if I'm making it eventually better, or not. :-)
Spoiler:
I'm trying to combine the words into one big character array to avoid the need to keep opening and closing strings and put commas there. Intermediate steps. Make one big char array, and address using offsets. To stay within the base ASCII character set, I have to double the "index" which means I have to insert padding on even-length strings (odd-length with the terminating null). Here it is with my big translation comment, and sorry for the bad-form tabs:

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char
        *w =
         "\0 "         // `  2   0    0   32  space 
         "Do\0 "         // a  4   2    1   33  !
         "Over\0 "      // b  6   6    3   35  #
         "After\0"      // c  6   12   6   38  &
         "Faster\0 "      // d  8   18   9   41  )
         "Hour\0 "      // e  6   26   13  45  -
         "Stronger\0 "   // f  10  32   16  48  0
         "Makes\0"      // g  6   42   21  53  5
            "Is\0 "         // h  4   48   24  56  8
         "Never\0"      // i  6   52   26  58  :
         "Harder\0 "      // j  8   58   29  61  =
         "It\0 "         // k  4   66   33  65  A
         "Us\0 "         // l  4   70   35  67  C
         "Better\0 "      // m  8   78   39  71  G
         "Make\0 "      // n  6   82   41  73  I
         "Gonna\0"      // o  6   88   44  76  L
         "Work\0 "      // p  6   94   47  79  O
         "Ever\0 "      // q  6   100  50  82  R
         "Than\0 "      // r  6   106  53  85  U
         "More\0 "      // s  6   112  56  88  X
         "Our\0",      // t  4   118  59  91  [
        *p[] = { "OA IA !A 5C = E ) 0.",
             "XU - [ : R & O8 #.",
                 "OA= IAE !A) 5C0.",
             "XUR -& [O8 :#.",
                 "OA=IA !A)5C XUR- [O8.",
             "OA= !A) XUR [O8:#." },
        *s = "abacdcdcdcdcdcdeecdeecdfcd";
         int i;
    for( i=0;i<26;i++){
        int n,j = 0;
        do{
            n=p[s[i]-97][j++]-32;
            printf(n!=14 && n!=0?"%s ":"\n",w+n*2);
        }while(n!=14);
    }
    return 0;
}


But I want to be able to spell \0 with one character, so I'll do a transformation:

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char
        w[] =
         "  "         // `  2   0    0   32  space 
         "dO  "         // a  4   2    1   33  !
         "oVER  "      // b  6   6    3   35  #
         "aFTER "      // c  6   12   6   38  &
         "fASTER  "      // d  8   18   9   41  )
         "hOUR  "      // e  6   26   13  45  -
         "sTRONGER  "   // f  10  32   16  48  0
         "mAKES "      // g  6   42   21  53  5
            "iS  "         // h  4   48   24  56  8
         "nEVER "      // i  6   52   26  58  :
         "hARDER  "      // j  8   58   29  61  =
         "iT  "         // k  4   66   33  65  A
         "uS  "         // l  4   70   35  67  C
         "bETTER  "      // m  8   78   39  71  G
         "mAKE  "      // n  6   82   41  73  I
         "gONNA "      // o  6   88   44  76  L
         "wORK  "      // p  6   94   47  79  O
         "eVER  "      // q  6   100  50  82  R
         "tHAN  "      // r  6   106  53  85  U
         "mORE  "      // s  6   112  56  88  X
         "oUR ",          // t  4   118  59  91  [
        *p[] = { "OA IA !A 5C = E ) 0.",
             "XU - [ : R & O8 #.",
                 "OA= IAE !A) 5C0.",
             "XUR -& [O8 :#.",
                 "OA=IA !A)5C XUR- [O8.",
             "OA= !A) XUR [O8:#." },
        *s = "abacdcdcdcdcdcdeecdeecdfcd";
   int i;
   for(i=0;i<122;++i) {
      w[i] ^= 32;
   }
    for( i=0;i<26;i++){
        int n,j = 0;
        do{
            n=p[s[i]-97][j++]-32;
            printf(n!=14 && n!=0?"%s ":"\n",w+n*2);
        }while(n!=14);
    }
    return 0;
}


Then, so I can remove the first string, I will just re-use a null that's elsewhere:

Code: Select all

        *p[] = { "OA%IA%!A%5C%=%E%)%0.",
             "XU%-%[%:%R%&%O8%#.",
                 "OA=%IAE%!A)%5C0.",
             "XUR%-&%[O8%:#.",
                 "OA=IA%!A)5C%XUR-%[O8.",
             "OA=%!A)%XUR%[O8:#." },
along with changing n!=0 elsewhere to n!=5

Then this drops the first string, which will save a couple characters (or would if I didn't now have " in my program :-); I may have screwed up the encoding but I'm too lazy to fix it)

Code: Select all

#include <stdio.h>
int main(int argc, char* argv[])
{
    char
        w[] =
         "dO  "         // a  4   2    1   33   
         "oVER  "      // b  6   6    3   35  \"
         "aFTER "      // c  6   12   6   38  %
         "fASTER  "      // d  8   18   9   41  (
         "hOUR  "      // e  6   26   13  45  ,
         "sTRONGER  "   // f  10  32   16  48  0
         "mAKES "      // g  6   42   21  53  /
            "iS  "         // h  4   48   24  56  7
         "nEVER "      // i  6   52   26  58  9
         "hARDER  "      // j  8   58   29  61  <
         "iT  "         // k  4   66   33  65  @
         "uS  "         // l  4   70   35  67  B
         "bETTER  "      // m  8   78   39  71  F
         "mAKE  "      // n  6   82   41  73  H
         "gONNA "      // o  6   88   44  76  K
         "wORK  "      // p  6   94   47  79  N
         "eVER  "      // q  6   100  50  82  Q
         "tHAN  "      // r  6   106  53  85  T
         "mORE  "      // s  6   112  56  88  W
         "oUR ",          // t  4   118  59  91  \\ .
        *p[] = { "N@$H@$ @$4B$<$D$($/}",
             "WT$,$Z$9$Q$%$N7$\"}",
                 "N@<$H@D$ @($4B/}",
             "WTQ$,%$ZN7$9\"}",
                 "N@<H@$@(4B$WTQ,$ZN7}",
             "N@<$@($WTQ$ZN79\"}" },
        *s = "abacdcdcdcdcdcdeecdeecdfcd";
   int i;
   for(i=0;i<120;++i) {
      w[i] ^= 32;
   }
    for( i=0;i<26;i++){
        int n,j = 0;
        do{
            n=p[s[i]-97][j++]-32;
            printf(n!=4&&n!=93?"%s ":"\n",w+n*2);
        }while(n!=93);
    }
    return 0;
}


Code: Select all

#include <stdio.h>
int main()
{
    char
        w[] = "oVER  dO  aFTER fASTER  hOUR  sTRONGER  mAKES iS  nEVER hARDER  iT  uS  bETTER  mAKE  gONNA wORK  eVER  tHAN  mORE  oUR ",
      *p[] = { "N@$H@$#@$4B$<$D$($/}",
             "WT$,$Z$9$Q$%$N7$ }",
             "N@<$H@D$#@($4B/}",
             "WTQ$,%$ZN7$9 }",
                 "N@<H@$@(4B$WTQ,$ZN7}",
             "N@<$@($WTQ$ZN79 }" },
        *s = "abacdcdcdcdcdcdeecdeecdfcd",
      i;
   for(i=0;i<120;++i) w[i] ^= 32;
    for( i=0;i<26;i++){
        int n,j = 0;
        do{
            n=p[s[i]-97][j++]-32;
            printf(n!=4&&n!=93?"%s ":"\n",w+n*2);
        }while(n!=93);
    }
    return 0;
}

422 non-whitespace characters, though I may have deleted a couple words accidentally. That would add a couple back in. Also, 34 whitespace characters in the string are semantically significant. So really it's like ~460. Should be possible to save ~15 more by combining the p array into one string and referencing it with offsets, using the same trick as above.

This did not produce the correct output for me (with GCC on MinGW). I tried to annotate all the errors, but there were too many towards the end (some verses were just totally wrong) and the lyrics at the end are almost unintelligible anyways, so I would just assume that Noy2222's lyrics are correct and work with that.

Also, "gonna" never appears in the song, so you can cut that out of the string. And some minor nitpicks: Your version capitalizes the first letter of every word, and prints a space at the end of every line.

Lastly, why does your words string have inverse capitalization? Can't you just use normal capitalization to store the words? I'm just asking because I'm wondering if I've missed some trick.

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Daft Punk - experiment in efficiency

Postby EvanED » Sat Apr 20, 2013 9:30 pm UTC

Derek wrote:This did not produce the correct output for me (with GCC on MinGW). I tried to annotate all the errors, but there were too many towards the end (some verses were just totally wrong) and the lyrics at the end are almost unintelligible anyways, so I would just assume that Noy2222's lyrics are correct and work with that.
I probably messed up the translation of the "program" in the p variable; a couple of the steps I did by hand. I was too lazy to fix it, but it should definitely be possible.

Also, "gonna" never appears in the song, so you can cut that out of the string. And some minor nitpicks: Your version capitalizes the first letter of every word, and prints a space at the end of every line.
Mine is based off of Xenomortis's which does the same thing.

Lastly, why does your words string have inverse capitalization? Can't you just use normal capitalization to store the words? I'm just asking because I'm wondering if I've missed some trick.
Yep, you did. :-) Basically I wanted a way to avoid saying {"", "Do", "Over", ...} because there are too many quotation marks and commas in there. So I put everything into one string. However, each word still needs to be null-terminated so the output stops at the right place. So what I did was separate the words by spaces, and invert the 5th bit (corresponding to 25) which changes a space into NUL. That takes fewer characters than explicitly checking if a character is a space and replacing it with '\0' if not, but it has the side effect of (assuming an ASCII-like encoding) flipping the case of letters.

User avatar
Xenomortis
Not actually a special flower.
Posts: 1448
Joined: Thu Oct 11, 2012 8:47 am UTC

Re: Daft Punk - experiment in efficiency

Postby Xenomortis » Sat Apr 20, 2013 9:51 pm UTC

Derek wrote:This did not produce the correct output for me (with GCC on MinGW). I tried to annotate all the errors, but there were too many towards the end (some verses were just totally wrong) and the lyrics at the end are almost unintelligible anyways, so I would just assume that Noy2222's lyrics are correct and work with that.

Also, "gonna" never appears in the song, so you can cut that out of the string. And some minor nitpicks: Your version capitalizes the first letter of every word, and prints a space at the end of every line.

Lastly, why does your words string have inverse capitalization? Can't you just use normal capitalization to store the words? I'm just asking because I'm wondering if I've missed some trick.


When I wrote my version, I didn't have an "official" spec on the lyrics (I couldn't be bothered to parse the output of the OP's version), so I just used the lyrics I found on some website, which evidently differed from what was used by others; hence the inclusion of the word "gonna" which doesn't ever get used.

I may go through and rewrite, but I don't think the differences will add up to much.
Image

Derek
Posts: 2181
Joined: Wed Aug 18, 2010 4:15 am UTC

Re: Daft Punk - experiment in efficiency

Postby Derek » Sun Apr 21, 2013 2:56 am UTC

EvanED wrote:Yep, you did. :-) Basically I wanted a way to avoid saying {"", "Do", "Over", ...} because there are too many quotation marks and commas in there. So I put everything into one string. However, each word still needs to be null-terminated so the output stops at the right place. So what I did was separate the words by spaces, and invert the 5th bit (corresponding to 25) which changes a space into NUL. That takes fewer characters than explicitly checking if a character is a space and replacing it with '\0' if not, but it has the side effect of (assuming an ASCII-like encoding) flipping the case of letters.

I knew you were using the spaces to represent null, but I didn't realize that it had the side effect of exactly inverting capitalization. That's interesting.

User avatar
tastelikecoke
Posts: 1208
Joined: Mon Feb 01, 2010 7:58 am UTC
Location: Antipode of Brazil
Contact:

Re: Daft Punk - experiment in efficiency

Postby tastelikecoke » Sun Apr 21, 2013 5:24 am UTC

I tried to amp out Divinas's code.

Code: Select all

#include <stdio.h>
#include <conio.h>
int main(){
   char* w[] = {"", "", "Do", "Over", "After", "Faster", "Hour", "Stronger", "Makes", "Is", "Never", "Harder", "It", "Us", "Better", "Make", "Gonna", "Work", "Ever", "Than", "More"};
   char* l = "ZRMBPMBCMBINBLBOBFBHBAUTBGBGBKBSBEBRJBDBARMBPMBCMBINBLBOBFBHBARMLBPMOBCMFBINHBAUTSBGEGBRJKDBARMLBPMOBCMFBINHBAUTSBGEGBRJKDBARMLPMOBCMFINHBUTSGEGBRJKDBARMLPMOBCMFINHBUTSGEGBRJKDBARMLPMOBCMFINHBUTSGEGBRJKDBARMLPMOBCMFINHBUTSGEGBRJKDBARMLPMOBCMFINHBUTSGEGBRJKDBAQRMLPMBQCMFINBUTSGEGBRJKDBARMLPMOBCMFINHBUTSGEGBRJKDBARMLPMOBCMFINHBUTSGEGBRJKDBARMLPMOBCMFINHBUTSGEGBRJKDBARMLBCMFBUTSGBRJKDBARMLPMOBCMFINHBUTSGEGBRJKD";
   for(;*l!=0;l++){
      if(*l>64) printf("%s\n",w[*l-65]);
      if(*l<66) system("cls");
      if(*l>65)getch();
   }
}

Cool, my solution kind of converged to Ben-oni's optimization :D

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: Daft Punk - experiment in efficiency

Postby TheChewanater » Mon Apr 22, 2013 9:16 pm UTC

Python version.
EDIT: Got it down to 348 characters.

Code: Select all

print(' '.join([['Work it','harder','Make it','better','Do it','faster','Makes us','stronger','More than','ever','Hour','after','Our','work is','Never','over'][eval('0x'+c)]for c in'024613578acf9bdf024613570123456789abcdffgggg01245689abcdefg01245689abcdef012456789abcdef023456789abcdef012456789abcdefg014589cdffg'.replace('g','0123456789abcdef')])) 
Last edited by TheChewanater on Tue Apr 23, 2013 2:29 am UTC, edited 9 times in total.
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

flownt
Posts: 70
Joined: Sat Feb 09, 2013 5:24 pm UTC

Re: Daft Punk - experiment in efficiency

Postby flownt » Mon Apr 22, 2013 9:45 pm UTC

PM 2Ring wrote:
noy2222 wrote:Make sure to include conio.h and stdlib.h even if you're not using them.

--
BTW, if you declare main() to return an int (as you should), you really ought to have an explicit return statement somewhere... Windows may let you get away with that sort of thing, but it's not exactly standard C. :)


Actually... it is.

Wikipedia wrote:In case a return value is not defined by the programmer, an implicit return 0; at the end of the main() function is inserted by the compiler; this behavior is required by the C++ standard.

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Daft Punk - experiment in efficiency

Postby EvanED » Mon Apr 22, 2013 9:53 pm UTC

flownt wrote:
Wikipedia wrote:In case a return value is not defined by the programmer, an implicit return 0; at the end of the main() function is inserted by the compiler; this behavior is required by the C++ standard.
So originally I was going to reply saying that's only true of C++, and that C does not have that implicit return at the end of main (and thus omitting an explicit return/exit will provoke undefined behavior). And this was true of C89. However, I'm apparently wrong about C99, which aligns with C++ on this issue:
C99 draft standard 5.1.2.2.3(1) wrote:If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0.
(emphasis mine)

User avatar
PM 2Ring
Posts: 3713
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Daft Punk - experiment in efficiency

Postby PM 2Ring » Tue Apr 23, 2013 2:15 am UTC

EvanED wrote:
C99 draft standard 5.1.2.2.3(1) wrote:If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0.
(emphasis mine)

I see. Thanks, guys. And apologies to noy2222.

But I won't be using this feature in my own C code. :)

User avatar
phlip
Restorer of Worlds
Posts: 7572
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Daft Punk - experiment in efficiency

Postby phlip » Tue Apr 23, 2013 3:32 am UTC

TheChewanater wrote:Python version.
EDIT: Got it down to 348 characters.

Code: Select all

print(' '.join([['Work it','harder','Make it','better','Do it','faster','Makes us','stronger','More than','ever','Hour','after','Our','work is','Never','over'][eval('0x'+c)]for c in'024613578acf9bdf024613570123456789abcdffgggg01245689abcdefg01245689abcdef012456789abcdef023456789abcdef012456789abcdefg014589cdffg'.replace('g','0123456789abcdef')])) 

Some thoughts on this:
Don't need the outermost square brackets - str.join(a for b in c) is the same as str.join([a for b in c]), and two chars shorter
int(c,16) is shorter than eval('0x'+c)
The list of words could be built shorter by "Work it,harder,Make it,etc".split(',')
I'm pretty sure the lyrics are wrong... near the start, there's a couple of places you have an 'f' when I believe you should have an 'e'... which would make there be an additional '0123456789abcdef' that you could replace with a 'g'.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: Daft Punk - experiment in efficiency

Postby TheChewanater » Tue Apr 23, 2013 7:44 pm UTC

phlip wrote:Some thoughts on this:
Don't need the outermost square brackets - str.join(a for b in c) is the same as str.join([a for b in c]), and two chars shorter
int(c,16) is shorter than eval('0x'+c)
The list of words could be built shorter by "Work it,harder,Make it,etc".split(',')
I'm pretty sure the lyrics are wrong... near the start, there's a couple of places you have an 'f' when I believe you should have an 'e'... which would make there be an additional '0123456789abcdef' that you could replace with a 'g'.

Yeah, that's what I get for using search-and-replace to make that string and not checking it.

This seems to work (I haven't gone through it manually) and is only 264 characters.

Code: Select all

print(' '.join('Work it,harder,Make it,better,Do it,faster,Makes us,stronger,More than,ever,Hour,after,Our,work is,Never,over'.split(',')[int(c,16)]for c in'024613578ace9bdf02461357gggggghhghhg01589cdefg'.replace('g','0123456789abcdef').replace('h','0125689acd'))) 
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

User avatar
Xenomortis
Not actually a special flower.
Posts: 1448
Joined: Thu Oct 11, 2012 8:47 am UTC

Re: Daft Punk - experiment in efficiency

Postby Xenomortis » Tue Apr 23, 2013 7:54 pm UTC

Dammit, Python!
Image

Derek
Posts: 2181
Joined: Wed Aug 18, 2010 4:15 am UTC

Re: Daft Punk - experiment in efficiency

Postby Derek » Wed Apr 24, 2013 5:14 am UTC

I had the idea of doing "r=str.replace" so that all the instances of "replace" could be changed to "r" (other characters shuffle around and the dot becomes a comma, but the number remains the same). This saves 11 characters (6 for each "replace", -1 because I have to add a space after "in"), but the new line adds 13 characters, so it's a narrow loss. If 2 characters more characters could be saved with an additional replace, it would break even, but I don't think there are any possibilities left.

EDIT: Found the break-even. But not where I expected. In the words string "er," occurs 7 times, 8 if you count the final "over". Setting up the string substitution with "r(...,'_','er,')" costs 13 characters, and saves 7*2 + 1 = 15 characters, for a net of 2 characters. At 264 characters, this ties with the previous Python best.

Code: Select all

r=str.replace
print(' '.join(r('Work it,hard_Make it,bett_Do it,fast_Makes us,strong_More than,ev_Hour,aft_Our,work is,Nev_ov_','_','er,').split(',')[int(c,16)]for c in r(r('024613578ace9bdf02461357gggggghhghhg01589cdefg','g','0123456789abcdef'),'h','0125689acd')))

Simstud
Posts: 3
Joined: Tue May 12, 2009 7:02 pm UTC

Re: Daft Punk - experiment in efficiency

Postby Simstud » Sun Nov 03, 2013 10:16 pm UTC

Is this still going?

by simply compressing the output I can do it in 270 characters, shy of the current leader:

Code: Select all

import base64,zlib
print zlib.decompress(base64.b64decode("eJztksEOgjAMhl+lD+PBC3rkXGMRQ0KTdujru24rEcOFEBIPO4wO1n7/t4SWZYBngAYHsnpif1OYFHqUOwncKIRYOlQrGoTHR9w0LAShxxHOPAlc47rQKx6kB3bW/E4BCmyf2j1pPly6nFG6M6rMzMQV1eSWfLOgWbtktl+o1rSatjntN2CN+008FlPvfvTdHbzE/MMf+gHdfRag"))


with only lowercase output i can do it in 262 characters, becoming the new winner!!

Code: Select all

import base64,zlib
print zlib.decompress(base64.b64decode('eJztkt0KwzAIhV/FV3PULqM0gtr29RfzU9bRmw4Ku8hFohL9zhGysUzwMphxIo8Dt0phUQgoAwk8yCyFEdWDmnB8pmRmIbCAEQIvAn4irekhXzh685YFFHjdix/V2nDtaozaXVB1ZieeWM3est9i0LNmsrg/WO1qXe2y2rfAGfeTeC+m73737g18xPzDD30DwQQkoA=='))

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: Daft Punk - experiment in efficiency

Postby TheChewanater » Sun Nov 03, 2013 11:32 pm UTC

Nice one, but I can play dirtier. :twisted: 147 characters.

Code: Select all

r=str.replace;print(r(r(r(__import__('urllib2').urlopen('http://goo.gl/4KvLMV').read()[20960:23114],"<p class='verse'>",''),'</p>',''),'<br/>','')) 


Inspired by StackSort, this beautiful piece of code requires Python 2.7, and will probably break within the next few days as the polls/sidebar on the site changes.

As a side note, I'm kind of amused by how zlib compresses the song almost exactly the same amount that my str.replace method does.
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Daft Punk - experiment in efficiency

Postby You, sir, name? » Mon Nov 04, 2013 9:30 pm UTC

Simstud wrote:Is this still going?

by simply compressing the output I can do it in 270 characters, shy of the current leader:

Code: Select all

import base64,zlib
print zlib.decompress(base64.b64decode("eJztksEOgjAMhl+lD+PBC3rkXGMRQ0KTdujru24rEcOFEBIPO4wO1n7/t4SWZYBngAYHsnpif1OYFHqUOwncKIRYOlQrGoTHR9w0LAShxxHOPAlc47rQKx6kB3bW/E4BCmyf2j1pPly6nFG6M6rMzMQV1eSWfLOgWbtktl+o1rSatjntN2CN+008FlPvfvTdHbzE/MMf+gHdfRag"))


with only lowercase output i can do it in 262 characters, becoming the new winner!!

Code: Select all

import base64,zlib
print zlib.decompress(base64.b64decode('eJztkt0KwzAIhV/FV3PULqM0gtr29RfzU9bRmw4Ku8hFohL9zhGysUzwMphxIo8Dt0phUQgoAwk8yCyFEdWDmnB8pmRmIbCAEQIvAn4irekhXzh685YFFHjdix/V2nDtaozaXVB1ZieeWM3est9i0LNmsrg/WO1qXe2y2rfAGfeTeC+m73737g18xPzDD30DwQQkoA=='))


Shave off a few additional characters by going shellcript

Code: Select all

(base64 -d|gunzip)<<<H4sICP8eeFICA29yaWdpbmFsAL3OPQ7CMAwF4N2neAfgEiBAZSgdAHWOhPlRpVqyQ8+PnTQTO0NiW4ne51F0wilTnyaOupc2GW5GXdI7K+04Zy/HZFEuWWV+etOLMq6vNFMnH6XBz5kXfzjEtX3E5zGAt9GwtOHfGmosVhRrfLFRkQ3aDrAfDpGPMFERl1GzDWUDFO4LOEp7rUsBAAA=


234, preserving case.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: Daft Punk - experiment in efficiency

Postby TheChewanater » Tue Nov 05, 2013 1:00 am UTC

This is only 220 characters. Some messages are wrtten to stderr, but the same lyrics are printed to stdout as before.

Code: Select all

(base64 -d|gunzip)<<<H4sICJVBeFICA291dC50eHQAvc49DsIwDAXg3ad4B+ASIEBlKB0AdY6E+VGlWrJDz4+dNBM7Q2Jbid7nUXTCKVOfJo66lzYZbkZd0jsr7ThnL8dkUS5ZZX5604syrq80UycfpcHPmRd/OMS1fcTnMYC30bC04d8aaixWFGt8sVGRDdoOsB8OkY8wURGXUbMNZQMU7g
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

User avatar
hotaru
Posts: 1045
Joined: Fri Apr 13, 2007 6:54 pm UTC

Re: Daft Punk - experiment in efficiency

Postby hotaru » Tue Nov 05, 2013 3:18 am UTC

204 characters.

Code: Select all

H4sIAPBceFIAA8XOOw7CMAwG4N2n+A/AJUCAylA6AGKOhHmoUi3ZoefHjunEARgS52H9n6+iIw6V+jJy1K0sN8PFqCt6Y6UN1+plXyzKqapMDz/0oozzs0zUyVtp8HXk2T92sa3v0dyAl9EQT3/RkLH4osj4tJHICssMsB8OkY8wkYjLyGxDmwCN+w;base64 -$0|zcat


edit: it's really ugly, but... 157.

Code: Select all


‹5lxR  ÅÎ
;Â0àݧøÀ%@€ÊP: bŽ„y¨R-Ù¡çÇŽéÄçaýŸ¯¢#•ú2rÔ­,7ÃŨ+zc¥
×êe_,Ê©ªL?ô¢Œó³LÔÉ[iðuäÙ?v±­ïÑÜ€—ÑOѐ±ø¢Èø´‘È
Ë°‘0‘ˆËÈlC› û 
;sed 1d $0|zcat

Code: Select all

factorial product enumFromTo 1
isPrime n 
factorial (1) `mod== 1


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 7 guests