summaryrefslogtreecommitdiff
path: root/src/Counter.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Counter.hs')
-rw-r--r--src/Counter.hs72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/Counter.hs b/src/Counter.hs
new file mode 100644
index 0000000..6646133
--- /dev/null
+++ b/src/Counter.hs
@@ -0,0 +1,72 @@
+module Counter(
+ SenateCounter,
+
+ createSenateCounter,
+ doCount
+ ) where
+
+
+
+
+import qualified Candidate as Typ
+import qualified Preferences as Pref
+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
+ arrayData <- 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 t1 = CSV.parseRecord CSV.defaultSettings t0
+ 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)
+ t5 = Maybe.fromJust t4
+ if (Either.isRight t1) && (Maybe.isJust t2) && (Either.isRight t3) && (Maybe.isJust t4)
+ then mapM_ (Vec.setPref arrayData n) t5 >> readFunc (n + 1) (p + 1)
+ else readFunc (n + 1) p
+ p <- readFunc 1 0
+ IO.hClose h
+ --
+ return (SenateCounter arrayData b p)
+
+
+
+
+doCount :: SenateCounter -> Typ.Criteria -> IO Int
+doCount sen criteria = do
+ --
+ let isValidCriteria = all (\(x,y) -> y `List.elem` (ballotMap sen)) criteria
+ --
+ let critToPref (a,b) = (Maybe.fromJust (List.elemIndex b (ballotMap sen)) + 1, a)
+ neededPrefs = map critToPref criteria
+ checkFunc n r = if (n > (numBallots sen)) then return r else do
+ t <- Con.liftM and (mapM (Vec.checkPref (prefData sen) n) neededPrefs)
+ if t then checkFunc (n + 1) (r + 1) else checkFunc (n + 1) r
+ --
+ if isValidCriteria
+ then checkFunc 1 0
+ else return 0
+
+