Skip to content

Commit d5cb00b

Browse files
committed
Submited code
1 parent 26f43a8 commit d5cb00b

File tree

7 files changed

+123
-16
lines changed

7 files changed

+123
-16
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Hashcode 2017
2+
3+
This is the code developed for Google Hashcode 2017. The tag 1.0 is the code exactly as it was submited.
4+
5+
The score was **1286849**.

cmd/main.go

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,32 @@
11
package main
22

33
import (
4+
"bytes"
45
"flag"
6+
"fmt"
57
"os"
8+
"sort"
69

710
log "github.com/Sirupsen/logrus"
811
"github.com/bigomby/hashcode2017/internal/input"
12+
"github.com/bigomby/hashcode2017/internal/types"
913
)
1014

15+
// Videos is cool
16+
type Videos []*types.Video
17+
18+
func (slice Videos) Len() int {
19+
return len(slice)
20+
}
21+
22+
func (slice Videos) Less(i, j int) bool {
23+
return slice[i].Size < slice[j].Size
24+
}
25+
26+
func (slice Videos) Swap(i, j int) {
27+
slice[i], slice[j] = slice[j], slice[i]
28+
}
29+
1130
func main() {
1231
input.Logger = log.New()
1332

@@ -29,5 +48,49 @@ func main() {
2948
log.Fatal(err.Error())
3049
}
3150

32-
input.ParseHeader(f)
51+
// Sort videos
52+
var videos Videos
53+
endpoints, videos, servers, _ := input.ParseHeader(f)
54+
sort.Sort(videos)
55+
56+
// Sort every endpoint
57+
for _, endpoint := range endpoints {
58+
var sortable types.Connections
59+
sortable = endpoint.Connections
60+
sort.Sort(sortable)
61+
}
62+
63+
for _, video := range videos {
64+
serverLoop:
65+
for _, server := range servers {
66+
if server.Capacity >= video.Size {
67+
server.Videos = append(server.Videos, video)
68+
server.Capacity -= video.Size
69+
break serverLoop
70+
}
71+
}
72+
}
73+
74+
// The output
75+
var usedServersCount int
76+
for _, server := range servers {
77+
if len(server.Videos) > 0 {
78+
usedServersCount++
79+
}
80+
}
81+
82+
output := new(bytes.Buffer)
83+
fmt.Fprintf(output, "%d\n", usedServersCount)
84+
85+
for i, server := range servers {
86+
fmt.Fprintf(output, "%d", i)
87+
for _, video := range server.Videos {
88+
fmt.Fprintf(output, " %d", video.ID)
89+
}
90+
91+
fmt.Fprintf(output, "\n")
92+
}
93+
94+
outfile, err := os.Create("output")
95+
outfile.Write(output.Bytes())
3396
}

internal/input/input.go

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
var Logger *log.Logger
1717

