words.go

 1package words
 2
 3import (
 4	"bufio"
 5	"strings"
 6)
 7
 8type List struct {
 9	words [][]string
10	len   int
11}
12
13func newList(words []string) List {
14	return List{
15		words: [][]string{words},
16		len:   len(words),
17	}
18}
19
20func NewList(words []string) List {
21	cleaned := make([]string, 0, len(words))
22	for _, w := range words {
23		w = strings.TrimSpace(w)
24		w = strings.ToUpper(w)
25		cleaned = append(cleaned, w)
26	}
27	return newList(cleaned)
28}
29
30func NewListFromLines(s string) List {
31	s = strings.TrimSpace(s)
32	words := make([]string, 0, strings.Count(s, "\n"))
33	scanner := bufio.NewScanner(strings.NewReader(s))
34
35	for scanner.Scan() {
36		word := scanner.Text()
37		word = strings.TrimSpace(word)
38		word = strings.ToUpper(word)
39		words = append(words, word)
40	}
41
42	return newList(words)
43}
44
45func (l *List) Len() int {
46	return l.len
47}
48
49func (l *List) Get(i int) string {
50	for _, words := range l.words {
51		if i < len(words) {
52			return words[i]
53		}
54		i -= len(words)
55	}
56	panic("out of bounds")
57}
58
59func (l List) Concat(other List) List {
60	words := make([][]string, 0, len(l.words)+len(other.words))
61	words = append(words, l.words...)
62	words = append(words, other.words...)
63
64	return List{
65		words: words,
66		len:   l.len + other.len,
67	}
68}