Different solution for Gophercise 1

This commit is contained in:
2025-05-31 13:14:20 -04:00
parent b22ab92d79
commit 1da6e395bf
56 changed files with 3374 additions and 0 deletions

View File

@@ -0,0 +1,159 @@
package main
import (
"bufio"
"flag"
"fmt"
"io/ioutil"
"log"
"math/rand"
"os"
"strconv"
"strings"
"time"
)
// Problem structure
type Problem struct {
q string
a int
}
// PROBLEMBUFCOUNT sets number of problems in buffer
const PROBLEMBUFCOUNT = 100
// DEFAULTTIMELIMIT sets the default time limit for the quiz
const DEFAULTTIMELIMIT = 30 //seconds
// Problem counter
var count int
// Score counter
var score int
var faults int
// readProblems takes reads problems from file, line by line
// problems are written to problems channel
func readProblems(problems chan Problem, filename string, shuffle bool) {
// problems buffer
buf := make([]Problem, PROBLEMBUFCOUNT)
// Open problems file
fd, err := os.Open(filename)
if err != nil {
log.Fatal(err)
}
defer fd.Close()
// Scan file
scanner := bufio.NewScanner(fd)
for scanner.Scan() {
// Read comma separated line
line := strings.Split(scanner.Text(), ",")
// first value is the question string
q := line[0]
// Convert string answer to integer
ans, err := strconv.Atoi(line[1])
if err != nil {
log.Fatal(err)
}
// store problem in buffer
buf[count] = Problem{q, ans}
count++
}
// shuffle problems
if shuffle {
rand.Seed(time.Now().Unix())
for i := range buf[:count] {
j := rand.Intn(i + 1)
buf[i], buf[j] = buf[j], buf[i]
}
}
// send problems over channel
for _, p := range buf[:count] {
problems <- p
}
}
// solveProblem consumes problems from chan
// will check timer before giving points
func solveProblem(problems chan Problem) {
// IO reader
scanner := bufio.NewScanner(os.Stdin)
// start consuming problems from channel
for p := range problems {
// Print problem question
fmt.Printf("%s = ", p.q)
// Scan IO
scanner.Scan()
input := strings.Trim(scanner.Text(), " ") // remove whitespace
// convert string answer to integer
givenAns, err := strconv.Atoi(input)
if err != nil {
fmt.Printf("'%s' is not a valid answer\n", input)
continue
}
// Check answer and give points
if givenAns == p.a {
score++
fmt.Println("Correct!")
} else {
faults++
fmt.Println("Wrong!")
}
}
return
}
// startTimer blocks for n seconds
func startTimer(seconds int) {
time.Sleep(time.Duration(seconds) * time.Second)
}
func main() {
// Parse Command line flags
filenamePtr := flag.String("f", "problems.csv", "name of problem csv file")
secondsPtr := flag.Int("t", DEFAULTTIMELIMIT, "number of seconds to solve problems")
shufflePtr := flag.Bool("s", false, "shuffle questions")
debugPtr := flag.Bool("debug", false, "show debug information")
flag.Parse()
// Show debug/logging information
if !*debugPtr {
log.SetOutput(ioutil.Discard)
}
log.Println("debug:", *debugPtr)
log.Println("filename:", *filenamePtr)
log.Println("shuffle:", *shufflePtr)
log.Println("timer:", *secondsPtr)
// Problems channel (buffered)
problems := make(chan Problem, PROBLEMBUFCOUNT)
// read problems goroutine
go readProblems(problems, *filenamePtr, *shufflePtr)
// Prompt to start the game
fmt.Printf("Press any key to start the quiz!")
bufio.NewScanner(os.Stdin).Scan()
// solve problems goroutine
go solveProblem(problems)
// start timer barrier
startTimer(*secondsPtr)
// Show final tally
fmt.Printf("\nNumber of questions: %d\n", count)
fmt.Printf("Correct answers: %d\n", score)
fmt.Printf("Incorrect answers: %d\n", faults)
}

View File

@@ -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
1 5+5 10
2 1+1 2
3 8+3 11
4 1+2 3
5 8+6 14
6 3+1 4
7 1+4 5
8 5+1 6
9 2+3 5
10 3+3 6
11 2+4 6
12 5+2 7