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 = M.map fst $ iterate add (M.map ((,) 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: Haskell, programming, praxis, kata, bonsai, code, house, representatives, united, states