16
$\begingroup$

I am learning Mathematica because I love it. I also love solving puzzles so I think it would be a nice way to learn Mathematica through puzzles. This is first puzzle in series I intend to solve.

So here is the problem.

  • People = 20
  • Food = 20
  • Restrictions;

    • A man eats 2 units
    • A woman consumes 1.5 units
    • A baby can take only .5 units of food
    • Combined number of men women and babies must equal 20
    • All units of food must be consumed.

There are four possible solutions, I would like to learn

  1. shortest syntax to get a random solution

  2. syntax/program which gives all possible solution

$\endgroup$
  • $\begingroup$ @m_goldberg I disagree with change of tag as it is an iteration problem. i.e. it has less number of equations to solve than the variables, so no matrix solution is possible for them. Only way to solve such problem is through iteration. So iteration tag was best suited here. $\endgroup$ – Jawad_Mansoor Feb 25 '17 at 17:08
  • $\begingroup$ No iteration is needed to solve this problem in Mathematica. $\endgroup$ – m_goldberg Feb 25 '17 at 17:09
  • $\begingroup$ Alright then, if you think you can do that then do it on paper. You will find getting solutions to questions which have less number of equations than variables (which make the equations) is not easy. Because you will have to hit and try to get correct answer Anyway, if you REALLY KNOW that there is a way to solve such kind of puzzles/questions then do tell me I am always eager to learn. $\endgroup$ – Jawad_Mansoor Feb 25 '17 at 17:13
  • 3
    $\begingroup$ You already got an answer from mikado that doesn't use iteration. $\endgroup$ – m_goldberg Feb 25 '17 at 17:16
  • $\begingroup$ @m_goldberg if that was not iteration then I don't know what is. $\endgroup$ – Jawad_Mansoor Feb 25 '17 at 17:27
20
$\begingroup$

We can do this more efficiently using IntegerPartitions:

Counts /@ IntegerPartitions[20, {20}, {1, 3, 4}/2]
{
 <|2 -> 6, 3/2 -> 1, 1/2 -> 13|>,
 <|2 -> 4, 3/2 -> 4, 1/2 -> 12|>,
 <|2 -> 2, 3/2 -> 7, 1/2 -> 11|>,
 <|3/2 -> 10, 1/2 -> 10|>
}

Also as requested code for only one solution:

Counts /@ IntegerPartitions[20, {20}, {1, 3, 4}/2, 1]
{<|2 -> 6, 3/2 -> 1, 1/2 -> 13|>}

This does not generate all and then throw some away; it only generates the one requested.

As a rule when working any problem similar to this I try to apply IntegerPartitions as when it fits it is usually much faster than Solve, Reduce, etc. Some examples:

$\endgroup$
  • 1
    $\begingroup$ Nice. I didn't know we could use rationals in IntegerPartitions $\endgroup$ – Simon Woods Feb 25 '17 at 22:54
  • $\begingroup$ @Mr.Wizard thank you for introducing me to this option of IntegerPartitions. Useful for 'Nickel and Dime' problems...:) $\endgroup$ – ubpdqn Feb 26 '17 at 3:30
  • $\begingroup$ @mr.wizard thank you. I never imagined a community so prolific with genius minds and yet to humble and generous. Thank you all, everybody for participating. I know I need to learn a lot and this is my starting point and I see it is good for many other people as well they are learning too. $\endgroup$ – Jawad_Mansoor Feb 26 '17 at 7:55
  • $\begingroup$ @mr.wizard how do you make hyper links appear like that? They are neat and short. I mean I don't see a full length link like [Link] mathematica.stackexchange.com/questions/22397/… [/Link] Instead of just a few words as you mentioned integerpartitions (off site link) and three on site links. $\endgroup$ – Jawad_Mansoor Feb 26 '17 at 11:43
  • $\begingroup$ @Jawad For the first kind I am using the Ref button added by halirutan's wonderful toolbar extension. The three links at the bottom are auto-formatted by the site software; simply include a bare URL like http://mathematica.stackexchange.com/q/79587/ and it appears as a link with a proper title. Start a line with - to create a "bullet point" as I used for those last three links. $\endgroup$ – Mr.Wizard Feb 26 '17 at 11:49
22
$\begingroup$

Just write the problem literally and use Reduce

Reduce[
 m >= 0 && w >= 0 && b >= 0 && {m, w, b} ∈ Integers && 
  2 m + 3/2 w + 1/2 b == 20 && m + w + b == 20, {m, w, b}]

