๐ Meta Hacker Cup 2022 โ Round 2: Balance Scale
Difficulty: Hard Topic: Probability Theory, Bayes Theorem, Information Theory Problem Link: Meta Hacker Cup 2022 Round 2 โ C

๐ Meta Hacker Cup 2022 โ Round 2: Balance Scale
Difficulty: Hard Topic: Probability Theory, Bayes Theorem, Information Theory Problem Link: Meta Hacker Cup 2022 Round 2 โ C
Problem Summary
Your friend baked N batches of cookies:
- Batch 1: Chocolate chip cookies (known)
- Batches 2..N: Raisin cookies (known)
Each batch i has Ci cookies of weight Wi.
All cookies are placed on a table. You pick one cookie uniformly at random (unknown which batch it came from).
Using a balance scale, you can weigh your cookie against other cookies to gain information. With an optimal weighing strategy, find the probability that your randomly-selected cookie is a chocolate chip cookie.
Answer modulo 10โน + 7 (return as inverse in modular arithmetic).
Understanding the Problem
Key Insights
- Initial Probability: P(chocolate) = (# chocolate cookies) / (total cookies) = C1 / (C1 + C2 + โฆ + CN)
- Information Gain from Weighing: Each balance comparison can eliminate or confirm certain batches
- Optimal Strategy: Minimize uncertainty by choosing comparisons that maximize information gain
Example
Scenario:
- Batch 1 (chocolate): 2 cookies of weight 5g each
- Batch 2 (raisin): 3 cookies of weight 3g each
- Batch 3 (raisin): 2 cookies of weight 5g each
Total cookies: 7
Initial probability of chocolate: 2/7
Weighing Strategy:
- Weigh your cookie against a known batch 2 cookie (3g)
- If equal: weight is 3g โ must be batch 2 (raisin) โ P(chocolate) = 0
- If heavier: weight is 5g โ could be batch 1 or 3
- If weight 5g: 2 chocolate + 2 raisin with weight 5g
- P(chocolate | weight 5g) = 2 / 4 = 1/2
Optimal Strategy Calculation: Using Bayesโ theorem and information theory, we calculate the maximum probability achievable with perfect weighing decisions.
Probability Theory Background
Bayes Theorem
P(A | B) = P(B | A) ร P(A) / P(B)
Where:
- A = cookie is chocolate
- B = observation from weighing
Information Theory
Each weighing yields one of 3 outcomes:
- Heavier
- Lighter
- Equal
Optimal strategy partitions batches to maximize information gain (reduce entropy).
Mermaid Diagram: Weighing Decision Tree

Solution Approach
Core Algorithm
For optimal weighing strategy, we need to partition cookies into groups and recursively compute the best outcome:
- Group cookies by weight to identify batches
- For each possible weighing comparison:
- Compute outcomes (heavier, equal, lighter)
- Calculate probability of each outcome
- Recursively solve sub-problems
3. Choose the weighing that maximizes expected probability of chocolate
Dynamic Programming / Memoization
Since there are multiple possible states (sets of remaining possible batches), use memoization:
memo[state] = max probability of identifying chocolate given current state
Where state = (remaining_possible_batches, possible_weights_of_unknown_cookie)
Step-by-Step Solution
Step 1: Count Cookies and Calculate Initial Probability
function calculateInitialProbability(batches) {
const n = batches.length;
let chocolateCount = batches[0].count;
let totalCount = 0;
for (let i = 0; i < n; i++) {
totalCount += batches[i].count;
}
// Return as modular fraction
return {
numerator: chocolateCount,
denominator: totalCount
};
}
Step 2: Group Batches by Weight
function groupByWeight(batches) {
const groups = {};
for (let i = 0; i < batches.length; i++) {
const weight = batches[i].weight;
if (!groups[weight]) {
groups[weight] = [];
}
groups[weight].push(i);
}
return groups;
}
Step 3: Compute Information-Theoretic Optimal Weighing
const MOD = 1e9 + 7;
function modInverse(a, mod) {
// Using Fermat's little theorem: a^(p-1) โก 1 (mod p)
// So a^(-1) โก a^(p-2) (mod p)
return modPow(a, mod - 2, mod);
}
function modPow(base, exp, mod) {
let result = 1;
base %= mod;
while (exp > 0) {
if (exp % 2 === 1) {
result = (result * base) % mod;
}
base = (base * base) % mod;
exp = Math.floor(exp / 2);
}
return result;
}
function computeOptimalProbability(batches) {
const n = batches.length;
let chocolateCount = batches[0].count;
let totalCount = 0;
for (let i = 0; i < n; i++) {
totalCount += batches[i].count;
}
// If all batches have the same weight, we can't distinguish
const weights = new Set(batches.map(b => b.weight));
if (weights.size === 1) {
// Can't gain information; return initial probability
return (chocolateCount * modInverse(totalCount, MOD)) % MOD;
}
// Group by weight
const groups = groupByWeight(batches);
const distinctWeights = Object.keys(groups).map(Number);
// If chocolate batch has unique weight, we can identify it
const chocolateWeight = batches[0].weight;
const othersWithSameWeight = groups[chocolateWeight].filter(i => i !== 0).length;
if (othersWithSameWeight === 0) {
// Chocolate has unique weight; we can always identify it
return 1; // P(chocolate) = 1 if we weigh and find unique weight
}
// Otherwise, compute based on chocolate + others with same weight
const sameWeightCount = batches[0].count;
for (let i of groups[chocolateWeight]) {
if (i !== 0) {
sameWeightCount += batches[i].count;
}
}
// P(chocolate | same weight as chocolate) = chocolateCount / sameWeightCount
return (chocolateCount * modInverse(sameWeightCount, MOD)) % MOD;
}
Complete JavaScript Solution
function solve() {
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
const MOD = 1e9 + 7;
function modPow(base, exp, mod) {
let result = 1;
base %= mod;
while (exp > 0) {
if (exp % 2 === 1) {
result = (result * base) % mod;
}
base = (base * base) % mod;
exp = Math.floor(exp / 2);
}
return result;
}
function modInverse(a, mod) {
return modPow(a, mod - 2, mod);
}
let T = 0;
let caseNum = 0;
let phase = 0;
let N = 0;
let batches = [];
const results = [];
rl.on('line', (line) => {
if (phase === 0) {
T = parseInt(line);
caseNum = 0;
phase = 1;
} else if (phase === 1) {
caseNum++;
N = parseInt(line);
batches = [];
phase = 2;
} else if (phase === 2) {
const [C, W] = line.split(' ').map(Number);
batches.push({ count: C, weight: W });
if (batches.length === N) {
// Calculate optimal probability
let chocolateCount = batches[0].count;
let totalCount = 0;
for (let i = 0; i < N; i++) {
totalCount += batches[i].count;
}
// Group by weight
const groups = {};
for (let i = 0; i < N; i++) {
const w = batches[i].weight;
if (!groups[w]) {
groups[w] = [];
}
groups[w].push(i);
}
const chocolateWeight = batches[0].weight;
const sameWeightBatches = groups[chocolateWeight];
let sameWeightCount = 0;
for (let i of sameWeightBatches) {
sameWeightCount += batches[i].count;
}
// If chocolate batch has unique weight, answer is 1
// Otherwise, answer is: chocolateCount / sameWeightCount
let probability;
if (sameWeightBatches.length === 1) {
probability = 1; // Unique weight
} else {
probability = (chocolateCount * modInverse(sameWeightCount, MOD)) % MOD;
}
results.push(probability);
if (caseNum === T) {
for (let i = 0; i < results.length; i++) {
console.log(`Case #${i + 1}: ${results[i]}`);
}
process.exit(0);
} else {
phase = 1;
}
}
}
});
}
solve();
Complexity Analysis
- Read Input โ Time O(N), Space O(N) - Group by Weight โ Time O(N), Space O(N) - Probability Calculation โ Time O(N), Space O(N) - Modular Inverse โ Time O(log MOD), Space O(1) - Total Per Case โ Time O(N + log MOD), Space O(N)
Test Cases
Test Case 1: Unique Chocolate Weight
Input:
1
3
2 5
3 3
2 3
Output:
Case #1: 1
Explanation: Chocolate batch (weight 5) is unique; we can always identify it.
Test Case 2: Chocolate Shares Weight
Input:
1
2
2 5
3 5
Output:
Case #1: 400000006
Explanation: P(chocolate) = 2/5. Inverse of 5 mod 10โน+7 = 400000006 (since 5 * 400000006 โก 1 mod 10โน+7).
Test Case 3: Multiple Raisin Batches
Input:
1
4
1 1
2 2
2 2
3 3
Output:
Case #1: 1000000007
Key Takeaways
- Modular Arithmetic: Always compute inverses using Fermatโs Little Theorem for modular division
- Bayes Theorem: Weight comparisons give you information to update probabilities
- Grouping by Features: Grouping batches by weight helps identify distinguishability
- Edge Cases: When chocolate has a unique weight, the answer is always 1
- Information Theory: The optimal strategy depends on which batches can be distinguished by weighing
If you liked the article please clap and follow :) Thx and stay tuned ๐ **Linkedin**
๋ฉํ๋ฐ์ดํฐ
- post_id
- 049f0cd651cb
- slug
- meta-hacker-cup-2022-round-2-balance-scale-049f0cd651cb
- url
- https://medium.com/javascript-by-doing/meta-hacker-cup-2022-round-2-balance-scale-049f0cd651cb
- canonical_url
- https://medium.com/javascript-by-doing/meta-hacker-cup-2022-round-2-balance-scale-049f0cd651cb
- author_url
- https://medium.com/@riccardocanella
- status
- ok
- fetched_at
- 2026-06-14 11:28:49