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$
9
  • $\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$ Feb 25, 2017 at 17:08
  • $\begingroup$ No iteration is needed to solve this problem in Mathematica. $\endgroup$
    – m_goldberg
    Feb 25, 2017 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$ Feb 25, 2017 at 17:13
  • 3
    $\begingroup$ You already got an answer from mikado that doesn't use iteration. $\endgroup$
    – m_goldberg
    Feb 25, 2017 at 17:16
  • $\begingroup$ @m_goldberg if that was not iteration then I don't know what is. $\endgroup$ Feb 25, 2017 at 17:27

5 Answers 5

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$
5
  • 1
    $\begingroup$ Nice. I didn't know we could use rationals in IntegerPartitions $\endgroup$ Feb 25, 2017 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, 2017 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$ Feb 26, 2017 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$ Feb 26, 2017 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, 2017 at 11:49
21
$\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$
5
  • $\begingroup$ man that was fast, and thank you. :) Really appreciate that. $\endgroup$ Feb 25, 2017 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$ Feb 25, 2017 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$ Feb 25, 2017 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, 2017 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$ Feb 25, 2017 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$
2
  • $\begingroup$ I did not understand that solution at all. However it is correct. But how does it work, please explain. $\endgroup$ Feb 25, 2017 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, 2017 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$
2
  • $\begingroup$ Okay, it seams to be working, but where does the 10 in the end come from? I appreciate help. Thank you $\endgroup$ Feb 25, 2017 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, 2017 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$
2
  • 1
    $\begingroup$ thank you that was really nice. by the way do you hate babies? $\endgroup$ Feb 26, 2017 at 8:07
  • 2
    $\begingroup$ @Jawad_Mansoor Terrified $\endgroup$
    – swish
    Feb 26, 2017 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.