1818
// ParseHeader parses the fist line of the file
19-
func ParseHeader(input io.Reader) {
19+
func ParseHeader(input io.Reader) ([]types.Endpoint, []*types.Video, []*types.CacheServer, []types.RequestDescription) {
2020
var videosCount int
2121
var endpointsCount int
2222
var requestsDescriptionsCount int
@@ -42,32 +42,52 @@ func ParseHeader(input io.Reader) {
4242
&capacity,
4343
)
4444

45+
serverTemplate := types.CacheServer{
46+
Capacity: capacity,
47+
}
48+
49+
var servers []*types.CacheServer
50+
for i := 0; i < cacheServersCount; i++ {
51+
serverTemplateCopy := serverTemplate
52+
servers = append(servers, &serverTemplateCopy)
53+
}
54+
55+
for _, server := range servers {
56+
server = new(types.CacheServer)
57+
server.Capacity = capacity
58+
}
59+
4560
scanner.Scan()
4661
videos := parseVideos(scanner.Text())
4762
parseVideos(scanner.Text())
4863

4964
for i := 0; i < endpointsCount; i++ {
50-
endpoints = append(endpoints, parseEndpoint(scanner))
65+
endpoints = append(endpoints, parseEndpoint(scanner, servers))
5166
}
5267

5368
for i := 0; i < requestsDescriptionsCount; i++ {
5469
requests = append(requests, parseRequest(scanner, videos, endpoints))
5570
}
71+
72+
return endpoints, videos, servers, requests
5673
}
5774

58-
func parseVideos(line string) []types.Video {
59-
var videos []types.Video
75+
func parseVideos(line string) []*types.Video {
76+
var videos []*types.Video
6077
sizes := strings.Split(line, " ")
6178

62-
for _, size := range sizes {
79+
for i, size := range sizes {
6380
sizeInt, _ := strconv.ParseInt(size, 10, 32)
64-
videos = append(videos, types.Video{Size: int(sizeInt)})
81+
videos = append(videos, &types.Video{
82+
ID: i,
83+
Size: int(sizeInt),
84+
})
6585
}
6686

6787
return videos
6888
}
6989

70-
func parseEndpoint(scanner *bufio.Scanner) types.Endpoint {
90+
func parseEndpoint(scanner *bufio.Scanner, servers []*types.CacheServer) types.Endpoint {
7191
var connections int
7292
var latency int
7393

@@ -77,15 +97,17 @@ func parseEndpoint(scanner *bufio.Scanner) types.Endpoint {
7797

7898
endpoint := types.Endpoint{
7999
Latency: latency,
80-
Connections: make([]types.Connection, connections),
100+
Connections: make([]types.Connection, 0),
81101
}
82102

83103
for i := 0; i < connections; i++ {
84104
connection := types.Connection{}
105+
var connectionID int
85106

86107
scanner.Scan()
87108
attributes := scanner.Text()
88-
fmt.Sscanf(attributes, "%d %d", &connection.ID, &connection.CacheLatency)
109+
fmt.Sscanf(attributes, "%d %d", &connectionID, &connection.CacheLatency)
110+
connection.Server = servers[connectionID]
89111
endpoint.Connections = append(endpoint.Connections, connection)
90112
}
91113

@@ -94,7 +116,7 @@ func parseEndpoint(scanner *bufio.Scanner) types.Endpoint {
94116

95117
func parseRequest(
96118
scanner *bufio.Scanner,
97-
videos []types.Video,
119+
videos []*types.Video,
98120
endpoints []types.Endpoint,
99121
) types.RequestDescription {
100122
var videoID int
@@ -104,11 +126,11 @@ func parseRequest(
104126
scanner.Scan()
105127
line := scanner.Text()
106128
fmt.Sscanf(line, "%d %d %d", &videoID, &endpointID, &amount)
107-
Logger.Debugf("[REQUEST] Amount: %d | Video: %d | Endpoint: %d", amount, videoID, endpointID)
129+
// Logger.Debugf("[REQUEST] Amount: %d | Video: %d | Endpoint: %d", amount, videoID, endpointID)
108130

109131
return types.RequestDescription{
110132
Amount: amount,
111-
Video: &videos[videoID],
133+
Video: videos[videoID],
112134
Source: &endpoints[endpointID],
113135
}
114136
}

internal/types/cache_server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ package types
33
// CacheServer is a server who caches. Really.
44
type CacheServer struct {
55
Capacity int
6+
Videos []*Video
67
}

internal/types/endpoint.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
package types
22

3+
// Connections does stuff
4+
type Connections []Connection
5+
6+
func (slice Connections) Len() int {
7+
return len(slice)
8+
}
9+
10+
func (slice Connections) Less(i, j int) bool {
11+
return slice[i].CacheLatency < slice[j].CacheLatency
12+
}
13+
14+
func (slice Connections) Swap(i, j int) {
15+
slice[i], slice[j] = slice[j], slice[i]
16+
}
17+
318
// Endpoint represents a group of users connecting to the Internet in the same
419
// geographical area (for example, a neighborhood in a city). Every endpoint is
520
// connected to the data center. Additionally, each endpoint may (but doesn’t
@@ -11,13 +26,12 @@ package types
1126
// is connected to (how long it takes to serve a video stored in the given cache
1227
// server to a user in this endpoint).
1328
type Endpoint struct {
14-
Servers []*CacheServer
15-
Latency int
1629
Connections []Connection
30+
Latency int
1731
}
1832

1933
// Connection is a connection from an endpoint to a Cache Server
2034
type Connection struct {
21-
ID int
35+
Server *CacheServer
2236
CacheLatency int
2337
}

internal/types/requests.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package types
22

3+
// RequestDescription hola manu
34
type RequestDescription struct {
45
Amount int
56
Video *Video

internal/types/video.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ package types
22

33
// Video is just a video
44
type Video struct {
5+
ID int
56
Size int
67
}

0 commit comments

Comments
 (0)