6 kyu

Identify Ball Bearings

146 of 175Kacarott

Description:

Failure on the factory floor!! One box of 'deluxe' ball-bearings has been mixed in with all the boxes of 'normal' ball-bearings! We need your help to identify the right box!

Information

What you know about the bearings:

  • 'deluxe' ball-bearings weigh exactly 11 grams
  • 'normal' ball-bearings weigh exactly 10 grams
  • Besides weight, both kinds of ball-bearings are identical
  • There are (effectively) infinite bearings in each box
  • Each box contains exclusively one type of bearing (either regular, or 'deluxe')

To help you identify the right box, you also have access to a Super Scale™ which will tell you the exact weight of anything you give it. Unfortunately, getting it ready for each measurement takes a long time, so you only have time to use it once!

Task

Write a function which accepts two arguments:

  • bearings: A list of the bearing types contained in each 'box'. (length between 1 and 200 inclusive)
  • weigh: a function which accepts any number of arguments, returning the total weight of all. Can only be used once!

Your function should identify and return the single 'deluxe' bearing sample from bearings.

Example

def identify_bb(bearings, weigh):
    a, b, c = bearings
    if weigh(a, b) == 20:
        # bearings 'a' and 'b' must both be 10, so 'c' must be deluxe
        return c 
    if weigh(a) == 10: # Error: weigh has already been used!
        return b
    return a
public static Bearing IdentifyBb(Bearing[] bearings, Func<IEnumerable<Bearing>, long> weigh)
{
  Bearing a = bearings[0],
          b = bearings[1],
          c = bearings[2];
  if (weigh(a, b) == 20)
    // bearings 'a' and 'b' must both be 10, so 'c' must be deluxe
    return c;
  if (weigh(a) == 10) // Error: weigh has already been used!
    return b;
  return a;
}
let identify_bearing (bearings: bearing list) (weigh: bearing list -> int): bearing = 
  let a = List.at bearings 0
  and b = List.at bearings 1
  and c = List.at bearings 2
  in if weigh [a; b] = 20 then
    (* bearings 'a' and 'b' must both be 10, so 'c' must be deluxe *)
    c
  else if weigh [a] = 10 then (* Failure: weigh has already been used! *)
    b
  else
    a
identifyBB :: [Bearing] -> ([Bearing] -> IO Int) -> IO Bearing
identifyBB bearings@[a,b,c] weigh = do
  weightAB <- weigh [a,b]
  if weightAB == 20
    then return c
    else do
      weightA <- weight [a] -- Failure: weigh has already been used!
      if weightA == 10
        then return b
        else return a

Note: modules sys and inspect have been disabled.

Try some other riddle kata:

Riddles

More By Author:

Check out these other kata created by Kacarott

Stats:

CreatedOct 21, 2021
PublishedOct 21, 2021
Warriors Trained867
Total Skips16
Total Code Submissions1149
Total Times Completed175
Python Completions146
C# Completions31
OCaml Completions5
Haskell Completions4
Total Stars22
% of votes with a positive feedback rating91% of 60
Total "Very Satisfied" Votes51
Total "Somewhat Satisfied" Votes7
Total "Not Satisfied" Votes2
Total Rank Assessments17
Average Assessed Rank
6 kyu
Highest Assessed Rank
5 kyu
Lowest Assessed Rank
7 kyu
Ad
Contributors
  • Kacarott Avatar
  • Avanta Avatar
  • FArekkusu Avatar
  • hobovsky Avatar
  • tobeannouncd Avatar
  • KayleighWasTaken Avatar
Ad