// brute-force solver for http://scratch.mit.edu/projects/16127726
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define GEARS 5
#define MAX_GEARTRAIN 11
int gear[GEARS] = { 10, 20, 30, 50, 80 };
int geartrain[MAX_GEARTRAIN+1];

static char result[1024], *s;
static double best_so_far = 9999999999.9;

void try_ratio(int gearno, double RPM, double target, int max_depth) {
  double this;
  int i, mult, div;
  for (mult = 0; mult < GEARS; mult++) {
    geartrain[gearno] = mult;
    for (div = 0; div < GEARS; div++) {
      geartrain[gearno+1] = div;
      this = -RPM*gear[mult]/gear[div];
      if (fabs(target-fabs(this)) < best_so_far) { // record the new best so far
        best_so_far = fabs(target-fabs(this));
        s = result; *s = '\0';
        if (this < 0) s += sprintf(s, "reversed ");
        s += sprintf(s, "drive ");
        for (i = 0; i <= gearno+1; i++) {
          s += sprintf(s, "%d ", gear[geartrain[i]]);
          if (i != gearno+1) {
            if ((i&1) == 0) s+=sprintf(s, " mesh "); else s+=sprintf(s," compound ");
          }
        }
        s+=sprintf(s, " = %f\n", fabs(this));
      }
      if (gearno < max_depth) try_ratio(gearno+2, this, target, max_depth);
    }
  }
}

int main(int argc, char **argv) {
  int maxdepth;
  double target;
  if (argc == 2) {
    target = atof(argv[1]);
  } else if (argc == 3) {
    target = atof(argv[1])/atof(argv[2]);
    fprintf(stderr, "Target %f\n", target);
  } else {
    fprintf(stderr, "syntax: gears revs, or gears num denom\n");
    exit(1);
  }
  sprintf(result, "Nothing found\n");
  for (maxdepth = 2; maxdepth < MAX_GEARTRAIN; maxdepth++) {
    try_ratio(0, 1.00, target, maxdepth);
    printf("%s", result);
  }
  exit(0);
  return 1;
}