14

Could you please help me with this puzzle that I am not able to find a nice answer to!!

There are 49 cars which race at unique speeds. Also there is a race track in which at maximum 7 cars can be raced together. We need to find the 25th fastest car in the group. We don't have a stop watch to measure time (so we can only measure the relative speed of each car w.r.t the 6 other cars in a race). What is the least number of races that would be needed?

I. J. Kennedy
  • 24,725
  • 16
  • 62
  • 87
Santhosh
  • 6,547
  • 15
  • 56
  • 63
  • Are you asking us to do this or are you the one who needs help doing this? – BoltClock Nov 02 '10 at 06:10
  • You tags are misleading - Algorithm, data structures and in your question you are asking for an answer to the puzzle. what do you want? – pavanred Nov 02 '10 at 06:38
  • @pavanred, using Algorithms and DS, I want an answer to a puzzle (henceforth the 3 tags) – Santhosh Nov 02 '10 at 06:44
  • Are you asking "What is the least number of races that would be needed?" in the best case, or in the worst (general) case? – Dr. belisarius Nov 02 '10 at 09:53
  • @belisarius, Sorry I did not mention; It is the worst case that I am interested in. And anyways, how would one differentiate between these in this scenario? – Santhosh Nov 03 '10 at 06:43
  • @Santosh The best case is when the cars are sorted. You are done with seven races. – Dr. belisarius Nov 03 '10 at 11:49
  • 1
    @belisarius: the lower bound is strictly greater than 7 races. You need to race all cars to know what their relative speed is and the least you can do that in is 7, but then you have 7 disjoint sets with no relative information. Anyway, sorted has no relevant meaning in this context. You have 49 cars, they don't have numbers assigned, any order you assign them is your own. – JPvdMerwe Nov 03 '10 at 15:14
  • @JPvdMerwe yep, you're right. – Dr. belisarius Nov 03 '10 at 15:36
  • If they were already sorted by speed, best and worse case would be 0 races. – ypercubeᵀᴹ Mar 05 '11 at 00:34
  • @Santosh: You posted this puzzle a while ago, but do you have any more information about it? – Tom Sirgedas Mar 08 '11 at 23:12
  • Question: Will each car's speed be the same across different races? i.e. if Car1 is on Race-1 and Race-2 will its speed be the same? I'm not talking about relative speed, Actual speed. I know you said you cannot measure the actual speed. I do not need the value of the actual speed just need to know its its speed remains constant on different races. – Viv Mar 09 '11 at 21:11
  • @Vivek indeed it stays constant troughout the races - otherwise it would be a hell of a problem... – Dunaril Mar 16 '11 at 00:17

6 Answers6

10

Following Dialecticus inspiration. Divide into 7 random groups and race each of them, then race the medians of these groups. This car becomes the pivot and we already know its relation to 30 other cars, directly or indirectly (this is a property of the median of medians). So to place it with resp. the other 18 we need to run 3 races all including the pivot. After the pivoting, we need to recurse on at most 33 cars. Keep going. I ended up with 29 races. Even if you assume that complete sorting is needed, which is not, there is a lower bound at 17 races (a true lower bound will be even lower), which is much less than 29. So I suspect this is not the right answer, but since this has been lacking any solution, here is a suboptimal one. If you look at the research on sorting networks (this problem with races limited to two cars at a time), finding optimal networks is difficult and optimal networks are known only for very small sizes, definitely not up to 49. I am not aware of any research on networks with 7-way comparators.

Maybe an example can help. Let's say number the cars from the slowest to the fastest and arrange them in a 7x7 matrix (arbitrarily, since we don't know speeds until we race them).

     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]   34   25   45   43   26   21   13
[2,]   11   24    2   40   14   30   32
[3,]   27   19   29   42    4   17   46
[4,]   15   10   39   33    1    9    5
[5,]   28   18   41    8   23   20    6
[6,]   16    3   38    7   12   22   36
[7,]   31   44   48   35   49   37   47

Then let's race each of the columns and sort them according to the outcome of the race:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]   11    3    2    7    1    9    5
[2,]   15   10   29    8    4   17    6
[3,]   16   18   38   33   12   20   13
[4,]   27   19   39   35   14   21   32
[5,]   28   24   41   40   23   22   36
[6,]   31   25   45   42   26   30   46
[7,]   34   44   48   43   49   37   47

Now let's race row #4 (medians) and rearrange the columns according to the outcome

     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    1    3    9   11    5    7    2
