There are classical “12 Marbles riddle” that goes like this,
“You have 12 marbles and a balance scale. One of the 12 marbles is inconsistent with the others, meaning it could be heavier or lighter than its peers of normal weight. You are allowed to use the seesaw exactly 3 times to identify which of the 12 marbles is irregular AND determine whether it is heavier or lighter than normal.”
The solution is as following steps,
For ease of explanation, I will call those 12 marbles Marble 1, Marble 2… Marble 12.
We start with 12 marbles and divide them into 3 groups, which each group has 4 marbles respectively.
Group A: Marbles 1-4
Group B: Marbles 5-8
Group C: Marbles 9-12
Then I will weigh Group A against Group B using a seesaw, let Group C alone. This is the first time weighing using the seesaw.
There will be 2 outcomes, the seesaw either balance (which suggest both groups of marbles share the same weight), or the seesaw skew to left or right (which suggest either group of marbles is heavier or lighter)
Outcome 1: Seesaw is balanced
So this means Group A and B (Marbles 1-8) share normal marbles, and the anomaly marble resides in Group C (Marbles 9-12).
2. Now, we weigh 3 marbles (Marbles 9-11) from Group C, against any of 3 normal marbles from Group A or Group B. This is the second time weighing using the seesaw. There will have 2 possible outcomes that will occur.
Outcome 1 Sub Outcome A: Seesaw is balanced
3. This means marble 9-11 is also a normal marble, now we can confirm Marble 12 is anomaly marble. We weigh again Marble 12 with any other normal marble, this is the third time of weighing using the seesaw. From the result, we can tell the anomaly marble is heavier or lighter than other marbles.
Outcome 1 Sub Outcome B: Seesaw skewed to left or right
3. This means marble 9-11 is either heavier or lighter than other marbles (based on the seesaw skewing direction). Then we weight either two marbles from marble 9-11, this is the third time of weighing using the seesaw. If the seesaw result is not balanced, then we can tell which one is heavier/lighter, else if the seesaw is balanced, the remaining marble is heavier/lighter.
Outcome 2: Seesaw skewed to left or right
In this outcome, this means Group C (Marbles 9-12) are normal marbles and the anomaly marble in either Group A or B (Marbles 1-8).
For simplicity of explanation, I assume Group A is heavier than Group B (the logic is vice versa if the outcome is otherwise), so this means Marbles 1-4 are heavier than Marbles 5-8. But we still cannot tell whether the anomaly marble is heavier or lighter.
2. Now, we weigh 3 marbles from Group B (maybe lighter)+ 1 marble from Group A (maybe heavier) against, 1 marble from Group B (maybe lighter)+ 3 normal marble from Group C. The marble arrangement in the seesaw will look like this
(Marble 5, 6, 7, 1 ) vs (Marble 9, 10, 11, 8), this is the second time of weighing using the seesaw. There will have 3 possible outcomes that will occur.
Outcome 2 Sub Outcome A: Seesaw is skewed to left
3. This means either marble 1 is heavier, or marble 8 is lighter. We can tell by weighing either marble 1 or 8 with anyone normal marble. This is the third time weighing using the seesaw. If the seesaw result is balanced, we can tell another marble is heavier or lighter, if the seesaw result is not balanced against normal marble, then we can tell the anomaly marble is heavier or lighter.
Outcome 2 Sub Outcome B: Seesaw is skewed to the right
3. This means the marbles 5,6 or 7 is anomaly marble and it is lighter. So weigh either two of these marbles, let say weigh marble 5 against 6. This is the third time weighing using the seesaw. If the seesaw result is balanced, the remaining marble is the anomaly, else, based on the seesaw result, we can tell which one is lighter.
Outcome 2 Sub Outcome C: Seesaw is balanced
3. This means the 3 marbles from maybe heavier category (marbles 2,3 and 4) contain anomaly marble, and it is heavier. Repeat the above steps, weigh either two of these marbles, then we can tell which marble is heavier. This is the third time weighing using the seesaw.
The C# console of 12 marbles riddle solutions will look like this: I will display the anomaly marble (for verify), and display the logic of each step, and get the conclusion to determine the anomaly marble.
Class of Marble and properties,
public class Marble {
public string Id {
get;
set;
}
public double Weight {
get;
set;
}
public bool Anomaly {
get;
set;
} = false;
public string AnomalyMsg {
get;
set;
} = string.Empty;
}
Another class named AllMarbles.cs serves as a collection of marble.
public class AllMarbles {
public AllMarbles() {
Marbles = GenerateMabrles(Marbles);
}
public List < Marble > Marbles {
get;
set;
} = new List < Marble > ();
public int AnomalyMarble {
get;
set;
}
public bool IsHeavier {
get;
set;
}
public override string ToString() {
string compare = IsHeavier ? "heavier" : "lighter";
double Weight = IsHeavier ? 1.5 : 0.5;
return "Anomaly marbe is Marble " + AnomalyMarble + ", weight: " + Weight + ", " + compare + " than other marbles";
}
GenerateMabrles function that randomly generates anomaly marble and which is heavier or lighter.
private List < Marble > GenerateMabrles(List < Marble > Marbles) {
Random ran = new Random();
int anomaly = ran.Next(1, 13); //9;//ran.Next(1, 13);
bool heavier = ran.Next(1, 3) % 2 == 0 ? true : false;
AnomalyMarble = anomaly;
IsHeavier = heavier;
for (int i = 1; i < 13; i++) {
Marble marble = new Marble();
marble.Id = "Marble " + i.ToString();
marble.Weight = 1;
if (i != anomaly) {
Marbles.Add(marble);
continue;
}
marble.Anomaly = true;
if (heavier) marble.Weight += 0.5;
else marble.Weight -= 0.5;
Marbles.Add(marble);
}
return Marbles;
}
The main function, SeeSaw to determine the weight of marbles against marbles
static string Seesaw(List < Marble > marbleLHS, List < Marble > marbleRHS) {
double weightLHS = 0.00;
double weightRHS = 0.00;
string LHS = string.Empty;
string RHS = string.Empty;
LHS = marbleLHS.Aggregate("", (str, s) => str += s.Id + ", ");
RHS = marbleRHS.Aggregate("", (str, s) => str += s.Id + ", ");
Console.WriteLine("Weigh {0} against {1}", LHS, RHS);
foreach(Marble mar in marbleLHS)
weightLHS += mar.Weight;
foreach(Marble mar in marbleRHS)
weightRHS += mar.Weight;
if (weightLHS > weightRHS) {
Console.WriteLine("Seesaw result: {0} heavier than {1} ", LHS, RHS);
return "L";
} else if (weightRHS > weightLHS) {
Console.WriteLine("Seesaw result: {0} heavier than {1} ", RHS, LHS);
return "R";
} else {
Console.WriteLine("Seesaw result: {0} and {1} share the same weight", RHS, LHS);
return "M";
}
}
This is the code snippet in decide which branch to go, and each step not only returns the decision of which branch to go but also will decide whether the anomaly marble is heavier or lighter by variable “is heavier”.
//Step 1
(nextStep, maybeHeavierMarbles, maybeLighterMarbles, normalMarbles) = StepOne(marbleLHS, marbleRHS, marbleLeftout);
bool isHeavier = false;
Console.WriteLine();
//Step 2
List < Marble > oddMarbles = new List < Marble > ();
switch (nextStep) {
case "StepTwoSubA":
(nextStep, isHeavier) = StepTwo_SubA(marbleLeftout, normalMarbles);
break;
case "StepTwoSubB_BranchA":
(nextStep, isHeavier, oddMarbles) = StepTwoSubB_BranchA(maybeHeavierMarbles, maybeLighterMarbles, marbleLeftout);
break;
default:
break;
}
Console.WriteLine();
//Step 3
switch (nextStep) {
Variable “isHeavier” will result in different marble being chosen as an anomaly.
if (seesawResult == "L") {
if (isHeavier) {
suspiciousMarble9.Anomaly = true;
suspiciousMarble9.AnomalyMsg = "Heavier";
return suspiciousMarble9;
} else {
suspiciousMarble10.Anomaly = true;
suspiciousMarble10.AnomalyMsg = "Lighter";
return suspiciousMarble10;
}
}
Full source code can be download from my Github.
Reference: Prep with Jen LLC: Can you solve this classic brain teaser?