Another Quick Coding Challenge

Friday July 25thChallenges, Functional Programming, Haskell Category

I was about to head to bed when I stumbled across another interesting coding challenge. Since I had another half hour or so to kill I thought I’d give it a shot!

I first found the problem here, but this wasn’t the original source. The challenge was first posted here. The problem is as follows:

Write a counter function that counts from 1 to max but only returns numbers whose digits don’t repeat.

For example, part of the output would be:

* 8, 9, 10, 12 (11 is not valid)
* 98, 102, 103 (99, 100 and 101 are not valid)
* 5432, 5436, 5437 (5433, 5434 and 5435 are not valid)

Also:

* Display the biggest jump (in the sequences above, it’s 4: 98 -> 102)
* Display the total count of numbers
* Give these two values for max=10000

So without further ado, here’s my solution:

import Data.List
 
noDups :: String -> Bool
noDups l = length l == length (nub l)
 
items :: [Int]
items = filter (noDups . show) [1..10000]
 
main :: IO ()
main = print $ (maximum (zipWith (-) (tail items) items), length items)

It’s probably not as concise as it could be, and I’m sure a more experienced Haskeller would be able to tidy it up a little bit. Despite that, it still performs quite well:

Thu Jul 24 21:34 2008 Time and Allocation Profiling Report  (Final)
 
	   main +RTS -p -RTS
 
	total time  =        0.00 secs   (0 ticks @ 20 ms)
	total alloc =   4,121,500 bytes  (excludes profiling overheads)
 
COST CENTRE   MODULE   %time %alloc
 
CAF           Main       0.0  100.0
 
 
                                            individual    inherited
COST CENTRE   MODULE       no.    entries  %time %alloc   %time %alloc
 
MAIN          MAIN           1           0   0.0    0.0     0.0  100.0
 CAF          Main         152          14   0.0  100.0     0.0  100.0
 CAF          GHC.Handle    88           4   0.0    0.0     0.0    0.0

Thoughts? How could I make this better/faster/more elegant? I’m keen to get some insight from a more experienced Haskell coder :) Cheers!

2 Comments

  1. Bill Mill
    July 25, 2008

    My answer in python was the same as commenter “DeWitt” on that site - I was disappointed when he chimed in before me:

    (i for i in xrange(start, end) if len(str(i)) == len(set(str(i))))

  2. OJ
    July 25, 2008

    So that generates the set of numbers right? It doesn’t pick the biggest difference and the number of elements?

    the Haskell equivalent would probably be:

    [ n | n <- [1..1000], length (show n) == length (dup (show n)) ]

Leave a comment

Size

Colors