# Using results of Reduce

Suppose I have function f:

f[x_, y_] := 50000 + x 30000 + y 35000;


Now I want to find the x and y when f[]<=200000. I use Reduce:

Reduce[f[x, y] <= 200000 && 1 <= x <= 8 && 1 <= y <= 8 , {x,y}, Integers]


The result is:

(x == 1 && y == 1) || (x == 1 && y == 2) || (x == 1 && y == 3) ||
(x == 2 && y == 1) || (x == 2 && y == 2) || (x == 3 && y == 1)


Now I would like to use these results back into f[] but it requires formatting. I use:

results = Reduce[f[x, y] <= 200000 && 1 <= x <= 8 && 1 <= y <= 8,
{x, y},Integers] /.
Or[a__, b__] -> {a, b} /.
And[a_ == c_, b_ == d_] -> {c, d}


And I use:

f[#[], #[]] & /@ results


to get:

{115000, 150000, 185000, 145000, 180000, 175000}


I wonder if this is the right way to do this or if it can be done easier. It seems reduce can generate different (depending on the equations of course) formats of the results and this would mean that for every type of result new rules will be needed. Is this a fact of life?

• @rcollyer Thanks for editing. Still kind of struggling to get it nice.. – Lou Feb 15 '12 at 20:20

You may want to look at the documentation for ToRules. When applied to the output of Reduce you provided, the result is

Sequence[{x -> 1, y -> 1}, {x -> 1, y -> 2}, {x -> 1, y -> 3},
{x -> 2, y -> 1}, {x -> 2, y -> 2}, {x -> 3, y -> 1}]


If you want to substitute this back to f[x,y], put curly braces to turn the sequence into a list and use ReplaceAll:

f[x,y] /. {%}


This will give the desired output {115000, 150000, 185000, 145000, 180000, 175000}.

• +1, I was looking for ToRules and couldn't remember it. – rcollyer Feb 15 '12 at 20:45
• @rcollyer Thanks for editing my answer. I was so excited that I could finally contribute something that it did not occur to me to provide links or use the code block. – Michael Wijaya Feb 15 '12 at 20:57
• Not a problem. It was a nice answer. – rcollyer Feb 15 '12 at 21:10
• ToRules is great. I didn't know that! – Laura K Feb 22 '18 at 0:53

I'd do the following:

res = Reduce[f[x, y] <= 200000 && 1 <= x <= 8 && 1 <= y <= 8, {x, y}, Integers];
vals = Apply[List, res[[All, All, 2]], {0, 1}]
(*
==> {{1, 1}, {1, 2}, {1, 3}, {2, 1}, {2, 2}, {3, 1}}
*)


which uses Part in the form res[[All,All,2]] to get only the numerical values, and then Apply to replace the Or and And in the logical construct with List. For the second part, I'd again use Apply in its second short form:

f @@@ vals

50000 + x*30000 + y*35000 /. FindInstance[50000 + x*30000 + y*35000 < 200000 &&
((x == 1 && y == 1) || (x == 1 && y == 2) || (x == 1 && y == 3) ||
(x == 2 && y == 1) || (x == 2 && y == 2) || (x == 3 && y == 1)), {x, y},
Integers, 6]


(* ==>

{115000, 150000, 185000, 145000, 180000, 175000}

*)

• What about when there are more results? It seems that I first need to know how many results there are. I mean the number 6 at the end. Is it better to use FindInstance for these type of equations? – Lou Feb 15 '12 at 20:35
• You can put 137 or whatever instead of 6. The documentation says: FindInstance[expr,vars,dom,n] will return a shorter list if the total number of instances is less than n. Whether FindInstance is better: I do not know. – Rolf Mertig Feb 16 '12 at 9:09