blob: 855b2666c0636ea4ac401f5ac7da0a9dead53419 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
module Counter(
SenateCounter,
createSenateCounter,
doCount,
getBallot,
getTotal
) where
import qualified Candidate as Typ
import qualified Preferences as Pref
import qualified Criteria as Crit
import qualified CSV as CSV
import qualified Storage as Vec
import qualified System.IO as IO
import qualified File as File
import qualified Control.Monad as Con
import qualified Data.Either.Unwrap as Either
import qualified Data.Maybe as Maybe
import qualified Data.List as List
data SenateCounter = SenateCounter
{ prefData :: Vec.Store
, ballotMap :: Typ.BelowLineBallot
, numBallots :: Int }
createSenateCounter :: FilePath -> Typ.AboveLineBallot -> Typ.BelowLineBallot -> IO SenateCounter
createSenateCounter f a b = do
numLines <- File.countLines f
prefStore <- Vec.createStore numLines (length b)
h <- IO.openFile f IO.ReadMode
let readFunc n p = if (n > numLines) then return p else do
t0 <- IO.hGetLine h
let prefs = parseRawLine a b t0
result = Maybe.fromJust prefs
if (Maybe.isJust prefs)
then Vec.setPrefs prefStore n result >> readFunc (n + 1) (p + 1)
else readFunc (n + 1) p
p <- readFunc 1 0
IO.hClose h
return (SenateCounter prefStore b p)
parseRawLine :: Typ.AboveLineBallot -> Typ.BelowLineBallot -> String -> Maybe [Pref.Preference]
parseRawLine a b input =
let t1 = CSV.parseRecord CSV.defaultSettings (input ++ "\n")
t2 = Maybe.listToMaybe . reverse . Either.fromRight $ t1
t3 = Pref.parsePreferences (length a) (length b) (Maybe.fromJust t2)
t4 = Pref.normalise a b (Either.fromRight t3)
in if (Either.isRight t1 && Maybe.isJust t2 && Either.isRight t3)
then t4
else Nothing
doCount :: SenateCounter -> Crit.Criteria -> IO Int
doCount sen criteria =
let tailFunc n r = if (n > numBallots sen) then return r else do
prefs <- Vec.getPrefs (prefData sen) n
if (Crit.evaluate (ballotMap sen) prefs criteria)
then tailFunc (n + 1) (r + 1)
else tailFunc (n + 1) r
in tailFunc 1 0
getBallot :: SenateCounter -> Typ.BelowLineBallot
getBallot = ballotMap
getTotal :: SenateCounter -> Int
getTotal = numBallots
|