-
Notifications
You must be signed in to change notification settings - Fork 0
/
encounter_count.go
109 lines (96 loc) · 2.32 KB
/
encounter_count.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
100
101
102
103
104
105
106
107
108
109
// Reimplementation of the Python script with the same name.
// Refer to the Python script for documentation.
package main
import (
"bufio"
"flag"
"fmt"
"os"
"sort"
"strconv"
"strings"
)
func main() {
u := flag.Bool("u", false, "Unique encounters (not total).")
flag.Parse()
// read contacts from stdin
contacts := []Contact{}
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
fields := strings.Split(strings.TrimSpace(scanner.Text()), ",")
node1, node2 := fields[0], fields[1]
start, _ := strconv.Atoi(fields[2])
contacts = append(contacts, Contact{node1, node2, start})
}
// calculate results
var results []IntPair
if *u {
results = unique(contacts)
} else {
results = total(contacts)
}
// write results to stdout
for _, r := range results {
fmt.Println(strings.Join([]string{
strconv.Itoa(r.one),
strconv.Itoa(r.two)},
","))
}
}
func total(contacts []Contact) []IntPair {
sort.Sort(ByStart(contacts))
counts := []IntPair{}
start := contacts[0].start
count := 0
current_time := contacts[0].start
for _, c := range contacts {
if current_time != c.start {
counts = append(counts, IntPair{current_time - start,
count})
}
count++
current_time = c.start
}
counts = append(counts, IntPair{current_time - start, count})
return counts
}
func unique(contacts []Contact) []IntPair {
sort.Sort(ByStart(contacts))
counts := []IntPair{}
start := contacts[0].start
count := 0
current_time := contacts[0].start
// key -> sorted NodePair
node_pairs := make(map[NodePair]bool)
for _, c := range contacts {
if current_time != c.start {
counts = append(counts, IntPair{current_time - start,
count})
}
nodes := []string{c.node1, c.node2}
sort.Strings(nodes)
pair := NodePair{nodes[0], nodes[1]}
if !node_pairs[pair] {
count++
node_pairs[pair] = true
}
current_time = c.start
}
counts = append(counts, IntPair{current_time - start, count})
return counts
}
type IntPair struct {
one, two int
}
type Contact struct {
node1, node2 string
start int
}
type NodePair struct {
node1, node2 string
}
// sorting interface by contact start time
type ByStart []Contact
func (a ByStart) Len() int { return len(a) }
func (a ByStart) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByStart) Less(i, j int) bool { return a[i].start < a[j].start }