I saw the Cerebrate solve the first Scripting Games challenge: Pairing off. And immediately thought “I can do that in Haskell too”.
So, here it is.
import Data.List
cards = [(1,7),(0,5),(3,7),(2,7),(2,13)]
countpairs [] = 0
countpairs [a] = 0
countpairs (a:as) = length . filter (((snd a)==) . snd) $ as
pairingOff = sum . map countpairs . tails
And that’s that. Alas, the actual competition only takes Perl, VBScript and PowerShell, so I won’t be submitting this.
4 People had this to say...
I also like the following:
import Data.List (sort, group)
cards :: [(Int, Int)]
cards = [(1,7),(0,5),(3,7),(2,7),(2,13)]
pairs :: [(Int, Int)] -> Int
pairs = sum . map ((`choose` 2) . length) . group . sort . map snd
-- | Binomial coefficient
-- http://en.wikipedia.org/wiki/Binomial_coefficient
choose :: (Integral a) => a -> a -> a
n `choose` k | n >= k && k >= 0 = fac n `div` (fac k * fac (n - k))
| otherwise = 0
fac :: (Num t) => t -> t
fac 0 = 1
fac n = n * fac (n-1)
(’choose’ and ‘fac’ don’t actually belong in this script but should be part of a larger mathematical library.)
Just for reference, here is my python solution
cards = [(1,7),(0,5),(3,7),(2,7),(2,13)]
print sum([(n*(n-1)/2) for n in [[l for _,l in cards].count(x) for x in xrange(1,14)] if n>1])
I have to poke around for functional language ports to the .NET Framework some more. They make the code so much more short and elegant.
Alistair: You might want to look into F#. I haven’t yet, but it’s a seriously functional language, integrated in the .NET Framework. Its development group is backed by some of the Great Minds behind Haskell.
Want your say?