-
Notifications
You must be signed in to change notification settings - Fork 728
added my solution #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| 5+5,10 | ||
| 1+1,2 | ||
| 8+3,11 | ||
| 1+2,3 | ||
| 8+6,14 | ||
| 3+1,4 | ||
| 1+4,5 | ||
| 5+1,6 | ||
| 2+3,5 | ||
| 3+3,6 | ||
| 2+4,6 | ||
| 5+2,7 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "encoding/csv" | ||
| "os" | ||
| "fmt" | ||
| "strings" | ||
| "log" | ||
| "flag" | ||
| "time" | ||
| "math/rand" | ||
| ) | ||
|
|
||
| type Question struct { | ||
| question string | ||
| answer string | ||
| } | ||
|
|
||
| func getQuestions(filePath string) ([]Question) { | ||
| file, err := os.Open(filePath) | ||
| if(err != nil){ | ||
| log.Fatal("Failed to open file.") | ||
| } | ||
| reader := csv.NewReader(file) | ||
| questionList, err := reader.ReadAll() | ||
| if(err != nil) { | ||
| log.Fatal("Failed to parse CSV file.") | ||
| } | ||
| questions := make([]Question, 0) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now you have successfully loaded your questions := make([]Question, len(questionList))
for i, question := range questionList {
if len(question) != 2 {
continue
}
questions[i] = Question{
strings.TrimSpace(question[0]),
strings.TrimSpace(question[1]),
}
}This way you don't allocate new array every time append is called. Also always check the input coming from outside world. |
||
|
|
||
| for _, question := range questionList { | ||
| questions = append(questions, Question{strings.TrimSpace(question[0]), | ||
| strings.TrimSpace(question[1])}) | ||
| } | ||
| return questions | ||
| } | ||
|
|
||
| func Quiz(questions []Question, timer *time.Timer) (score int){ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no need for named return, it's another allocation. If you simply name your function |
||
|
|
||
| for i, question := range questions { | ||
| fmt.Printf("Problem #%d %s : ", i + 1, question.question) | ||
| answerChannel := make(chan string) | ||
| go func() { | ||
| var userAnswer string | ||
| fmt.Scanln(&userAnswer) | ||
| answerChannel <- userAnswer | ||
| }() | ||
|
|
||
| select { | ||
| case <-timer.C: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very clever use of timers. |
||
| fmt.Println("\nTimeout") | ||
| return score | ||
| case userAnswer := <- answerChannel: | ||
| if(strings.TrimSpace(userAnswer) == question.answer) { | ||
| score += 1 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can simply do: |
||
| } | ||
| } | ||
| } | ||
| return score | ||
| } | ||
|
|
||
| func randomize(questions []Question) []Question{ | ||
| n := len(questions) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can do this too: rand.Seed(time.Now().UnixNano())
for i := range questions {
j := rand.Intn(i + 1)
questions[i], questions[j] = questions[j], questions[i]
}or rand.Seed(time.Now().UnixNano())
rand.Shuffle(len(questions), func(i, j int) {
questions[i], questions[j] = questions[j], questions[i]
})It's a good idea to seed your random generator otherwise the shuffle returns the same results every time you run the program, which defeats its purpose. |
||
| for i := n-1; i>0; i-- { | ||
| j := rand.Intn(i) | ||
| temp := questions[i] | ||
| questions[i] = questions[j] | ||
| questions[j] = temp | ||
| } | ||
| return questions | ||
| } | ||
|
|
||
| var csvPath string | ||
| var timeout int | ||
| var shuffle bool | ||
|
|
||
| func init() { | ||
| flag.StringVar(&csvPath, "csv", "problems.csv", "a CSV file in format of 'question,answer'") | ||
| flag.IntVar(&timeout, "limit", 30, "The time limit of the quiz in seconds") | ||
| flag.BoolVar(&shuffle, "shuffle", false, "Shuffle the questions (default 'false')") | ||
| } | ||
|
|
||
| func main() { | ||
| flag.Parse() | ||
| fmt.Print("Hit Enter to start the timer:") | ||
| questions := getQuestions(csvPath) | ||
| if(shuffle) { | ||
| questions = randomize(questions) | ||
| } | ||
| fmt.Scanln() | ||
| timer := time.NewTimer(time.Second * time.Duration(timeout)) | ||
| score := Quiz(questions, timer) | ||
| fmt.Printf("Your scored %d out of %d\n", score, len(questions)) | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a good idea to document an exported struct. You can use
golinttool to tell you about these actions: