<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Summing to a target value in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/707948#M217456</link>
    <description>&lt;P&gt;Must you always choose 3 of the numbers?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If there is more than one combination that sums to 20 do you want all possible combinations?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In your example, 8 + 9 + 1 + 2 = 20.&amp;nbsp; Also 5 + 3 + 9 + 1 + 2 = 20.&amp;nbsp; So what result do you want?&amp;nbsp; 1, 2, 3, 5, 8, 9?&lt;/P&gt;</description>
    <pubDate>Wed, 23 Dec 2020 18:33:35 GMT</pubDate>
    <dc:creator>Astounding</dc:creator>
    <dc:date>2020-12-23T18:33:35Z</dc:date>
    <item>
      <title>Summing to a target value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/707928#M217447</link>
      <description>I have a problem that I can summarise as:&lt;BR /&gt;&lt;BR /&gt;I have the numbers 1-10 in a variable and have to keep the numbers that will sum to 20 (e.g. 3, 8 &amp;amp; 9)&lt;BR /&gt;&lt;BR /&gt;The only way I can think of doing this is transposing and then with a lot of do loops and a do until. Unfortunately when I put the problem into practice there could be over 100 numbers summing to the target number.&lt;BR /&gt;&lt;BR /&gt;Has anyone got any ideas?</description>
      <pubDate>Wed, 23 Dec 2020 17:03:04 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/707928#M217447</guid>
      <dc:creator>Imp1</dc:creator>
      <dc:date>2020-12-23T17:03:04Z</dc:date>
    </item>
    <item>
      <title>Re: Summing to a target value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/707932#M217450</link>
      <description>&lt;P&gt;I think some computer science teachers might like to use this problem to teach the subject of recursion.&amp;nbsp; As far as SAS goes, you can learn PROC FCMP which will let you do recursion.&amp;nbsp; But I haven't done this in SAS myself.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://documentation.sas.com/?cdcId=pgmsascdc&amp;amp;cdcVersion=9.4_3.5&amp;amp;docsetId=proc&amp;amp;docsetTarget=n1712ebq466zztn1qli0vyf0e4v8.htm&amp;amp;locale=en"&gt;SAS Help Center: Recursion&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 23 Dec 2020 17:30:22 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/707932#M217450</guid>
      <dc:creator>PhilC</dc:creator>
      <dc:date>2020-12-23T17:30:22Z</dc:date>
    </item>
    <item>
      <title>Re: Summing to a target value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/707936#M217451</link>
      <description>&lt;P&gt;... you would need to access an Hash Object too.&amp;nbsp; Ok I'm intrigued, now.&amp;nbsp; &amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 23 Dec 2020 17:36:11 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/707936#M217451</guid>
      <dc:creator>PhilC</dc:creator>
      <dc:date>2020-12-23T17:36:11Z</dc:date>
    </item>
    <item>
      <title>Re: Summing to a target value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/707937#M217452</link>
      <description>&lt;P&gt;Suppose your variable is:&amp;nbsp; &lt;STRONG&gt;data_in&lt;/STRONG&gt; &lt;STRONG&gt;= "1 2 3 4 5 6 7 8 9 10";&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;1) assign each number to a different variable: v1-v10 using &lt;STRONG&gt;scan&lt;/STRONG&gt;() function.&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;now you have 10 variables with value &amp;gt; 0.&lt;/P&gt;
