Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Mathematical Challenge (Lottery)
Message
From
02/06/2003 05:43:47
Walter Meester
HoogkarspelNetherlands
 
 
To
01/06/2003 06:20:59
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
00785796
Message ID:
00795106
Views:
32
All,

O.K, I've taken another strategy. See my code below. It is far faster than my previous code and has the possibility to define the maximum number of solutions you want to have.
FUNCTION AddUp
PARAMETERS nResultNumber, nMaxNumberToFind 
** nResultNumber: The number to search
** nMaxNumberToFind: Define the maximum number of Addup expressions you  want. -1 = all

PRIVATE nMaxNumberToFind, nFound, nNumber 
LOCAL nT, nSec, nAddpos, nAddNeg

CREATE CURSOR Result (Result C(240))
CREATE CURSOR Numbers (Number B(2))

FOR nT = 1 TO 20
	INSERT INTO Numbers VALUES(nT)
ENDFOR

nFound           = 0					
nNumbers         = RECCOUNT()
nMaxNumberToFind = IIF(EMPTY(nMaxNumberToFind),-1,nMaxNumberToFind)
nSec             = SECONDS()

** Just sort all numbers is decending order and calculated the cumulative summaries for both ;
** positives and negatives

SELECT *, 1*Number as Addpos, 1*Number Addneg;
	 FROM Numbers ;
	 ORDER BY 1 DESCENDING ;
	 INTO CURSOR Num2 READWRITE
	 
INDEX ON Number TAG Num

STORE 0 TO nAddPos, nAddneg
SCAN
	nAddPos = nAddPos + IIF(Number > 0, Number,0)
	nAddNeg = nAddNeg + IIF(Number < 0, Number,0)
	REPLACE Addpos WITH nAddPos,;
		Addneg WITH nAddNeg
ENDSCAN

DO CheckForSumIsResult WITH 0, 0, "",1
? "Time: "+STR(SECONDS()-nSec,6,3)

SELECT Result
BROWSE NORMAL
RETURN

*-

FUNCTION CheckForSumIsResult(nTotal, nRec, cCalc, nLevel)

IF SEEK(nResultNumber - nTotal) AND RECNO()> nRec
	INSERT INTO Result VALUES(cCalc+"+"+ALLTRIM(STR(Num2.Number,10,2)))
	nFound = nFound + 1
ENDIF

IF nRec = nNumbers OR nLevel > 127
	RETURN .F.
ENDIF

GO nRec+1
DO WHILE BETWEEN(nResultNumber,nTotal+Addneg, nTotal+Addpos) AND ;
	CheckForSumIsResult(nTotal+Number, RECNO(), cCalc+"+"+ALLTRIM(STR(Number,10,2)), nLevel+1) AND nFound # nMaxNumberToFind 
ENDDO
GO nRec+1
RETURN
With 20 numbers this routine could list all possible expressions that add up to a certain number within a second (XP 1800+). Be warned when for example for calculating all possible numbers combinations that add up to 100, it will list more than 15000 expressions.

If you're only interested in one or a few possible combinations, just pass the the maximumnumber of results as the second parameter.

You can increase the number of numbers safely if you set a maximum for the number of results. The number of results could increase exponential, depending on the distribution of the numbers and the summ to search for.

Walter,
Previous
Reply
Map
View

Click here to load this message in the networking platform