3

To get acquainted with Mathematica's solving functions, I tried to work out a solution to a MinuteMath problem:

There is a list of seven numbers. The average of the first four numbers is 5, and the average of the last four numbers is 8. If the average of all seven numbers is 46/7, then what is the number common to both sets of four numbers?

Of course, this is an excercise that can be solved without computer, but how can I solve this using Mathematica? My first approach

X = Table[Subscript[x, i], {i, 1, 7}];
cond = {
  Mean[Part[X, 1 ;; 4]] == 5,  
  Mean[Part[X, 4 ;; 7]] == 8, 
  Mean[X] == 46/7
};
Solve[cond, Subscript[x, 4]]

returned no solution. My second approach

X = Table[Subscript[x, i], {i, 1, 7}];
rules = {Mean[Part[X, 1 ;; 4]] -> 5,  
   Mean[Part[X, 4 ;; 7]] -> 8, 
   Mean[X] -> 46/7
};
Solve[
  Mean[X] == Mean[Part[X, 1 ;; 4]] 
    + Mean[Part[X, 4 ;; 7]] 
    - Subscript[x, 4] /. rules, 
  Subscript[x, 4]
]

gives a wrong solution (45/7 instead 6). What did I wrong?

Dr. belisarius
  • 60,527
  • 15
  • 115
  • 190
Karsten W.
  • 17,826
  • 11
  • 69
  • 103
  • Ok, there is a problem with the second approach. It should read 7*Mean[X] == 4*Mean[Part[X, 1 ;; 4]] + 4*Mean[Part[X, 4 ;; 7]] - Subscript[x, 4], but this reduces to `True` when applying `rules`... Why is that? – Karsten W. Apr 06 '11 at 12:48
  • Your second approach has 3 serious problems. **1st** the LHS of your rules are quite complicated and in less contrived cases (or if you simplify/expand your equations before applying the rules) they will fail to match anything. **2nd** your equations aren't actually true. Explicitly expand and look at each side and you'll see what's happened. **3rd** When adding equations together you lose information. You lose what the equation differences are. So reducing the problem to a single equation like you have done will never yield the full result. – Simon Apr 08 '11 at 22:31

2 Answers2

6

The first piece of code that you give is fine. The only problem is there is no solution for x_4 alone. If you replace the last line by Solve[cond] then Mathmatica automagically chooses the free variables and you'll get the solution.


I think that a simple/trivial example would make this type problem clear:

In[1]:= Solve[x==1&&y==2,x]
        Solve[x==1&&y==2,{x,y}]
Out[1]= {}
Out[2]= {{x->1,y->2}}

The final output can also be obtained using Solve[x==1&&y==2], where Mma guesses the free variables. This behaviour differs from that of Mathematica 7. In Mathematica 8 a new option for Solve (and related functions) called MaxExtraCondtions was introduced. This allows Solve to give solutions that use the new ConditionalExpression and is intended to make the behaviour of solve more consistent and predictable. Here's how it works in this simple example:

In[3]:= Solve[x==1&&y==2, x, MaxExtraConditions->1]
Out[3]= {{x -> ConditionalExpression[1, y==2]}}

See the above linked to docs for more examples that show why this Option is useful. (Although maybe defaulting to Automatic instead of 0 would be a more pragmatic design choice for the new option...)


Finally, here's your first solution rewritten a little:

In[1]:= X=Array[Symbol["x"<>ToString[#]]&,{7}]
Out[1]= {x1,x2,x3,x4,x5,x6,x7}

In[2]:= cond=Mean[X[[1;;4]]]==5&&Mean[X[[4;;7]]]==8&&Mean[X]==46/7;

In[3]:= Solve[cond]
         x4/.%
Out[3]= {{x1->14-x2-x3,x4->6,x5->26-x6-x7}}
Out[4]= {6}
Simon
  • 14,631
  • 4
  • 41
  • 101
  • Simon, in Mma 7 `Solve[x == 1 && y == 2, x]` yields `{{x -> 1}}` ; has this changed in v8? – Mr.Wizard Apr 07 '11 at 00:32
  • @Mr.Wizard: Yeah - it looks like it has. I thought it was a little strange that `Solve[x == 1 && y == 2, x]` didn't work in Mma8. The behaviour seems a little counter intuitive. Maybe it's unintentional and we should point it out to WRI. – Simon Apr 07 '11 at 00:48
  • @Karsten: @Mr.Wizard: Got a reply from WRI. This was an intentional change in Mma8 that is meant to lead to more predictable behaviour for more complicated examples. There is a new `Option` for `Solve` called `MaxExtraConditions` that controls this behaviour and is defaulted to `0`. See the edit. – Simon Apr 08 '11 at 22:22
4

Perhaps more compact:

Reduce[Mean@Array[f, 4] == 5 && 
       Mean@Array[f, 4, 4] == 8 && 
       Mean@Array[f, 7] == 46/7]
(*
-> f[5] == 26 - f[6] - f[7] && 
   f[4] == 6 && 
   f[1] == 14 - f[2] - f[3]
*)  

Although for clarity, I probably prefer:

Reduce[Sum[f@i, {i, 4}] == 20 && 
       Sum[f@i, {i, 4, 7}] == 32 && 
       Sum[f@i, {i, 7}] == 46]

Edit

Note that I am using function upvalues as vars and not list elements. I prefer this way because:

  • You don't need to initialize the list (Table[Subscript ... in your example`)
  • The resulting expressions are usually less cluttered (No Part[ ;; ], etc)
Dr. belisarius
  • 60,527
  • 15
  • 115
  • 190
  • You guys are quick! How often do you check for new questions? – Mr.Wizard Apr 06 '11 at 12:01
  • @Mr.W: Your comment is only a couple of minutes behind! – Simon Apr 06 '11 at 12:05
  • @Simon I was thinking "oh, a new question, let's see if I can answer it first" but no, two people before me. Don't you guys do anything else? – Mr.Wizard Apr 06 '11 at 12:07
  • @Mr. Well, I am also fond of image processing questions – Dr. belisarius Apr 06 '11 at 12:09
  • @belisarius Is it possible to know how Mma's `Reduce` worked in the case of your solution? It seems like magic. – DavidC Apr 06 '11 at 12:24
  • @David The only difference with the usual Reduce[ ] usage is that I haven't specified vars. I found that Reduce will try to guess every undefined symbol if you enter just equations, but I don't know if that is properly documented. Or perhaps I am missing some other oddity in my solution? – Dr. belisarius Apr 06 '11 at 12:37
  • @David: Solve will do the same thing when not supplied with the variables to solve for. – Simon Apr 06 '11 at 22:40