&lt;P&gt;2) choose randomly any integer between 1 and 10; (with &lt;STRONG&gt;ranuni&lt;/STRONG&gt;() function or other )&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- subtract the number from 20 and keep the difference in a variable &lt;STRONG&gt;diff&lt;/STRONG&gt;.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- assign 0 to v(number)&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- save the v(number) in a list if its value is not 0.&lt;/P&gt;
&lt;P&gt;3) if diff &amp;gt;10 repeat step 2&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; else, if diff &amp;lt;=10 that is the last number to save.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Try to code it and post your code when you have any issue.&lt;/P&gt;</description>
      <pubDate>Wed, 23 Dec 2020 17:44:59 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/707937#M217452</guid>
      <dc:creator>Shmuel</dc:creator>
      <dc:date>2020-12-23T17:44:59Z</dc:date>
    </item>
    <item>
      <title>Re: Summing to a target value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/707948#M217456</link>
      <description>&lt;P&gt;Must you always choose 3 of the numbers?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If there is more than one combination that sums to 20 do you want all possible combinations?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In your example, 8 + 9 + 1 + 2 = 20.&amp;nbsp; Also 5 + 3 + 9 + 1 + 2 = 20.&amp;nbsp; So what result do you want?&amp;nbsp; 1, 2, 3, 5, 8, 9?&lt;/P&gt;</description>
      <pubDate>Wed, 23 Dec 2020 18:33:35 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/707948#M217456</guid>
      <dc:creator>Astounding</dc:creator>
      <dc:date>2020-12-23T18:33:35Z</dc:date>
    </item>
    <item>
      <title>Re: Summing to a target value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/708014#M217491</link>
      <description>&lt;P&gt;Use the ALLCOMB function to check all combinations.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/* Fake data */
data have;
call streaminit(865764579);
do case = 1 to 30;
    nbNums = rand("integer", 1, 8);
    do i = 1 to nbNums;
        num = rand("integer", 1, 10);
        output;
        end;
    end;
keep case num;
run;

data want;
array c{*} c1-c8;
do nbNums = 1 by 1 until(last.case);
    set have; by case;
    c{nbNums} = num;
    end;
k = 3;
if nbNums &amp;gt;= k then do;
    ncomb = comb(nbNums, k);
    do j = 1 to ncomb+1;
        select (nbNums);
            when(3) rc = 1;
            when(4) do; rc = allcomb(j, k, of c1-c4); end;
            when(5) do; rc = allcomb(j, k, of c1-c5); end;
            when(6) do; rc = allcomb(j, k, of c1-c6); end;
            when(7) do; rc = allcomb(j, k, of c1-c7); end;
            when(8) do; rc = allcomb(j, k, of c1-c8); end;
            otherwise rc = -1;
            end;
        if rc &amp;gt;= 0 then if sum(c1,c2,c3) = 20 then do;
            output;
            /* leave */; /* If you only want one combination */
            end;
        end;
    end;
keep case c1 c2 c3;
run;

proc print noobs data=want; var case c1-c3; run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PGStats_0-1608762548322.png" style="width: 400px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/52993iB1C72A4EDF492B81/image-size/medium?v=v2&amp;amp;px=400" role="button" title="PGStats_0-1608762548322.png" alt="PGStats_0-1608762548322.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 23 Dec 2020 22:30:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/708014#M217491</guid>
      <dc:creator>PGStats</dc:creator>
      <dc:date>2020-12-23T22:30:05Z</dc:date>
    </item>
    <item>
      <title>Re: Summing to a target value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/708070#M217518</link>
      <description>&lt;P&gt;the best choice is SAS/OR if you have it . post your questions at OR forum&lt;/P&gt;
