diff options
Diffstat (limited to 'src/Counter.hs')
-rw-r--r-- | src/Counter.hs | 72 |
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 + + |