summaryrefslogtreecommitdiff
path: root/src/Senate.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Senate.hs')
-rw-r--r--src/Senate.hs52
1 files changed, 46 insertions, 6 deletions
diff --git a/src/Senate.hs b/src/Senate.hs
index 21c8f4b..b3aad8c 100644
--- a/src/Senate.hs
+++ b/src/Senate.hs
@@ -26,6 +26,7 @@ data SenateCounter = SenateCounter { inputData :: FilePath
headerLines = 2
fieldsInRecord = 6
+minAboveTheLine = 1
minBelowTheLine = 6
@@ -92,9 +93,46 @@ tester m tr p =
-- converts a set of above+below-the-line preferences to just below-the-line
normalise :: Typ.UpperMap -> Typ.LowerMap -> Typ.FullPreferences -> Typ.BelowPreferences
normalise a b f =
- if (isValidBelowPreference b (snd f))
- then (snd f)
- else (fromAboveToBelow a (fst f))
+ let na = normaliseAbove (fst f)
+ nb = normaliseBelow (snd f)
+ in if (isValidBelowPreference b nb)
+ then nb
+ else if (isValidAbovePreference a na)
+ then (fromAboveToBelow a na)
+ else [] -- empty preference if both above/below are invalid
+
+
+
+
+-- this needs to be merged with normaliseBelow
+normaliseAbove :: Typ.AbovePreferences -> Typ.AbovePreferences
+normaliseAbove p =
+ let funcTail n r p =
+ let (matches,rest) = List.partition ((== n) . snd) p
+ in if (p == [] || (length matches) /= 1)
+ then r
+ else funcTail (n + 1) ((head matches):r) rest
+ in funcTail 1 [] p
+
+
+
+
+-- this needs to be merged with normaliseAbove
+normaliseBelow :: Typ.BelowPreferences -> Typ.BelowPreferences
+normaliseBelow p =
+ let funcTail n r p =
+ let (matches,rest) = List.partition ((== n) . snd) p
+ in if (p == [] || (length matches) /= 1)
+ then r
+ else funcTail (n + 1) ((head matches):r) rest
+ in funcTail 1 [] p
+
+
+
+
+isValidAbovePreference :: Typ.UpperMap -> Typ.AbovePreferences -> Bool
+isValidAbovePreference a p =
+ (((length a) < minAboveTheLine) && ((length a) == (length p))) || ((length p) >= minAboveTheLine)
@@ -123,7 +161,8 @@ fromAboveToBelow a p =
-- the two int arguments are the number of boxes above the line and the number
-- of boxes below the line respectively
parsePreferences :: Int -> Int -> String -> Either Parsec.ParseError Typ.FullPreferences
-parsePreferences a b input = Parsec.parse (preference a b) "error" (input ++ ",")
+parsePreferences aboveBoxes belowBoxes input =
+ Parsec.parse (preference aboveBoxes belowBoxes) "error" input
preference a b = do
@@ -139,7 +178,7 @@ preference a b = do
rank = do
n <- Parsec.choice [normalRank, weirdRank, nullRank]
- Parsec.char ','
+ Parsec.choice [Parsec.char ',' >> return (), Parsec.eof]
return n
@@ -149,11 +188,12 @@ normalRank = do
return (n:ns)
--- currently assuming that these symbols always mean '1'
+-- these symbols are taken to mean '1' according to AEC guidelines
weirdRank = do
Parsec.choice [Parsec.char '/', Parsec.char '*']
return "1"
+-- these ranks are standins that will be filtered out
nullRank = return "-1"