Enigmatic Code

Programming Enigma Puzzles

Enigma 1551: The same chance

From New Scientist #2714, 27th June 2009 [link]

Harry and Tom each had a set of 15 red and six coloured snooker balls. Each of them had a bag, into which he put one or more of the red balls and four or more of the coloured balls from his set. Although Tom put more balls into his bag than Harry put into his bag, each of them calculated that if he picked four balls out of his bag simultaneously at random there was a 1 in X chance that all four would be coloured.

X represents the same number for each of them.

What number?

[enigma1551]

Advertisements

2 responses to “Enigma 1551: The same chance

  1. Jim Randell 13 March 2012 at 7:39 pm

    Here’s my original Perl code. It runs in 9ms.

    use strict;
    
    # 15 red, 6 coloured
    # 1 or more red 4 or more coloured
    
    # probability of drawing 4 coloured is:
    # p = c / (r + c)  *  (c - 1) / (r + c - 1)  *  (c - 2) / (r + c - 2)  *  (c - 3) / (r + c - 3)
    # let x = 1/p
    
    my ($R, $C, $X);
    my %seen = ();
    
    for $R (1..15) {
      for $C (4..6) {
        $X = ($R + $C) * ($R + $C - 1) * ($R + $C - 2) * ($R + $C - 3) /
             ($C * ($C - 1) * ($C - 2) * ($C - 3));
        next unless $X == int($X);
        if ($seen{$X}) {
          my ($r, $c) = @{$seen{$X}};
          if ($r + $c > $R + $C) {
    	print "X=$X [T:R=$r,C=$c H:R=$R,C=$C]\n";
          } elsif ($R + $C > $r + $c) {
    	print "X=$X [T:R=$R,C=$C H:R=$r,C=$c]\n";
          }
        } else {
          $seen{$X} = [ $R, $C ];
        }
      }
    }
    

    Solution: X = 14.

    • Jim Randell 13 March 2012 at 7:40 pm

      This is how I would solve it now in Python. This code runs in 38ms.

      from collections import defaultdict
      from itertools import combinations
      from enigma import irange, printf
      
      seen = defaultdict(list)
      for r in irange(1, 15):
        for c in (4, 5, 6):
          n = (r + c) * (r + c - 1) * (r + c - 2) * (r + c - 3)
          d = c * (c - 1) * (c - 2) * (c - 3)
          (x, y) = divmod(n, d)
          if y: continue
          seen[x].append((r, c))
      
      for (x, v) in seen.items():
        if len(v) < 2: continue
        for s in combinations(v, 2):
          printf("X={x} T:R={s[1][0]},C={s[1][1]} H:R={s[0][0]},C={s[0][1]}", l=sorted(s, key=sum))
      

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: