(* flunky *) val path = if (!System.architecture=".hppa") then "/users/staff/sez125/election/" else "/usr/local/etc/ftp/pub/a.cumming/election/"; use (path^"parse.sml"); val allFiles = map (fn s=>path^"1983."^s^".txt") ["01","02","03","04","05", "06","07","08","09","10", "11","12","13","14","15", "16","17"]; fun uniq l = let fun uniq' acc nil = acc | uniq' acc(h::t) = if member acc h then uniq' acc t else uniq' (h::acc) t in uniq' nil l end; (* Find the party which gained most seats in the most recent contest *) fun flunky allFiles = let val allSeats = flatten(map read allFiles) val winners = map (party o hd o hd o rev o snd) allSeats val contenders = uniq winners fun countSeats p = length(filter (member [p]) winners) val psc = map (fn p => (p, countSeats p)) contenders val fl = fst(hd(sort (fn(a,b)=>snd a>snd b) psc)) in fl end; (* Find the name of the MP for constituency number x *) fun MP allFiles x = let val allConstituencies = flatten(map read allFiles) val targetConstituency = nth(allConstituencies,x-1) fun nameOf s = substring(s,24,min(30,size s - 24)) in nameOf(hd(hd(rev(snd targetConstituency)))) end; (* Find the key Tory marginals - Conservative seat where the margin between the winner and the runner up is less than or equal to x *) fun marginal allFiles x = let val allSeats = flatten(map read allFiles) fun isTorySeatP con = (party(hd(hd(rev(snd con))))="C ") fun isMarginalP con = let val contest = hd(rev(snd con)) val winner_votes = votes(hd contest) val runner_up_votes = votes(hd(tl contest)) in winner_votes - runner_up_votes <= x end val targetSeats = filter (fn c => (isTorySeatP c) andalso (isMarginalP c)) allSeats in map fst targetSeats end; (* Redistribute the seats based on popular vote - exclude parties with less than barValue% of the national vote *) fun pr allFiles barValue = let val allSeats = flatten(map read allFiles) val contests = map (hd o rev o snd) allSeats val whoGotWhat = map (fn c => (party c,votes c)) (flatten contests) val contenders = uniq (map fst whoGotWhat) fun voteTot p = (p,sum(map snd(filter (fn(pn,_)=>pn=p)whoGotWhat))) val whoGotWhatCondensed = map voteTot contenders val bar = floor(real(sum(map snd whoGotWhatCondensed))*barValue/100.0) val newContenders = filter (fn(_,v)=> v>=bar) whoGotWhatCondensed val newVoteTot = real(sum(map snd newContenders)) fun redistrib(p,v) = (p,650.0*(real v)/newVoteTot) in filter (fn(_,v)=>v>0.5) (map redistrib newContenders) end; (* Try them out *) flunky allFiles; MP allFiles 568; app print (marginal allFiles 1000); pr allFiles 5.0;