(* (m == 0 && w == 10 && b == 10) || (m == 2 && w == 7 && b == 11) || 
   (m == 4 && w == 4 && b == 12)  || (m == 6 && w == 1 && b == 13) *)
$\endgroup$
  • $\begingroup$ man that was fast, and thank you. :) Really appreciate that. $\endgroup$ – Jawad_Mansoor Feb 25 '17 at 16:48
  • $\begingroup$ I found these also work 'Reduce[2 m + 3/2 w + 1/2 b == 20 && {m, w, b} [Element] Integers && {m, w, b} >= 0 && m + w + b == 20]' And 'Reduce[2 m + 3/2 + 1/2 b == 20 && w + m + b == 20 && {m, w, b} >= 0, {m, w, b}, Integers]' But since they are based on your code so kudos to you my friend. Also, I just copied the e 'MEMBER' I don't know how to write it. How to write e? $\endgroup$ – Jawad_Mansoor Feb 25 '17 at 17:00
  • $\begingroup$ I don't know how to format code in code format, as you did. Please tell me how to format that also. Thank you $\endgroup$ – Jawad_Mansoor Feb 25 '17 at 17:04
  • 1
    $\begingroup$ @Jawad to format code use backward apostrophes, the top left key of my keyboard, with the tilde (~). $\endgroup$ – Nicholas G Feb 25 '17 at 17:21
  • $\begingroup$ Reduce[2 m + 3/2 w + 1/2 b == 20 && {m, w, b} [Element] Integers && {m, w, b} >= 0 && m + w + b == 20] Reduce[2 m + 3/2 + 1/2 b == 20 && w + m + b == 20 && {m, w, b} >= 0, {m, w, b}, Integers] Thank @NicholasG man $\endgroup$ – Jawad_Mansoor Feb 25 '17 at 17:33
18
$\begingroup$

Another solution:

Select[FrobeniusSolve[{20, 15, 5}, 200], Total[#] == 20 &]

{{0, 10, 10}, {2, 7, 11}, {4, 4, 12}, {6, 1, 13}}

The first element in each list is the number of men, the second element is the number of women, and the third element is the number of babies.

$\endgroup$
  • $\begingroup$ I did not understand that solution at all. However it is correct. But how does it work, please explain. $\endgroup$ – Jawad_Mansoor Feb 25 '17 at 17:29
  • 1
    $\begingroup$ @Jawad_Mansoor You have to read the documentation for FrobeniusSolve as that is the core of the solution. The Select comes from the fact that FrobeniusSolve returns all possible combinations of any number of men, women, and children. Select picks out just those solutions where the total number of people is 20. $\endgroup$ – C. E. Feb 25 '17 at 17:42
10
$\begingroup$

YAW: Yet Another Way.

FindInstance seems created for such tasks:

Let m = number of men, w = number of women, b = number of babies.

FindInstance[{2 m + (3/2) w + (1/2) b == 20, m + w + b == 20, m >= 0, w >= 0, b >= 0}, {m, w, b}, Integers, 10]

(*{{m -> 0, w -> 10, b -> 10}, {m -> 2, w -> 7, b -> 11}, {m -> 4,  w -> 4, b -> 12}, {m -> 6, w -> 1, b -> 13}}*)
$\endgroup$
  • $\begingroup$ Okay, it seams to be working, but where does the 10 in the end come from? I appreciate help. Thank you $\endgroup$ – Jawad_Mansoor Feb 25 '17 at 18:12
  • 2
    $\begingroup$ That tells FindInstance to look for 10 solutions, else it will only look for 1 by default. Remember, the number of solutions was a given. I wanted to be sure that there were no others. $\endgroup$ – bobbym Feb 25 '17 at 18:14
8
$\begingroup$

Not all solutions, but the one that minimizes the number of babies to feed

LinearProgramming[{0, 0, 1}, {{2, 1.5, .5}, {1, 1, 1}}, {{20, 0}, {20, 0}}, 0, Integers]
$\endgroup$
  • 1
    $\begingroup$ thank you that was really nice. by the way do you hate babies? $\endgroup$ – Jawad_Mansoor Feb 26 '17 at 8:07
  • 2
    $\begingroup$ @Jawad_Mansoor Terrified $\endgroup$ – swish Feb 26 '17 at 14:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.