[2,]    4   10   17   15    6    8   29
[3,]   12   18   20   16   13   33   38
[4,]   14   19   21   27   32   35   39
[5,]   23   24   22   28   36   40   41
[6,]   26   25   30   31   46   42   45
[7,]   49   44   37   34   47   43   48

Now observe that the median of medians (element [4,4]) is faster than any car above and left and slower than any car below and right (this is a property of the median of medians). For the other cars (lower left and upper right) we don't know, so we need to race them against [4,4], 6 at a time (3 races). Now we observe that 26 cars are slower than [4,4] and therefore the median must be one of those. No need to race any of the others any further. Now repeat the process with those 26 cars.

piccolbo
  • 1,305
  • 7
  • 17
  • 1
    The problem with this solution is that even after 8 comparisons, you still don't have a clue about the median of medians' position within the set... because the only quadrant you can safely discard is the lower right one – Yanick Rochon Mar 06 '11 at 17:41
10

I have a solution that requires only 17 races.

First, though, let me explain a simple solution that requires 32 races. Divide the cars into 7 groups of 7, and race each group (7 races). Repeat 25 times: Pick the fastest remaining car from each group and enter it into a race, and set aside the winner (25 races). The first of the 25 races determines the fastest overall car (#1), the second race determines #2, and so on.

Now a solution with only 17 races:

Our strategy will be to first identify the 24 fastest cars (let's call these cars "speedy"). Then we'll find the fastest of the rest (#25).

Randomly place the cars on a 7x7 grid, and race each row (7 races). Then, race the 3rd place finishers from each race (8th race), and sort the rows by the 3rd place finisher speeds.

So, after 8 races we have this:

enter image description here

Each grid cell represents a car. An arrow points to the faster car. Note that the arrow is transitive.

Already we can identify 8 "speedy" cars:

enter image description here

How do we know they are speedy? Take a look at the blue 'x'. Only 23 cars are possibly faster than it (those not in the bottom-right 5x5). So, it is certainly "speedy". You can verify this for the other x's.

We have identified 8 of the 24 "speedy" cars. Let's remove these 8 from future consideration. We are now looking for the fastest 16 of the remaining cars. Our seven groups have sizes 4,4,5,7,7,7, and 7. (For the diagrams, whenever we remove a car, let's slide the remaining cars in the row to the left.)

Let's race the 2nd fastest remaining car of each group, and sort the rows accordingly (9th race). As before, we can identify 4 cars which are certainly among the 16 fastest (i.e. "speedy"):

enter image description here

I colored in the cells where the removed cars might be, but this has no effect yet.
We have identified 12 "speedy" cars. Remove the "speedy" cars, and we look for the fastest 12 of the remaining cars. Our groups have sizes between 2 and 7. Let's race the 2nd fastest remaining car of each group, and sort the rows accordingly (10th race). We identify 2 cars which are among the 12 fastest (i.e. "speedy"):

enter image description here (10 "speedy" cars remain.)

We can repeat the previous step twice more (11th and 12th races). Each time we remove 2 more cars. However, note that a row/group might have 0 or 1 cars in it. If it has 1 car in it, we race that car instead of "the 2nd fastest remaining". If that car wins, we know that it is "speedy", as well as the next fastest 2nd place car. In any case we identify 2 "speedy" cars. (6 "speedy" cars remain.)

After 12 races we have identified and removed 18 "speedy" cars. We need to identify the remaining 6 "speedy" cars.

Now let's simply race the fastest remaining car in each group (13th race), and sort the rows accordingly. The winner is "speedy". 5 left.

After that last race, there are only 2 cars which could be the fastest remaining car. The blue o's:

enter image description here

Additionally, the 2nd fastest remaining car is either a blue 'o' or green 'o'. Let's race these 5 cars (14th race), and the top two finishers are certainly "speedy". 3 left.

Let's repeat the last two steps/races to identify the last 3 speedy cars (15th and 16th race).

So, we have identified 24 "speedy" cars. The fastest remaining car must be the 25th fastest. We can find this car by simply racing the fastest car in each row/group (17th race).

Tom Sirgedas
  • 3,208
  • 20
  • 17
  • I like it very much ! Although I cannot be certain that it is working in every case. A few questions : What do you do in the 7 last races when there are not enough cars in the top rows ? For exemple if a row is empty, or has less than the appropriate number of cars in the races 14 and 16 ? Besides, how did you get to this solution ? It seems optimal in the sense that you don't race twice two cars together, and you don't get more info than you need. But is there a proof that 17 is a lower bound? – Dunaril Mar 10 '11 at 00:44
  • If a row is empty, just remove it from the grid. In races 14 and 16, if some o's are missing, just omit them from the race. The 2 fastest will still be among the o's that are present. After finding the "simple solution" with 32 races, it was clear I could do better! I would be shocked if 17 is optimal. Three of my races identify only one car. – Tom Sirgedas Mar 10 '11 at 01:02
  • This looks promising... I'm no mathematician, but this question has been bugging me. Now I'm going to have to try and script this to see if it works, and when :) – Benjol Mar 10 '11 at 06:16
  • @Tom I tried your solution several times, it works and rocks :) The bounty is yours. Thank you! – Dunaril Mar 10 '11 at 08:24
  • @Tom, doesn't look like you'll be a F# man, but if you care to [take a look](https://gist.github.com/863751), I've tried to implement this to test it. It's not looking good from around race 14, I think because I'm not correctly understanding you. (If you scroll down, there is an example output) – Benjol Mar 10 '11 at 08:30
  • @Benjol it is because you only repeat the 5-car race. You must repeat the two last races (13th and 14th), that is, first sort the rows by their first column and **then** race the 5 cars of the two top-left diagonals. Nice job though :) – Dunaril Mar 10 '11 at 10:14
  • @Dunaril. Arrgh! Why did you answer? There was me thinking I might get some real work done :) – Benjol Mar 10 '11 at 10:24
  • @Dunaril, @Tom. V2 done. It doesn't work in very rare cases (scroll to bottom to see an example) – Benjol Mar 10 '11 at 11:06
  • @Dunaril: cool, thanks, fun problem! @Benjol: You end up with 26 cars, instead of 25. After race 12, you needed to remove 2 cars (20 and 22). (A slightly simpler alternative: if the first row contains just 1 car, remove it and the first car in the next row.) That's cool that you implemented it! – Tom Sirgedas Mar 10 '11 at 16:27
  • @Dunaril, @Tom. Last (I hope) iteration, modified per Tom's comment. With the same test case (now working) at the bottom. – Benjol Mar 11 '11 at 07:43
