1 /* A knapsack full of songs */
6 #include <ucw/fastbuf.h>
7 #include <ucw/mempool.h>
19 static struct song *songs;
20 static struct mempool *mp;
22 int main(int argc, char **argv)
25 die("Usage: songsack <minutes>");
26 int goal = atoi(argv[1]) * 60;
32 struct fastbuf *f = bopen_fd(0, NULL);
34 while (bgets(f, line, sizeof(line)))
36 char *c = strchr(line, ' ');
41 if (sscanf(line, "%d:%d", &m, &s) != 2)
46 if (d < 60) // Ignore bogus tracks
49 DBG("<< %d <%s>", d, c);
50 struct song *g = GARY_PUSH(songs, 1);
51 g->name = mp_strdup(mp, c);
55 int n = GARY_SIZE(songs);
56 fprintf(stderr, "Considering %d songs\n", n);
58 srand(time(NULL) ^ getpid());
59 for (int i=0; i<n; i++)
61 int j = i + random_max(n-i);
62 struct song t = songs[i];
67 int *best = xmalloc_zero(size * sizeof(int));
68 int *used = xmalloc_zero(size * sizeof(int));
70 for (int i=0; i<n; i++)
72 int d = songs[i].duration;
73 for (int j=size-1; j>=d; j--)
74 if (!best[j] && best[j-d])
81 int opt=10*size, opti=-1;
82 for (int i=size-1; i>=0; i--)
85 int score = (i > goal) ? 3*(i-goal) : goal-i;
86 score += random_max(20) - 10;
88 opt = score, opti = i;
93 fprintf(stderr, "Duration: %02d:%02d\n", opti/60, opti%60);
97 int d = songs[j].duration;
98 fprintf(stderr, "%02d:%02d %s\n", d/60, d%60, songs[j].name);
99 printf("%s\n", songs[j].name);