-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
99 lines (81 loc) · 1.72 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main
import (
"encoding/csv"
"fmt"
"io"
"log"
"os"
"sort"
"strconv"
"strings"
"unicode/utf8"
)
type Driver struct {
Name string
Score int
}
func newDriver(fields []string) (d Driver, err error) {
if len(fields) < 2 {
return d, fmt.Errorf("not enough data for Driver")
}
d.Name = fields[0]
d.Score, err = strconv.Atoi(fields[1])
if err != nil {
return d, fmt.Errorf("failed to convert score into int")
}
return d, nil
}
type byScore []Driver
func (a byScore) Len() int { return len(a) }
func (a byScore) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byScore) Less(i, j int) bool { return a[j].Score < a[i].Score }
func main() {
drivers, err := readData("input.csv")
if err != nil {
log.Fatal(err)
}
sort.Sort(byScore(drivers))
output, err := os.Create("output.txt")
if err != nil {
log.Fatal(err)
}
defer output.Close()
for _, driver := range drivers {
line := ""
charsLen := utf8.RuneCountInString(driver.Name) + countLengthOfInt(driver.Score)
if charsLen < 21 {
line = fmt.Sprintln(driver.Name, strings.Repeat(" ", 21-charsLen), driver.Score)
} else {
line = fmt.Sprintln(driver.Name, driver.Score)
}
output.WriteString(line)
}
}
func countLengthOfInt(number int) int {
str := strconv.Itoa(number)
return utf8.RuneCountInString(str)
}
func readData(fileName string) ([]Driver, error) {
f, err := os.Open(fileName)
if err != nil {
return nil, err
}
r := csv.NewReader(f)
defer f.Close()
var drivers []Driver
for {
record, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
driver, err := newDriver(record)
if err != nil {
continue
}
drivers = append(drivers, driver)
}
return drivers, nil
}