+#include "lib/lib.h"
+#include "lib/fastbuf.h"
+#include "lib/bbuf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+struct file {
+ char *name;
+ int blocks;
+};
+
+int main(int argc, char **argv)
+{
+ if (argc != 3)
+ die("Usage: du -sb * | fit <block-size> <num-blocks>");
+ int bs = atol(argv[1]);
+ int m = atol(argv[2]);
+
+ char buf[1024];
+ struct fastbuf *in = bopen_fd(0, NULL);
+ bb_t files_buf;
+ struct file *files = NULL;
+ int n = 0;
+ int tb = 0;
+ bb_init(&files_buf);
+ while (bgets(in, buf, sizeof(buf)))
+ {
+ char *c = strchr(buf, '\t');
+ if (!c)
+ die("Syntax error in input: %s", buf);
+ while (*c == '\t')
+ *c++ = 0;
+ files = (struct file *) bb_grow(&files_buf, sizeof(struct file) * (n+1));
+ files[n].name = xstrdup(c);
+ files[n].blocks = (atol(buf) + bs - 1) / bs;
+ printf("#%d: %s (%d blocks)\n", n, files[n].name, files[n].blocks);
+ tb += files[n].blocks;
+ n++;
+ }
+ printf("%d files of %d blocks total\n\n", n, tb);
+
+ char *map = xmalloc_zero(m+1);
+ map[0] = 1;
+ for (int i=0; i<n; i++)
+ {
+ int s = files[i].blocks;
+ for (int j=m-s; j>=0; j--)
+ if (map[j] && !map[j+s])
+ map[j+s] = 2+i;
+ }
+ int max = m;
+ while (!map[max])
+ max--;
+
+ printf("Found subset with %d blocks:\n", max);
+ while (max)
+ {
+ int f = map[max]-2;
+ printf("%7d\t%s\n", files[f].blocks, files[f].name);
+ max -= files[f].blocks;
+ }
+
+ return 0;
+}