Skip to content

Commit

Permalink
Merge pull request #617 from vaskoz/day300
Browse files Browse the repository at this point in the history
Day300
  • Loading branch information
vaskoz committed Jun 22, 2019
2 parents 8119d23 + fd7028a commit 0a69e9d
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,3 +307,4 @@ problems from
* [Day 297](https://github.com/vaskoz/dailycodingproblem-go/issues/607)
* [Day 298](https://github.com/vaskoz/dailycodingproblem-go/issues/609)
* [Day 299](https://github.com/vaskoz/dailycodingproblem-go/issues/611)
* [Day 300](https://github.com/vaskoz/dailycodingproblem-go/issues/612)
61 changes: 61 additions & 0 deletions day300/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package day300

import (
"fmt"
"io"
"os"
"sort"
)

var (
out io.Writer = os.Stdout // nolint
in io.Reader = os.Stdin // nolint
)

// VotingResult is the number of votes a candidate received.
type VotingResult struct {
Candidate, Votes int
}

func main() {
var voterID, candidateID int
voters := make(map[int]struct{})
candidates := make(map[int]*VotingResult)
top3 := make([]*VotingResult, 0, 3)
_, err := fmt.Fscanf(in, "%d,%d", &voterID, &candidateID)
for err != io.EOF {
if _, voted := voters[voterID]; voted {
fmt.Fprintf(out, "voter %d already voted. this vote for candidate %d will not count\n", voterID, candidateID)
} else {
voters[voterID] = struct{}{}
if cand, exists := candidates[candidateID]; !exists {
candidates[candidateID] = &VotingResult{Candidate: candidateID, Votes: 1}
if len(top3) < 3 {
top3 = append(top3, candidates[candidateID])
}
} else {
cand.Votes++
if cand.Votes > top3[0].Votes && !Contains(top3, candidates[candidateID]) {
top3[0] = cand
}
}
sort.Slice(top3, func(i, j int) bool {
return top3[i].Votes < top3[j].Votes
})
for _, v := range top3 {
fmt.Fprintf(out, "%d,%v ", v.Candidate, v.Votes)
}
fmt.Fprintln(out)
}
_, err = fmt.Fscanf(in, "%d,%d", &voterID, &candidateID)
}
}

func Contains(top3 []*VotingResult, cand *VotingResult) bool {
for _, c := range top3 {
if cand == c {
return true
}
}
return false
}
42 changes: 42 additions & 0 deletions day300/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package day300

import (
"bytes"
"strings"
"testing"
)

// nolint
var testcases = []struct {
input, output string
}{
{"1,1 2,2 3,3 4,3 5,3", "1,1 \n1,1 2,1 \n1,1 2,1 3,1 \n1,1 2,1 3,2 \n1,1 2,1 3,3 \n"},
{"1,1 2,2 3,3 1,3", "1,1 \n1,1 2,1 \n1,1 2,1 3,1 \nvoter 1 already voted. this vote for candidate 3 will not count\n"},
{"1,1 2,2 3,3 4,4 5,4",
"1,1 \n1,1 2,1 \n1,1 2,1 3,1 \n1,1 2,1 3,1 \n2,1 3,1 4,2 \n"},
}

func TestMainVoterTop3(t *testing.T) {
// don't run in parallel due to global var
for _, tc := range testcases {
buff := new(bytes.Buffer)
out = buff
in = strings.NewReader(tc.input)
main()
if result := buff.String(); result != tc.output {
t.Errorf("Expected \n%s, got \n%s", tc.output, result)
}
}
}

func BenchmarkMainVoterTop3(b *testing.B) {
// don't run in parallel due to global var
buff := new(bytes.Buffer)
out = buff
for i := 0; i < b.N; i++ {
for _, tc := range testcases {
in = strings.NewReader(tc.input)
main()
}
}
}

0 comments on commit 0a69e9d

Please sign in to comment.