A blog about my nerdy stuff. 0x3a29

Friday, August 21, 2009

Combinatorics are tricky

One of these days I was helping a friend of mine with a relatively simple Combinatorics problem. It goes like this: using the digits from 0 to 9, how many 4-digits natural numbers we can write? There may be repetition of digits, but only if they aren't adjacent: 2424 is a valid number, but 2244 isn't.

The way I solved it was something like this:
  • The first digit may be any digit (except 0 or it'll be a 3-digits number actually), so there are 9 possibilities.
  • The forth digit may be any digit, so there are 10 possibilities.
  • The second number may be any digit, except the first one, so there are 9 possibilities.
  • The third number may be any digit, except the second and the fourth, so there are 8 possibilities.

Multiplying it all, we have: 9 × 9 × 8 × 10 = 6480.

According to the book my friend was reading, the answer was 6561, but there wasn't an explanation of why. I suspect the author of the book did something like this:
  • The first digit may be any digit, except 0.
  • The second digit may be any digit, except the previous.
  • The third digit may be any digit, except the previous.
  • The fourth digit may be any digit, except the previous.

This way of thinking will yield 9^4 = 6561 and it also seems to be correct. In the doubt of who was right, I did a little Haskell program to check the answer: given the numbers from 1000 to 9999, filter the ones that have adjacent numbers equal and print the length of the list.

module Main
where

import System.IO

num = [1000..9999]

main = putStrLn $ show $ length $ filter (adjp) num

adjp n = if fd == sd then False
else
if sd == td then False
else
if td == fd then False
else True
where
fd = (mod n 10)
sd = (mod (div n 10) 10)
td = (mod (div n 100) 10)
ft = (mod (div n 1000) 10)

I don't like the nested ifs and elses, there must be a more elegant way of writing this, but I wrote it quickly and it works, so whatever. If you run it, it will print 6480, meaning that I was correct, but the other way of solving it also seems reasonable, so why it's wrong?

2 comments:

  1. Hi, I just wandered here from Google, looking for a hint on another type of combin. problem, and was intrigued by this puzzle.

    I believe the solution is 6561, per the logic presented above. Selecting the first and last digits and restricting the third digit to eight possibilities causes the undercount, brcause when the second digit == fourth digit, you have 9, not 8 choices for the third, e.g. 2424.

    I don't know Haskell, but it appears you reused variable fd where you intended ft, which had the evil effect of "confirming" your error.

    I look forward to visiting again.

    ReplyDelete
  2. Much more easier with Python (not sure the code will be indented correctly here):

    --------------------
    sequence_size = 0

    for number in range(1000,9999):
    seq = str(number)
    if seq[0] != seq[1]:
    if seq[1] != seq[2]:
    if seq[2] != seq[3]:
    sequence_size += 1

    print sequence_size
    --------------------

    Yields: 6561

    ReplyDelete