Skip to content

Commit e219c8c

Browse files
author
vaddya
committed
implement democracy task
1 parent e08a3fd commit e219c8c

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

effective/src/main/scala/com/vaddya/fpscala/effective/democracy/MajorityJudgement.scala

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ object Grade:
3131
* - `apply` to select an element at a specific index.
3232
*/
3333
def median(grades: Seq[Grade]): Grade =
34-
???
34+
grades.sortBy(_.ordinal)
35+
.drop(grades.length / 2)
36+
.head
37+
3538
end Grade
3639

3740
/**
@@ -73,14 +76,14 @@ case class Election(description: String, candidates: Set[Candidate]):
7376
// into a single sequence containing the grades assigned to each
7477
// candidate by the voters.
7578
val allGrades: Seq[(Candidate, Grade)] =
76-
???
79+
ballots.flatMap(_.grades.toSeq)
7780

7881
// Second step: use the operation `groupMap` to transform the
7982
// collection of pairs of `(Candidate, Grade)` into a `Map`
8083
// containing all the grades that were assigned to a given
8184
// `Candidate`.
8285
val gradesPerCandidate: Map[Candidate, Seq[Grade]] =
83-
???
86+
allGrades.groupMap(_._1)(_._2)
8487

8588
findWinner(gradesPerCandidate)
8689
end elect
@@ -108,18 +111,21 @@ case class Election(description: String, candidates: Set[Candidate]):
108111
// of grades, and finally use the operation `maxBy` to find the highest
109112
// median grade.
110113
val bestMedianGrade: Grade =
111-
???
114+
gradesPerCandidate.values
115+
.filter(_.nonEmpty)
116+
.map(Grade.median)
117+
.maxBy(_.ordinal)
112118

113119
// Use the operation `filter` to select all the candidates that got the
114120
// same best median grade (as the case may be)
115121
val bestCandidates: Map[Candidate, Seq[Grade]] =
116-
???
122+
gradesPerCandidate.filter((_, grades) => Grade.median(grades) == bestMedianGrade)
117123

118124
// In case only one candidate got the best median grade, it’s the winner!
119125
if bestCandidates.size == 1 then
120126
// Use the operation `head` to retrieve the only element
121127
// of the collection `bestCandidates`
122-
???
128+
bestCandidates.head._1
123129
else
124130
// Otherwise, there is a tie between several candidates. The tie-breaking
125131
// algorithm is the following:
@@ -128,16 +134,16 @@ case class Election(description: String, candidates: Set[Candidate]):
128134
// median grade from each tied candidate's total. This is repeated until only one
129135
// of the previously tied candidates is currently found to have the highest
130136
// median-grade.” (source: https://en.wikipedia.org/wiki/Majority_judgment)
131-
137+
132138
// Use the operation `map` to transform each element of the `bestCandidates`.
133139
// And use the operation `diff` to remove one `bestMedianGrade` from the
134140
// grades assigned to the candidates.
135141
val bestCandidatesMinusOneMedianGrade: Map[Candidate, Seq[Grade]] =
136-
???
137-
142+
bestCandidates.map((candidate, grades) => (candidate, grades diff Seq(bestMedianGrade)))
143+
138144
// Finally, call `findWinner` on the reduced collection of candidates,
139145
// `bestCandidatesMinusOneMedianGrade`.
140-
???
146+
findWinner(bestCandidatesMinusOneMedianGrade)
141147
end findWinner
142148

143149
end Election

0 commit comments

Comments
 (0)