Programming Praxis – House Of Representatives

In today’s Programming Praxis exercise, our goal is to calculate the amount of seats each state gets in the United States House of Representatives. Let’s get started, shall we?

Some imports:

import Control.Arrow
import qualified Data.List.Key as K
import qualified Data.Map as M

To calculate the seat distribution we need the population data for each state.

popData :: M.Map String Integer
popData = M.fromList [("Alabama",4779736), ("Alaska",710231),
  ("Arizona",6392017), ("Arkansas",2915918), ("California",37253956),
  ("Colorado",5029196), ("Connecticut",3574097), ("Delaware",897934),
  ("Florida",18801310), ("Georgia",9687653), ("Hawaii",1360301),
  ("Idaho",1567582), ("Illinois",12830632), ("Indiana",6483802),
  ("Iowa",3046355), ("Kansas",2853118), ("Kentucky",4339367),
  ("Louisiana",4533372), ("Maine",1328361), ("Maryland",5773552),
  ("Massachusetts",6547629), ("Michigan",9883640), ("Minnesota",5303925),
  ("Mississippi",2967297), ("Missouri",5988927), ("Montana",989415),
  ("Nebraska",1826341), ("Nevada",2700551), ("New Hampshire",1316470),
  ("New Jersey",8791894), ("New Mexico",2059179), ("New York",19378102),
  ("North Carolina",9535483), ("North Dakota",672591), ("Ohio",11536504),
  ("Oklahoma",3751351), ("Oregon",3831074), ("Pennsylvania",12702379),
  ("Rhode Island",1052567), ("South Carolina",4625364), ("South Dakota",814180),
  ("Tennessee",6346105), ("Texas",25145561), ("Utah",2763885),
  ("Vermont",625741), ("Virginia",8001024), ("Washington",6724540),
  ("West Virginia",1852994), ("Wisconsin",5686986), ("Wyoming",563626)]

The algorithm itself is fairly simple. Start with one seat per state and then keep assigning one seat to the state with the highest geometric mean until the desired number of seats is reached.

house :: Int -> M.Map String Integer
house seats = fst $ iterate add ( ((,) 1) popData) !! k where
    add m = M.adjust (first succ) (maxMean m) m
    maxMean = fst . K.maximum (uncurry g . snd) . M.toList
    g n p = f p / sqrt (f n * (f n + 1)) where f = fromIntegral
    k = seats - M.size popData + 1

Some tests to see if everything is working properly:

main :: IO ()
main = do print $ house 435 M.! "California" == 53
          print $ house 435 M.! "Kentucky" == 6
          print $ house 435 M.! "Wyoming" == 1
          print . K.sort (negate . snd) . M.toList $ house 435

Tags: , , , , , , , , ,

Leave a Reply

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

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

Google photo

You are commenting using your Google 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 )

Connecting to %s

%d bloggers like this: