import java.lang.*; import java.awt.*; import java.applet.*; import java.util.*; final public class Alphametic extends Applet implements Runnable { final static int _iMaxDigits = 10; TextField _atfDigits[][] = new TextField[3][_iMaxDigits]; final static String _strGo = "Go", _strClear = "Clear", _strTest = "Test"; Thread _thread = null; int _cMaxDigits, _iNoZero; final public void init() { setLayout(new BorderLayout()); Color color = new Color(0xd8, 0xd0, 0xd8); setBackground(color); Panel panel = new Panel(); panel.setBackground(color); panel.setLayout(new GridLayout(3, 1)); panel.add(new Button(_strGo)); panel.add(new Button(_strClear)); panel.add(new Button(_strTest)); add("East", panel); panel = new Panel(); panel.setLayout(new GridLayout(3, _iMaxDigits)); for (int iNumber = 0; iNumber <= 2; iNumber++) { for (int iChar = 0; iChar < _iMaxDigits; iChar++) { panel.add(_atfDigits[iNumber][_iMaxDigits - 1 - iChar] = new TextField()); } } add("Center", panel); } final public void start() { requestFocus(); } final public void stop() { if (_thread != null && _thread.isAlive()) { _thread.stop(); } _thread = null; } final private boolean loop(int aaiDigitIndeces[][], int aiCharDigit[], int iCharIndex, int iMaxIndex, int cDigits, int iUsed) { for (int iLoopDigit = ((_iNoZero & (1 << iCharIndex)) != 0 ? 1 : 0); iLoopDigit <= 9; iLoopDigit++) { if ((iUsed & (1 << iLoopDigit)) == 0) { aiCharDigit[iCharIndex] = iLoopDigit; if (iMaxIndex == iCharIndex) { if (calculate(aaiDigitIndeces, aiCharDigit, iCharIndex, iMaxIndex, cDigits, iUsed | (1 << iLoopDigit))) { return true; } } else { if (loop(aaiDigitIndeces, aiCharDigit, iCharIndex + 1, iMaxIndex, cDigits, iUsed | (1 << iLoopDigit))) { return true; } } } } return false; } final private boolean calculate(int aaiDigitIndeces[][], int aiCharDigit[], int iCharIndex, int iMaxIndex, int cDigits, int iUsed) { int iSum1 = 0, iSum2 = 0, iScale = 1; for (int iGauge = 0; iGauge < cDigits; iGauge++) { int iTemp = aaiDigitIndeces[0][iGauge]; if (iTemp >= 0) { iSum1 += aiCharDigit[iTemp] * iScale; } iTemp = aaiDigitIndeces[1][iGauge]; if (iTemp >= 0) { iSum1 += aiCharDigit[iTemp] * iScale; } iTemp = aaiDigitIndeces[2][iGauge]; if (iTemp >= 0) { iSum2 += aiCharDigit[iTemp] * iScale; } iScale *= 10; } if (cDigits != _cMaxDigits) { iSum1 %= iScale; } if (iSum1 == iSum2) { if (cDigits == _cMaxDigits) { return true; } else { for (int iNumber = 0; iNumber <= 2; iNumber++) { iMaxIndex = Math.max(iMaxIndex, aaiDigitIndeces[iNumber][cDigits]); } if (iCharIndex == iMaxIndex) { return calculate(aaiDigitIndeces, aiCharDigit, iCharIndex, iMaxIndex, cDigits + 1, iUsed); } else { return loop(aaiDigitIndeces, aiCharDigit, iCharIndex + 1, iMaxIndex, cDigits + 1, iUsed); } } } return false; } final public void run() { Hashtable hash = new Hashtable(); int cDigits = 0; int acDigits[] = new int[3]; int aaiDigitIndeces[][] = new int[3][_iMaxDigits]; acDigits[0] = acDigits[1] = acDigits[2] = _iMaxDigits; _iNoZero = 0; for (int iDigit = 0; iDigit < _iMaxDigits; iDigit++) { for (int iNumber = 0; iNumber <= 2; iNumber++) { String strChar = _atfDigits[iNumber][iDigit].getText(); if (iDigit >= acDigits[iNumber]) { if (strChar.length() == 0) { aaiDigitIndeces[iNumber][iDigit] = -1; } else { _thread = null; return; } } else { if (strChar.length() == 0) { if (iDigit == 0) { _thread = null; return; } acDigits[iNumber] = iDigit; _iNoZero |= (1 << aaiDigitIndeces[iNumber][iDigit - 1]); aaiDigitIndeces[iNumber][iDigit] = -1; } else { Object intIndex = hash.get(strChar); if (intIndex != null) { aaiDigitIndeces[iNumber][iDigit] = ((Integer)intIndex).intValue(); } else { if (cDigits >= 10) { _thread = null; return; } hash.put(strChar, new Integer(cDigits)); aaiDigitIndeces[iNumber][iDigit] = cDigits++; } } } } } _cMaxDigits = Math.max(Math.max(acDigits[0], acDigits[1]), acDigits[2]); int aiCharDigit[] = new int[10]; if (loop(aaiDigitIndeces, aiCharDigit, 0, Math.max(Math.max(aaiDigitIndeces[0][0], aaiDigitIndeces[1][0]), aaiDigitIndeces[2][0]), 1, 0)) { for (int iNumber = 0; iNumber <= 2; iNumber++) { for (int iDigit = 0; iDigit < _iMaxDigits; iDigit++) { int iTemp = aaiDigitIndeces[iNumber][iDigit]; if (iTemp >= 0) { _atfDigits[iNumber][iDigit].setText(String.valueOf(aiCharDigit[iTemp])); } } } } _thread = null; } final public boolean action(Event evt, Object arg) { if (evt.target instanceof Button) { if (arg.equals(_strGo)) { if (_thread == null) { (_thread = new Thread(this)).start(); } } else if (arg.equals(_strClear)) { for (int iNumber = 0; iNumber <= 2; iNumber++) { for (int iDigit = 0; iDigit < _iMaxDigits; iDigit++) { _atfDigits[iNumber][iDigit].setText(""); } } } else if (arg.equals(_strTest)) { String aastr[][] = { { "d", "n", "e", "s" }, { "e", "r", "o", "m" }, { "y", "e", "n", "o", "m" } }; for (int iNumber = 0; iNumber <= 2; iNumber++) { int cLength = aastr[iNumber].length; for (int iDigit = 0; iDigit < _iMaxDigits; iDigit++) { _atfDigits[iNumber][iDigit].setText(iDigit >= cLength ? "" : aastr[iNumber][iDigit]); } } } } return true; } }