70 lines
1.5 KiB
Go
70 lines
1.5 KiB
Go
package challenge
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func readConfig(r io.Reader) (Config, error) {
|
|
var cfg Config
|
|
if err := json.NewDecoder(r).Decode(&cfg); err != nil {
|
|
return cfg, err
|
|
}
|
|
return cfg, nil
|
|
}
|
|
|
|
func readEvents(r io.Reader) ([]Event, error) {
|
|
var events []Event
|
|
scanner := bufio.NewScanner(r)
|
|
lineNo := 0
|
|
for scanner.Scan() {
|
|
lineNo++
|
|
line := strings.TrimSpace(scanner.Text())
|
|
if line == "" {
|
|
continue
|
|
}
|
|
event, err := parseEvent(line)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("line %d: %w", lineNo, err)
|
|
}
|
|
events = append(events, event)
|
|
}
|
|
return events, scanner.Err()
|
|
}
|
|
|
|
func parseEvent(line string) (Event, error) {
|
|
fields := strings.Fields(line)
|
|
if len(fields) < 3 {
|
|
return Event{}, errors.New("not enough fields")
|
|
}
|
|
if len(fields[0]) != len("[15:04:05]") || fields[0][0] != '[' || fields[0][len(fields[0])-1] != ']' {
|
|
return Event{}, errors.New("bad time format")
|
|
}
|
|
at, err := parseClock(fields[0][1 : len(fields[0])-1])
|
|
if err != nil {
|
|
return Event{}, err
|
|
}
|
|
player, err := strconv.Atoi(fields[1])
|
|
if err != nil {
|
|
return Event{}, err
|
|
}
|
|
id, err := strconv.Atoi(fields[2])
|
|
if err != nil {
|
|
return Event{}, err
|
|
}
|
|
|
|
return Event{At: at, Player: player, ID: id, Extra: strings.Join(fields[3:], " ")}, nil
|
|
}
|
|
|
|
func parseNonNegativeInt(value string) (int, bool) {
|
|
if strings.TrimSpace(value) != value || value == "" || strings.Contains(value, " ") {
|
|
return 0, false
|
|
}
|
|
n, err := strconv.Atoi(value)
|
|
return n, err == nil && n >= 0
|
|
}
|