&lt;P&gt;and calling&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/1636"&gt;@RobPratt&lt;/a&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 24 Dec 2020 12:28:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/708070#M217518</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2020-12-24T12:28:14Z</dc:date>
    </item>
    <item>
      <title>Re: Summing to a target value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/708104#M217535</link>
      <description>&lt;P&gt;You can use the constraint programming solver in PROC OPTMODEL:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc optmodel;
   num n = 10;
   num target = 20;

   /* X[j] = 1 if j is selected; 0 otherwise */
   var X {1..n} binary;

   /* selected numbers must sum to target */
   con Partition:
      sum {j in 1..n} j * X[j] = target;

   solve with clp / findallsolns;
   for {s in 1.._NSOL_} do;
      for {j in 1..n: X[j].sol[s] &amp;gt; 0.5} put j @;
      put;
   end;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The resulting partitions are:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;5 7 8&lt;BR /&gt;5 6 9&lt;BR /&gt;4 7 9&lt;BR /&gt;4 6 10&lt;BR /&gt;3 8 9&lt;BR /&gt;3 7 10&lt;BR /&gt;3 4 6 7&lt;BR /&gt;3 4 5 8&lt;BR /&gt;2 8 10&lt;BR /&gt;2 5 6 7&lt;BR /&gt;2 4 6 8&lt;BR /&gt;2 4 5 9&lt;BR /&gt;2 3 7 8&lt;BR /&gt;2 3 6 9&lt;BR /&gt;2 3 5 10&lt;BR /&gt;2 3 4 5 6&lt;BR /&gt;1 9 10&lt;BR /&gt;1 5 6 8&lt;BR /&gt;1 4 7 8&lt;BR /&gt;1 4 6 9&lt;BR /&gt;1 4 5 10&lt;BR /&gt;1 3 7 9&lt;BR /&gt;1 3 6 10&lt;BR /&gt;1 3 4 5 7&lt;BR /&gt;1 2 8 9&lt;BR /&gt;1 2 7 10&lt;BR /&gt;1 2 4 6 7&lt;BR /&gt;1 2 4 5 8&lt;BR /&gt;1 2 3 6 8&lt;BR /&gt;1 2 3 5 9&lt;BR /&gt;1 2 3 4 10&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;If you want to restrict to exactly three summands, you can add this constraint:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;   /* select three numbers */
   con Cardinality:
      sum {j in 1..n} X[j] = 3;   
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;5 7 8&lt;BR /&gt;5 6 9&lt;BR /&gt;4 7 9&lt;BR /&gt;4 6 10&lt;BR /&gt;3 8 9&lt;BR /&gt;3 7 10&lt;BR /&gt;2 8 10&lt;BR /&gt;1 9 10&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;If you want to allow the same number to appear more than once, you can change the VAR statement:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;   var X {1..n} &amp;gt;= 0 integer;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;And then also change the FOR loop:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;   for {s in 1.._NSOL_} do;
      for {j in 1..n, 1..round(X[j].sol[s])} put j @;
      put;
   end;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;5 5 10&lt;BR /&gt;4 6 10&lt;BR /&gt;5 6 9&lt;BR /&gt;1 9 10&lt;BR /&gt;2 9 9&lt;BR /&gt;6 6 8&lt;BR /&gt;2 8 10&lt;BR /&gt;3 8 9&lt;BR /&gt;4 8 8&lt;BR /&gt;3 7 10&lt;BR /&gt;4 7 9&lt;BR /&gt;5 7 8&lt;BR /&gt;6 7 7&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;If you want the order to matter (to distinguish 3 8 9 from 8 3 9), please let me know and I'll update the formulation.&lt;/P&gt;</description>
      <pubDate>Thu, 24 Dec 2020 16:20:57 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/708104#M217535</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2020-12-24T16:20:57Z</dc:date>
    </item>
    <item>
      <title>Re: Summing to a target value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/708133#M217553</link>
      <description>&lt;P&gt;One could program all combinations of 3 integers drawn from 1 through 10 - and then filter for those that sum to 20, which is how I understand many of the solutions.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;But you could use a different strategy that step through only those that start out summing to 20.&amp;nbsp; The program below finds only triples where&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;x1&amp;lt;x2&amp;lt;x3, and&amp;nbsp; &amp;nbsp; &amp;nbsp;(I have a similar approach for x1&amp;lt;=x2&amp;lt;=x3 below).&lt;/LI&gt;