7

Try one of these algorithms

http://en.wikipedia.org/wiki/Quick_select

Kevin Burke
  • 61,194
  • 76
  • 188
  • 305
  • I am not able to find an application of this algorithm to my question; Because my input set is not all the 49 cars at the same time (but rather i can only race 7 cars at a single time and know their relative positions); If you could elaborate more it will be helpful. – Santhosh Nov 02 '10 at 09:44
  • Find "Median of Medians algorithm" and replace number 5 in text with number 7 in your case. – Dialecticus Nov 02 '10 at 10:17
  • Median of medians doesn't work for the cases where the 25th fastest car is not the 4th fastest in its 7-car set. – rettvest Nov 04 '10 at 10:03
  • @Dialecticus, great idea, but it should be an answer. – piccolbo Nov 04 '10 at 16:03
  • @piccolbo, It's just an idea and not the complete answer. I don't really know how to implement the solution. – Dialecticus Nov 04 '10 at 16:13
  • @Dialecticus, that was a honest answer. – piccolbo Nov 05 '10 at 05:46
6

http://www.sureinterview.com/shwqst/1062001

Round one

  1. (7 races) Divide the cars into 7 groups and get the order within each group.
  2. (1 race) Take the 7 medians and get the order. Find the median of medians (denote as o). In following example, it is 34.
  3. (3 races) Find the rank of the median of medians. Take 6 elements from lower-left corner (25 ~ 33) and upper-right corner (13 ~ 21) and race against the o (34). After 3 rounds, we know the rank of this median of medians within in the whole set. The best case is that o is the global median (25th fastest). The worst case is that o is the 16th or 34th fastest.

This example shows one possible worst case.

1   2   3   4   13  14  15  <- group 1
5   6   7   8   16  17  18 
9   10  11  12  19  20  21     ...
22  23  24  34  35  36  37
25  26  27  38  39  40  41  <- group 5
28  29  30  42  43  44  45  <- group 6
31  32  33  46  47  48  49  <- group 7

Round two

We want to find the rank of other medians in a binary search fashion.

  1. (3 races) Pick the median less than 34, which is 12. Race it against the lower-left and upper-right corner cars. After 3 races, we know its rank is 12.

Now, the gap between those two medians are at most 21, as shown in this example.

Round three

Rearrange the 21 cars (>12 and <34) as follows.

