[[https://www.revelation.com/|Sign up on the Revelation Software website to have access to the most current content, and to be able to ask questions and get answers from the Revelation community]] ==== Unique combinations of numbers in a set (AREV Specific) ==== === At 06 AUG 2011 06:44:07AM William Titus wrote: === {{tag>"AREV Specific"}} From a sorted list of numbers such as "10,20,30,40,50" I need to build an ordered list of all unique combinations without repeating elements. In this case, the combinations would be: 10, 20, 30, 40, 50, 10*20, 10*30, 10*40, 10*50, 20*30, 20*40, 20*50, 30*40, 30*50, 40*50, 10*20*30, 10*20*40, 10*20*50, 10*30*40, 10*30*50, 10*40*50, 10*20*30*40, 10*20*30*50, 10*30*40*50, 10*20*30*40*50 The number of numbers is not fixed. Can one of you math wizards set me on the right programmatic path (recursive or otherwise) to get me where I need to go? Thanks! ---- === At 06 AUG 2011 11:27AM Richard Hunt wrote: === Since I am not sure if you can delimit by using value marks and field marks rather than the commas ans asterisks, I used FOR/NEXT rather than REMOVE statements... RESULT=' DELIMITER=*' STRING=1:DELIMITER:2:DELIMITER:3:DELIMITER:4:DELIMITER:5 STRING=1:DELIMITER:2:DELIMITER:3:DELIMITER:4:DELIMITER:5 LAST_VALUE=COUNT(STRING,DELIMITER) + (STRING NE '') FOR VALUE=1 TO LAST_VALUE RESULT := @VM:FIELD(STRING,DELIMITER,VALUE) NEXT VALUE FOR VALUE=1 TO LAST_VALUE PREFIX=FIELD(STRING,DELIMITER,1,VALUE) SUFFIX=FIELD(STRING,DELIMITER,VALUE + 1,LAST_VALUE) LAST_SUFFIX_VALUE=COUNT(SUFFIX,DELIMITER) + (SUFFIX NE '') FOR SUFFIX_VALUE=1 TO LAST_SUFFIX_VALUE RESULT := @VM:PREFIX:DELIMITER:FIELD(SUFFIX,DELIMITER,SUFFIX_VALUE) NEXT SUFFIX_VALUE NEXT VALUE RESULT=RESULT2,LEN(RESULT) ---- === At 06 AUG 2011 02:58PM William Titus wrote: === Thanks, Richard, for taking time to send me your code. It's a lot more compact than mine and took me as far as: 1²2²3²4²5²1*2²1*3²1*4²1*5²1*2*3²1*2*4²1*2*5²1*2*3*4²1*2*3*5²1*2*3*4*5 The code I've built to this point is this: *********** DATUM=" RUN=1 NUMBERS=1,2,3,4,5" CONVERT "," TO @VM IN NUMBERS HOWMANY=COUNT(NUMBERS,@VM)+(NUMBERS NE "") COMBOS=HOWMANY * HOWMANY ARRAY=" FOR X=1 TO HOWMANY FOR G=1 TO HOWMANY ARRAY=NUMBERS NEXT G NEXT X * ALLCOMBOS=" FOR X=1 TO COMBOS FOR G=1 TO HOWMANY DATUM=ARRAY LOCATE DATUM IN ALLCOMBOS USING @VM SETTING POS ELSE IF DATUM NE "" THEN IF ALLCOMBOS=" THEN ALLCOMBOS=DATUM ELSE ALLCOMBOS:=@VM:DATUM END END NEXT G NEXT X * FOR X=1 TO COMBOS D=NUMBERS FOR Y=X+1 TO COMBOS E=NUMBERS IF E NE "" THEN DATUM=D:"*":E LOCATE DATUM IN ALLCOMBOS USING @VM SETTING POS ELSE IF DATUM NE "" THEN IF ALLCOMBOS=" THEN ALLCOMBOS=DATUM ELSE ALLCOMBOS:=@VM:DATUM END END END NEXT Y NEXT X FOR X=1 TO COMBOS D=NUMBERS FOR Y=X+1 TO COMBOS E=NUMBERS FOR Z=Y+1 TO COMBOS F=NUMBERS IF E NE "" AND F NE "" THEN DATUM=D:"*":E:"*":F LOCATE DATUM IN ALLCOMBOS USING @VM SETTING POS ELSE IF DATUM NE "" THEN IF ALLCOMBOS=" THEN ALLCOMBOS=DATUM ELSE ALLCOMBOS:=@VM:DATUM END END END NEXT Z NEXT Y NEXT X *********** And it gets me to: 1²2²3²4²5²1*2²1*3²1*4²1*5²2*3²2*4²2*5²3*4²3*5²4*5²1*2*3²1*2*4²1*2*5²1*3*4²1*3*5²1*4 *5²2*3*4²2*3*5²2*4*5²3*4*5 I realized that this is a kludge and only gets me to 3-digit groups, though it gets exactly what I want to that point. I think I need a simple recursive way to minimize the code and maximize efficiency. I'm just not proficient enough as a coder at this point to know the way to get there except by adding more FOR-NEXT loops while also accounting for the maximum number of numbers the user will want to put into as many groups as possible. Thanks again for your help. ---- === At 08 AUG 2011 10:13AM Michael Slack wrote: === Just off the top of my head, I think you might find a FOR loop and a LOCATE BY to be simpler. I'll sketch out what I'm thinking in pseudo code. * Start_Array is your array or row that you want to work with. * End_Array is your resulting array or row. CNT_START_ARRAY=COUNT(START_ARRAY, @VM) + (START_ARRAY # '') IF CNT_START_ARRAY=0 THEN STOP PROCESS FOR I=1 TO CNT_START_ARRAY LOCATE START_ARRAY IN END_ARRAY BY "AL" USING @VM SETTING POS ELSE END_ARRAY=START_ARRAY END NEXT I What this does is any time it doesn't find a matching value in the END_ARRAY, it put it in, in sorted order. So, if it find a duplicate value already within the END_ARRAY, it won't add it. So, in the end you get only unique values within the END_ARRAY. Of course if this is what you're looking for, you'll need to flesh it out to fit your particular needs. I hope this helps. Michael Slack ---- === At 10 AUG 2011 02:37PM Mike Ruane wrote: === Mike- I'd use the same code as you, except using a LOOP...REMOVE to remove the items from the array, instead of the FOR...NEXT loop. Mike ---- === At 11 AUG 2011 04:49PM Bill Titus wrote: === Thanks, all. Your help is much appreciated by this old dog. Now it's off to implement what's been suggested! [[https://www.revelation.com/revweb/oecgi4p.php/O4W_HANDOFF?DESTN=O4W_RUN_FORM&INQID=NONWORKS_READ&SUMMARY=1&KEY=1407169525032DFC852578E4003AF8D7|View this thread on the forum...]]