&lt;LI&gt;sum(of x:)=20.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Once you've found these, you could get all the re-orderings of x1,x2,x3 if desired.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The strategy is&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;first find the minimum possible x1 and maximum possible x1 that could satisfy 1 and 2 above.
&lt;OL&gt;
&lt;LI&gt;The minimum is obviously 1&lt;/LI&gt;
&lt;LI&gt;The maximum has to be the floor of (20/3) minus 1.&amp;nbsp; Since 5+6+7=18 and 6+7+8=21 the maximum has to be 5.&amp;nbsp; (drop the minus 1 if re-use of integers is allowed: x1&amp;lt;=x2&amp;lt;=x3).&lt;/LI&gt;
&lt;/OL&gt;
&lt;/LI&gt;
&lt;LI&gt;For each possible value of x1=1 to 5, get the maximum allowable value for X3.&amp;nbsp; That can be either 10, or 20-x1-(x1+1).&amp;nbsp; whichever is smaller (again adjustable for x1&amp;lt;=x2&amp;lt;=x3).&lt;/LI&gt;
&lt;LI&gt;Calculate the corresponding X2&lt;/LI&gt;
&lt;LI&gt;Then loop as long as x1&amp;lt;x2&amp;lt;x3 and sum(of x:)=20
&lt;OL&gt;
&lt;LI&gt;report the triple&lt;/LI&gt;
&lt;LI&gt;decrement x3 by 1 and increment x2 by 1&lt;/LI&gt;
&lt;/OL&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let sum=20;
%let max_x=10;

data _null_;
  upper_limit1=floor(&amp;amp;sum/3)-1;

  length x1-x3 8;

  do x1=1 to upper_limit1;
    x3=min(&amp;amp;sum-x1-x1-1,&amp;amp;max_x); 
    x2=&amp;amp;sum-x1-x3;
    do while (x1&amp;lt;x2 and x2&amp;lt;x3);
      put (x1 x2 x3) (+2 z2.);
      x3=x3-1;
      x2=x2+1;
    end;
  end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Now if a number can be re-used, then minor modifications can be made:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let sum=20;
%let max_x=10;

data _null_;
  upper_limit1=floor(&amp;amp;sum/3);  /* drop the "-1" */

  length x1-x3 8;

  do x1=1 to upper_limit1;
    x3=min(&amp;amp;sum-x1-x1,&amp;amp;max_x);    /*Change the 1st argument of MIN()*/
    x2=&amp;amp;sum-x1-x3;
    do while (x1&amp;lt;=x2 and x2&amp;lt;=x3);  /*Change "&amp;lt;" to "&amp;lt;=")*/
      put (x1 x2 x3) (+2 z2.);
      x3=x3-1;
      x2=x2+1;
    end;
  end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;This is more "efficient" in that it never generates non-qualifying triples that would have to be filtered ot.&amp;nbsp; But I think it would be harder to generalize to more than 3 summands compared to most of the other suggestions.&lt;/P&gt;</description>
      <pubDate>Thu, 24 Dec 2020 20:30:39 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/708133#M217553</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2020-12-24T20:30:39Z</dc:date>
    </item>
    <item>
      <title>Re: Summing to a target value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/708439#M217717</link>
      <description>&lt;P&gt;I did not use recursion, only one do loop surprisingly.&amp;nbsp; I think it would be handled better with recursion in C, because of array pointers, based on my own experience.&amp;nbsp; I do this kind of thing, on paper by hand, so much when I play my favorite logic puzzles.&amp;nbsp; It was fun and frustrating too.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;(Thanks for all the other submissions.)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want (keep=a01-a10);
  array a[0:10] a00-a10;
  array sum[0:10] s00-s10;
  x=1;
  a[0]=0;
  a[x]=a[x-1];
  sum[0]=0;
  goal=20;
  do while (a[x]&amp;lt;10 and x&amp;gt;0); a[x]+1;
    Sum[x]=sum[x-1]+a[x];
    Just_right=sum[x]=goal;
    If Just_right 
      then output;
    GoToNext = sum[x]&amp;gt;=goal or x&amp;gt;9 or a[x]&amp;gt;9;
    Promote_up= not GoToNext;
    If GoToNext then do;
      a[x]=.;
      sum[x]=.;
      x=x-1;/*demote index*/
      end;
    if Promote_up then do; /*Promote up index*/
      x=x+1;     
      a[x]=a[x-1];
    end;
  end;
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 28 Dec 2020 15:40:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Summing-to-a-target-value/m-p/708439#M217717</guid>
      <dc:creator>PhilC</dc:creator>
      <dc:date>2020-12-28T15:40:51Z</dc:date>
    </item>
  </channel>
</rss>