13  14  15  <- group 1
16  17  18 
19  20  21     ...
22  23  24
25  26  27  <- group 5
28  29  30  <- group 6
31  32  33  <- group 7

Each row is still sorted.

  1. (1 race) Find the median of medians again, which is 23.
  2. (1 race) Find its rank. After this step, we know the car in previous step is ranked 23 for sure.
  3. (1 race) Similar to a binary search, check the rank of another median, 29.
  4. (1 race) Sort all cars between 23 ~ 29 (exclusive). The 25th fastest car is found.

So at most 18 races are needed to get the 25th fastest car.

SureInterview
  • 131
  • 1
  • 1
  • Good approach! Though, let's say after determining 'o' is 34th, you find the median 'above' it is 28th (instead of 12th). Can you still locate the 25th in only 18 races? Without more logic, I think you actually need 21 races. In round 2, you mention "We want to find the rank of other medians in a binary search fashion", but you find 12 instead of 8. Also, this algorithm is very good, but probably not optimal. It's a very interesting problem! – Tom Sirgedas Mar 07 '11 at 18:41
  • Hmm, the worst case of this method is actually like `1 2 3 21 22 23 24 <- group 1` `4 5 6 26 27 28 29 ` `7 8 9 30 31 32 33 ...` `10 11 12 34 35 36 37` `13 14 15 38 39 40 41 <- group 5` `16 17 18 42 43 44 45 <- group 6` `19 20 25 46 47 48 49 <- group 7` Note that after the first round (34 was found), the lower-left and upper-right are also sorted column-wise. This information can help reduce number of race. – SureInterview Mar 08 '11 at 04:27
0

Can't you iteratively divide the pool by determining the exact position of a car?

Pick a car at random to pivot by Run through each of the other 48 cars, racing them in groups of 6 against the pivot car You know now the pivot car's exact position.

Now run the same process on the portion of the set that you know to include position 25 in it. If you have less than seven elements in the remaining partition, it is simple to determine.

The worst case performance of this is truly horrendous, but could be mitigated by picking successive pivots in some semi-intelligent way.

argentage
  • 2,758
  • 1
  • 19
  • 28
0

You can always solve it in 8 races... Lets take a Pivot Car say Car1 and race it with all other cars in 8 races and take the relative speed of other cars wrt Car1. lets say the result is given below: Read Car#(Relative speed to Car1)


Race 1: Car1-(0), Car2-(+10), Car3(+5), Car4(+7), Car5(-3), Car6(-4), Car7(+1)

Race 2: Car1-(0), Car8-(+10), Car9(+5), Car10(+7), Car11(-3), Car12(-4), Car13(+1)

Race 3: Car1-(0), Car14-(+11), Car15(+4), Car16(+6), Car17(-4), Car18(-10), Car19(+2)

Race 4: Car1-(0), Car20(+9), Car21(+3), Car22(+5), Car23(-5), Car24(-11), Car25(+3)

Race 5: Car1-(0), Car26-(+8), Car27(+2), Car28(+6), Car29(-6), Car30(-12), Car31(+4)

Race 6: Car1-(0), Car32-(+7), Car33(+1), Car34(+3), Car35(-7), Car36(-13), Car37(+5)

Race 7: Car1-(0), Car38-(+6), Car39(-1), Car40(+2), Car41(-8), Car42(-14), Car43(+6)

Race 8: Car1-(0), Car44-(+5), Car45(-2), Car46(+1), Car47(-9), Car48(-15), Car49(+7)

Since Car1 is the pivot car and the speed of each car is consistent through all the races, we can group all the results togather.

If you sort the relative speed (wrt car1) you can find out the 25th fastest car.

Viv
  • 2,515
  • 2
  • 22
  • 26
  • "We don't have a stop watch to measure time" – Tom Sirgedas Mar 28 '11 at 20:56
  • Its not time... its relative speed which you can measure between the pivot Car (Car1) and other cars. Which is why Car1's relative speed is always 0 since its measured with itself. – Viv Mar 29 '11 at 17:50
  • The races will tell you whether each car is faster or slower than the pivot car, but NOT by how much. (You don't get any numbers back after each race -- just the ranking of the 7 cars) – Tom Sirgedas Mar 29 '11 at 22:33
  • Here is a quote from the Question: "We don't have a stop watch to measure time (so we can only measure the relative speed of each car w.r.t the 6 other cars in a race)." ==> Which implies that we can measure relative speed. – Viv Mar 31 '11 at 14:35