Coder Social home page Coder Social logo

send_more_money's Introduction

SEND + MORE = MONEY

    SEND 
  + MORE 
  ------
   MONEY

A solver with an arithmetic propagator for SEND+MORE=MONEY. It is based on the propagator in Van Hentenryck's Coursera course on Discrete Optimization. The propagator is discussed in Video CP-2.

The program can be run by running the file send_more_money.py.

The primary feature of interest is the propagator, which is based on interval arithmetic as discussed by Van Hentenryck. The propagator is specialized to arithmetic addition problems and operates one column at a time. It is implemented in the function column_propagator in the file constraints_and_propagators.py. The function is generously commented.

The propagator is called repeatedly during the search, which is implemented by the function complete_the_assignment in the file CSP.py. It is called, via the function run_column_propagator at the beginning of complete_the_assignment. Since complete_the_assignmentis a recursive search, the propagator is called after every trial assignment of a value to a variable.

The function run_column_propagator repeatedly calls column_propagator on all the columns until no new information is generated, at which point the search continues.

An execution of SEND_MORE_MONEY generates the following output. (The variables C_i are carry variables. In particular, C0 is the carry-in variable to the units position. It is defined to be 0. The anonymous variable '_' serves as left-fill for short numbers and has the value 0. As you can see in the Initial state, C0 and _ are the only pre-defined values. They are both set to 0.) The other variables, both problem variables (other than 'M' and 'S') and carry variables are all given domains of frozenset(range(10)). As the initial digits of numbers M and S are given initial domains of frozenset(range(1, 10)). Numbers may not have leading zeros.

Problem: (['SEND', 'MORE'], 'MONEY')
Problem vars (in order of frequency): ['E', 'N', 'O', 'M', 'D', 'S', 'Y', 'R']

Columns:
4. (('C4', '_', '_'), ('C5', 'M'))
3. (('C3', 'S', 'M'), ('C4', 'O'))
2. (('C2', 'E', 'O'), ('C3', 'N'))
1. (('C1', 'N', 'R'), ('C2', 'E'))
0. (('C0', 'D', 'E'), ('C1', 'Y'))

Initial domains: {'C0': frozenset({0}), '_': frozenset({0}), 'M': frozenset({1, 2, 3, 4, 5, 6, 7, 8, 9}), 'S': frozenset({1, 2, 3, 4, 5, 6, 7, 8, 9}), 'E': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), 'N': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), 'O': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), 'D': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), 'Y': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), 'R': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), 'C1': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), 'C2': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), 'C3': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), 'C4': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), 'C5': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})}

Initial state:
assigned: {'C0': 0, '_': 0};
unassigned: ['E', 'N', 'O', 'M', 'D', 'S', 'Y', 'R', 'C1', 'C2', 'C3', 'C4', 'C5']

State after initial propagation
assigned: {'O': 0, 'M': 1, 'S': 9, 'C0': 0, 'C3': 0, 'C4': 1, 'C5': 0, '_': 0};
unassigned: ['E', 'N', 'D', 'Y', 'R', 'C1', 'C2']

Propagation after setting E = 5
assigned: {'E': 5, 'N': 6, 'O': 0, 'M': 1, 'D': 7, 'S': 9, 'Y': 2, 'R': 8, 'C0': 0, 'C1': 1, 'C2': 1, 'C3': 0, 'C4': 1, 'C5': 0, '_': 0};
unassigned: []

  SEND ->  9567
+ MORE ->  1085
------    -----
 MONEY -> 10652

{'E': 5, 'N': 6, 'O': 0, 'M': 1, 'D': 7, 'S': 9, 'Y': 2, 'R': 8, 'C0': 0, 'C1': 1, 'C2': 1, 'C3': 0, 'C4': 1, 'C5': 0, '_': 0}

Solution found after 4 assignments!

The initial propagation finds values for problem variables O=0, M=1, and S=9, and for the carry variables C3=0, C4=1, and C5=0. (C5 is the carry-out variables from the left-most column. The system is able to derive its value.)

The search selects E, the most frequently occuring variable, as the first variable for which to try trial values. Since 0 and 1 are taken, the search tries E=2, E=3, and E=4. These are all found to be incompatible with the problem specification. When the search tries E=5, it is able to solve the entire problem.

In other words, given the power of the arithmetic propagator, only four search steps are needed to solve the problem.

send_more_money's People

Contributors

russabbott avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.