money.c 2.27 KB
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include "fdc_int.h"

#define LETTERS 26
#define MAX_SIZE (10 * LETTERS)		// whatever

int main(int argc, char *argv[])
{
  char *equation = "send+more=money";
  fd_int letters[LETTERS], used[LETTERS];
  fd_int eqvars[MAX_SIZE];
  int eqcoefs[MAX_SIZE];
  fd_int zero;
  int n;			// different letters used
  int l;			// number of letters in the equation
  int p;
  char c, *s;

  int solutions = 0, one_solution = 1;
  int i, j;

  fd_init(&argc, &argv);

  for (i = 1; i < argc; ++i)
    if (!strcmp(argv[i], "--all"))
      one_solution = 0;
    else
      {
	equation = argv[i];

	break;
      }

  zero = fd_new(0, 0);

  memset(letters, 0, sizeof(letters));

  n = 0; l = 0;

  // first summand
  for (i = 0; (c = equation[i]) != '+'; ++i)
    {
      if (letters[c - 'a'] == 0)
	used[n++] = letters[c - 'a'] = fd_new(0, 9);

      eqvars[l++] = letters[c - 'a'];

      if (i == 0)
	fd_gt(letters[c - 'a'], zero);
    }

  for (j = l - 1, p = 1; j >= 0; --j, p *= 10)
    eqcoefs[j] = p;

  // second summand
  s = equation + i + 1;

  for (i = 0; (c = s[i]) != '='; ++i)
    {
      if (letters[c - 'a'] == 0)
	used[n++] = letters[c - 'a'] = fd_new(0, 9);

      eqvars[l++] = letters[c - 'a'];

      if (i == 0)
	fd_gt(letters[c - 'a'], zero);
    }

  s += i + 1;

  for (j = 0, p = 1; j < i; ++j, p *= 10)
    eqcoefs[l - 1 - j] = p;

  // sum
  for (i = 0; (c = s[i]) != '\0'; ++i)
    {
      if (letters[c - 'a'] == 0)
	used[n++] = letters[c - 'a'] = fd_new(0, 9);

      eqvars[l++] = letters[c - 'a'];

      if (i == 0)
	fd_gt(letters[c - 'a'], zero);
    }

  for (j = 0, p = -1; j < i; ++j, p *= 10)
    eqcoefs[l - 1 - j] = p;

  // constraints
  fd_all_different(used, n);
  fd_poly_eq(eqcoefs, eqvars, l, zero);

  while (fd_solve() == FD_OK)
    {
      printf("solution %d:\n", ++solutions);

      printf("\t%s\n", equation);

      putchar('\t');
      for (s = equation; *s; ++s)
	if (islower(*s))
	  printf("%d", fd_var_value(letters[*s - 'a']));
	else
	  putchar(*s);
      putchar('\n');

#if !(defined(LOCAL_SEARCH) || defined(DISTRIBUTED_SOLVER))
      if (one_solution)
#endif
	break;
    }

  if (solutions)
    printf("%d solutions found\n", solutions);
  else
    printf("inconsistent CSP\n");

  fd_end();

  return !solutions;
}