Решение на Game of Life от Екатерина Горанова

Обратно към всички решения

Към профила на Екатерина Горанова

Резултати

  • 9 точки от тестове
  • 0 бонус точки
  • 9 точки общо
  • 12 успешни тест(а)
  • 2 неуспешни тест(а)

Код

package main
import (
"encoding/json"
"net/http"
"strconv"
)
var gol *GameOfLife
type Cell struct {
X int64 `json:"x"`
Y int64 `json:"y"`
}
type Board struct {
cells map[Cell]bool
xMin, xMax int64
yMin, yMax int64
}
func (b *Board) IsAlive(x, y int64) bool {
cell := Cell{x, y}
_, ok := b.cells[cell]
return ok
}
func (b *Board) Add(x, y int64) {
cell := Cell{x, y}
b.cells[cell] = true
if b.xMin >= cell.X {
b.xMin = cell.X - 1
}
if b.yMin >= cell.Y {
b.yMin = cell.Y - 1
}
if b.xMax <= cell.X {
b.xMax = cell.X + 1
}
if b.yMax <= cell.Y {
b.yMax = cell.Y + 1
}
}
func (b *Board) GetAlive() [][2]int64 {
var alive [][2]int64
for cell := range b.cells {
alive = append(alive, [2]int64{cell.X, cell.Y})
}
return alive
}
func (b *Board) StayAlive(x, y int64) bool {
deltas := [][2]int64{
{-1, -1}, {0, -1}, {1, -1}, {1, 0},
{1, 1}, {0, 1}, {-1, 1}, {-1, 0},
}
var neighbours int
for _, delta := range deltas {
neighbour := Cell{x + delta[0], y + delta[1]}
if _, ok := b.cells[neighbour]; ok {
neighbours++
}
}
isAlive := b.IsAlive(x, y)
if neighbours == 2 && isAlive || neighbours == 3 {
return true
}
return false
}
type GameOfLife struct {
generation int64
board Board
}
func NewGameOfLife(coordinates [][2]int64) *GameOfLife {
newBoard := Board{cells: make(map[Cell]bool)}
g := &GameOfLife{board: newBoard}
for _, coord := range coordinates {
g.board.Add(coord[0], coord[1])
}
return g
}
func (g *GameOfLife) Evolve() {
newBoard := Board{cells: make(map[Cell]bool)}
for x := g.board.xMin; x <= g.board.xMax; x++ {
for y := g.board.yMin; y <= g.board.yMax; y++ {
if g.board.StayAlive(x, y) {
newBoard.Add(x, y)
}
}
}
g.board = newBoard
g.generation++
}
/* Handlers */
type CellStatus struct {
Alive bool `json:"alive"`
}
func CellStatusHandler(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
x, err := strconv.ParseInt(q.Get("x"), 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
y, err := strconv.ParseInt(q.Get("y"), 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
status := CellStatus{gol.board.IsAlive(x, y)}
js, err := json.Marshal(status)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.Write(js)
}
type Generation struct {
Generation int64 `json:"generation"`
Living [][2]int64 `json:"living"`
}
func GenerationHandler(w http.ResponseWriter, r *http.Request) {
generation := Generation{gol.generation, gol.board.GetAlive()}
js, err := json.Marshal(generation)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.Write(js)
}
func AddCellsHandler(w http.ResponseWriter, r *http.Request) {
cells := make([]Cell, 0)
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&cells)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
for _, c := range cells {
gol.board.Add(c.X, c.Y)
}
w.WriteHeader(http.StatusCreated)
}
func EvolveHandler(w http.ResponseWriter, r *http.Request) {
gol.Evolve()
w.WriteHeader(http.StatusNoContent)
}
func ResetHandler(w http.ResponseWriter, r *http.Request) {
gol = NewGameOfLife([][2]int64{})
w.WriteHeader(http.StatusNoContent)
}
type Route struct {
Path string
Method string
handler http.HandlerFunc
}
type GameOfLifeHandler struct {
Routes []Route
}
func NewGameOfLifeHandler(coordinates [][2]int64) *GameOfLifeHandler {
gol = NewGameOfLife(coordinates)
routes := []Route{
Route{"/cell/status/", "GET", CellStatusHandler},
Route{"/generation/", "GET", GenerationHandler},
Route{"/cells/", "POST", AddCellsHandler},
Route{"/generation/evolve/", "POST", EvolveHandler},
Route{"/reset/", "POST", ResetHandler},
}
return &GameOfLifeHandler{routes}
}
func (golh *GameOfLifeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
path := r.URL.EscapedPath()
var found bool
for _, route := range golh.Routes {
if route.Path == path {
found = true
if route.Method == r.Method {
route.handler(w, r)
} else {
w.WriteHeader(http.StatusMethodNotAllowed)
}
}
}
if !found {
w.WriteHeader(http.StatusNotFound)
}
}

Лог от изпълнението

PASS
ok  	_/tmp/d20160126-5892-gv2pss	0.004s
PASS
ok  	_/tmp/d20160126-5892-gv2pss	0.005s
PASS
ok  	_/tmp/d20160126-5892-gv2pss	0.006s
PASS
ok  	_/tmp/d20160126-5892-gv2pss	0.007s
PASS
ok  	_/tmp/d20160126-5892-gv2pss	0.007s
PASS
ok  	_/tmp/d20160126-5892-gv2pss	0.006s
PASS
ok  	_/tmp/d20160126-5892-gv2pss	0.006s
PASS
ok  	_/tmp/d20160126-5892-gv2pss	0.008s
PASS
ok  	_/tmp/d20160126-5892-gv2pss	0.006s
--- FAIL: TestWrongJSONs (0.00s)
	solution_test.go:355: Expected non 201 but got 201 for adding cells with body: []]
	solution_test.go:355: Expected non 201 but got 201 for adding cells with body: [{"x": 2, "y": -2}]]
FAIL
exit status 1
FAIL	_/tmp/d20160126-5892-gv2pss	0.008s
PASS
ok  	_/tmp/d20160126-5892-gv2pss	0.009s
PASS
ok  	_/tmp/d20160126-5892-gv2pss	0.009s
PASS
ok  	_/tmp/d20160126-5892-gv2pss	0.011s
panic: test timed out after 1s

goroutine 61 [running]:
testing.startAlarm.func1()
	/usr/local/go/src/testing/testing.go:703 +0x132
created by time.goFunc
	/usr/local/go/src/time/sleep.go:129 +0x3a

goroutine 1 [chan receive]:
testing.RunTests(0x83b160, 0x954f40, 0xe, 0xe, 0x4eae01)
	/usr/local/go/src/testing/testing.go:562 +0x8ad
testing.(*M).Run(0xc82004def8, 0x4eafb3)
	/usr/local/go/src/testing/testing.go:494 +0x70
main.main()
	_/tmp/d20160126-5892-gv2pss/_test/_testmain.go:80 +0x116

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1696 +0x1

goroutine 6 [semacquire]:
sync.runtime_Semacquire(0xc8200110ec)
	/usr/local/go/src/runtime/sema.go:43 +0x26
sync.(*WaitGroup).Wait(0xc8200110e0)
	/usr/local/go/src/sync/waitgroup.go:126 +0xb4
_/tmp/d20160126-5892-gv2pss.TestConcurrentOperation(0xc82007e120)
	/tmp/d20160126-5892-gv2pss/solution_test.go:585 +0x280
testing.tRunner(0xc82007e120, 0x955078)
	/usr/local/go/src/testing/testing.go:456 +0x98
created by testing.RunTests
	/usr/local/go/src/testing/testing.go:561 +0x86d

goroutine 7 [IO wait]:
net.runtime_pollWait(0x7fec767888e0, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc8200124c0, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc8200124c0, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).accept(0xc820012460, 0x0, 0x7fec75741000, 0xc8200ae8e0)
	/usr/local/go/src/net/fd_unix.go:408 +0x27c
net.(*TCPListener).AcceptTCP(0xc82002c048, 0xc820060f40, 0x0, 0x0)
	/usr/local/go/src/net/tcpsock_posix.go:254 +0x4d
net.(*TCPListener).Accept(0xc82002c048, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/tcpsock_posix.go:264 +0x3d
net/http/httptest.(*historyListener).Accept(0xc82000af30, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/httptest/server.go:48 +0x63
net/http.(*Server).Serve(0xc82001e300, 0x7fec767889a0, 0xc82000af30, 0x0, 0x0)
	/usr/local/go/src/net/http/server.go:1887 +0xb3
created by net/http/httptest.(*Server).Start
	/usr/local/go/src/net/http/httptest/server.go:109 +0x380

goroutine 8 [select]:
net/http.(*persistConn).roundTrip(0xc8200ca0b0, 0xc820417130, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1164 +0xb0d
net/http.(*Transport).RoundTrip(0xc82007e090, 0xc820415340, 0xc800000002, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:235 +0x530
net/http.send(0xc820415340, 0x7fec767877a8, 0xc82007e090, 0xc82041cd20, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:220 +0x52c
net/http.(*Client).send(0x9587e0, 0xc820415340, 0x1d, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:143 +0x15a
net/http.(*Client).doFollowingRedirects(0x9587e0, 0xc820415340, 0x83b3a8, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:380 +0xbc0
net/http.(*Client).Post(0x9587e0, 0xc82000e860, 0x1d, 0x7df990, 0x10, 0x7fec76788a00, 0xc8203ffc50, 0x74a4c0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:471 +0x107
net/http.Post(0xc82000e860, 0x1d, 0x7df990, 0x10, 0x7fec76788a00, 0xc8203ffc50, 0x41, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:454 +0x7a
_/tmp/d20160126-5892-gv2pss.TestConcurrentOperation.func1(0xc8200110e0, 0xc82001e360, 0xc820016880, 0xc82007e120)
	/tmp/d20160126-5892-gv2pss/solution_test.go:530 +0x3a8
created by _/tmp/d20160126-5892-gv2pss.TestConcurrentOperation
	/tmp/d20160126-5892-gv2pss/solution_test.go:538 +0xec

goroutine 9 [select]:
net/http.(*persistConn).roundTrip(0xc8200ca580, 0xc820423900, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1164 +0xb0d
net/http.(*Transport).RoundTrip(0xc82007e090, 0xc820421ea0, 0xc800000000, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:235 +0x530
net/http.send(0xc820421ea0, 0x7fec767877a8, 0xc82007e090, 0xc820427140, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:220 +0x52c
net/http.(*Client).send(0x9587e0, 0xc820421ea0, 0x1d, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:143 +0x15a
net/http.(*Client).doFollowingRedirects(0x9587e0, 0xc820421ea0, 0x83b3a8, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:380 +0xbc0
net/http.(*Client).Post(0x9587e0, 0xc8200ae0a0, 0x1d, 0x7df990, 0x10, 0x7fec76788a00, 0xc82042b590, 0x74a4c0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:471 +0x107
net/http.Post(0xc8200ae0a0, 0x1d, 0x7df990, 0x10, 0x7fec76788a00, 0xc82042b590, 0x41, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:454 +0x7a
_/tmp/d20160126-5892-gv2pss.TestConcurrentOperation.func1(0xc8200110e0, 0xc82001e360, 0xc820016880, 0xc82007e120)
	/tmp/d20160126-5892-gv2pss/solution_test.go:530 +0x3a8
created by _/tmp/d20160126-5892-gv2pss.TestConcurrentOperation
	/tmp/d20160126-5892-gv2pss/solution_test.go:538 +0xec

goroutine 10 [select]:
net/http.(*persistConn).roundTrip(0xc8200ca2c0, 0xc820417000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1164 +0xb0d
net/http.(*Transport).RoundTrip(0xc82007e090, 0xc820415260, 0xc800000002, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:235 +0x530
net/http.send(0xc820415260, 0x7fec767877a8, 0xc82007e090, 0xc82041cc60, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:220 +0x52c
net/http.(*Client).send(0x9587e0, 0xc820415260, 0x1d, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:143 +0x15a
net/http.(*Client).doFollowingRedirects(0x9587e0, 0xc820415260, 0x83b3a8, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:380 +0xbc0
net/http.(*Client).Post(0x9587e0, 0xc8200ae120, 0x1d, 0x7df990, 0x10, 0x7fec76788a00, 0xc8203ffb00, 0x74a4c0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:471 +0x107
net/http.Post(0xc8200ae120, 0x1d, 0x7df990, 0x10, 0x7fec76788a00, 0xc8203ffb00, 0x41, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:454 +0x7a
_/tmp/d20160126-5892-gv2pss.TestConcurrentOperation.func1(0xc8200110e0, 0xc82001e360, 0xc820016880, 0xc82007e120)
	/tmp/d20160126-5892-gv2pss/solution_test.go:530 +0x3a8
created by _/tmp/d20160126-5892-gv2pss.TestConcurrentOperation
	/tmp/d20160126-5892-gv2pss/solution_test.go:538 +0xec

goroutine 11 [select]:
net/http.(*persistConn).roundTrip(0xc8200ca160, 0xc820423a70, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1164 +0xb0d
net/http.(*Transport).RoundTrip(0xc82007e090, 0xc820446000, 0xab, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:235 +0x530
net/http.send(0xc820446000, 0x7fec767877a8, 0xc82007e090, 0xc820444050, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:220 +0x52c
net/http.(*Client).send(0x9587e0, 0xc820446000, 0x4f, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:143 +0x15a
net/http.(*Client).doFollowingRedirects(0x9587e0, 0xc820446000, 0x83b3a0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:380 +0xbc0
net/http.(*Client).Get(0x9587e0, 0xc820444000, 0x4f, 0xc820423a30, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:306 +0xaa
net/http.Get(0xc820444000, 0x4f, 0xc82033fe80, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:281 +0x45
_/tmp/d20160126-5892-gv2pss.isCellAlive(0xc820016880, 0x5a5e21e096ac2d64, 0x34360d60816459e1, 0x0, 0x0, 0x0)
	/tmp/d20160126-5892-gv2pss/solution_test.go:651 +0x203
_/tmp/d20160126-5892-gv2pss.TestConcurrentOperation.func2(0xc8200110e0, 0xc82001e360, 0xc820016880, 0xc82007e120)
	/tmp/d20160126-5892-gv2pss/solution_test.go:548 +0xc7
created by _/tmp/d20160126-5892-gv2pss.TestConcurrentOperation
	/tmp/d20160126-5892-gv2pss/solution_test.go:552 +0x163

goroutine 12 [select]:
net/http.(*persistConn).roundTrip(0xc8200b80b0, 0xc820417310, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1164 +0xb0d
net/http.(*Transport).RoundTrip(0xc82007e090, 0xc820415500, 0xab, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:235 +0x530
net/http.send(0xc820415500, 0x7fec767877a8, 0xc82007e090, 0xc8204363c0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:220 +0x52c
net/http.(*Client).send(0x9587e0, 0xc820415500, 0x4f, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:143 +0x15a
net/http.(*Client).doFollowingRedirects(0x9587e0, 0xc820415500, 0x83b3a0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:380 +0xbc0
net/http.(*Client).Get(0x9587e0, 0xc820436370, 0x4f, 0xc8204172d0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:306 +0xaa
net/http.Get(0xc820436370, 0x4f, 0xc82042c680, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:281 +0x45
_/tmp/d20160126-5892-gv2pss.isCellAlive(0xc820016880, 0x22614d6fbeca336a, 0x78c41cad289d547b, 0x0, 0x0, 0x0)
	/tmp/d20160126-5892-gv2pss/solution_test.go:651 +0x203
_/tmp/d20160126-5892-gv2pss.TestConcurrentOperation.func2(0xc8200110e0, 0xc82001e360, 0xc820016880, 0xc82007e120)
	/tmp/d20160126-5892-gv2pss/solution_test.go:548 +0xc7
created by _/tmp/d20160126-5892-gv2pss.TestConcurrentOperation
	/tmp/d20160126-5892-gv2pss/solution_test.go:552 +0x163

goroutine 13 [select]:
net/http.(*persistConn).roundTrip(0xc8200ca420, 0xc820423710, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1164 +0xb0d
net/http.(*Transport).RoundTrip(0xc82007e090, 0xc820421c00, 0xab, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:235 +0x530
net/http.send(0xc820421c00, 0x7fec767877a8, 0xc82007e090, 0xc820339e50, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:220 +0x52c
net/http.(*Client).send(0x9587e0, 0xc820421c00, 0x4f, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:143 +0x15a
net/http.(*Client).doFollowingRedirects(0x9587e0, 0xc820421c00, 0x83b3a0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:380 +0xbc0
net/http.(*Client).Get(0x9587e0, 0xc820339e00, 0x4f, 0xc8204236d0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:306 +0xaa
net/http.Get(0xc820339e00, 0x4f, 0xc82033fcc0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:281 +0x45
_/tmp/d20160126-5892-gv2pss.isCellAlive(0xc820016880, 0xeb5292585a45be6, 0x171a8ebfb2c1e9a4, 0x0, 0x0, 0x0)
	/tmp/d20160126-5892-gv2pss/solution_test.go:651 +0x203
_/tmp/d20160126-5892-gv2pss.TestConcurrentOperation.func2(0xc8200110e0, 0xc82001e360, 0xc820016880, 0xc82007e120)
	/tmp/d20160126-5892-gv2pss/solution_test.go:548 +0xc7
created by _/tmp/d20160126-5892-gv2pss.TestConcurrentOperation
	/tmp/d20160126-5892-gv2pss/solution_test.go:552 +0x163

goroutine 14 [select]:
net/http.(*persistConn).roundTrip(0xc8200ca000, 0xc8200b2050, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1164 +0xb0d
net/http.(*Transport).RoundTrip(0xc82007e090, 0xc8200be000, 0xc800000000, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:235 +0x530
net/http.send(0xc8200be000, 0x7fec767877a8, 0xc82007e090, 0xc8200ba060, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:220 +0x52c
net/http.(*Client).send(0x9587e0, 0xc8200be000, 0x29, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:143 +0x15a
net/http.(*Client).doFollowingRedirects(0x9587e0, 0xc8200be000, 0x83b3a8, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:380 +0xbc0
net/http.(*Client).Post(0x9587e0, 0xc8200ba000, 0x29, 0x0, 0x0, 0x0, 0x0, 0xc8200b2000, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:471 +0x107
net/http.Post(0xc8200ba000, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:454 +0x7a
_/tmp/d20160126-5892-gv2pss.nextGeneration(0xc820016880, 0x0, 0x0)
	/tmp/d20160126-5892-gv2pss/solution_test.go:679 +0x9d
_/tmp/d20160126-5892-gv2pss.TestConcurrentOperation.func3(0xc8200110e0, 0xc82001e360, 0xc820016880, 0xc82007e120)
	/tmp/d20160126-5892-gv2pss/solution_test.go:560 +0x82
created by _/tmp/d20160126-5892-gv2pss.TestConcurrentOperation
	/tmp/d20160126-5892-gv2pss/solution_test.go:563 +0x1da

goroutine 16 [select]:
net/http.(*persistConn).roundTrip(0xc8200b8160, 0xc820011300, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1164 +0xb0d
net/http.(*Transport).RoundTrip(0xc82007e090, 0xc8200b01c0, 0xc800000002, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:235 +0x530
net/http.send(0xc8200b01c0, 0x7fec767877a8, 0xc82007e090, 0xc82000b1d0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:220 +0x52c
net/http.(*Client).send(0x9587e0, 0xc8200b01c0, 0x29, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:143 +0x15a
net/http.(*Client).doFollowingRedirects(0x9587e0, 0xc8200b01c0, 0x83b3a8, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:380 +0xbc0
net/http.(*Client).Post(0x9587e0, 0xc82000b170, 0x29, 0x0, 0x0, 0x0, 0x0, 0xc8200112b0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:471 +0x107
net/http.Post(0xc82000b170, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:454 +0x7a
_/tmp/d20160126-5892-gv2pss.nextGeneration(0xc820016880, 0x0, 0x0)
	/tmp/d20160126-5892-gv2pss/solution_test.go:679 +0x9d
_/tmp/d20160126-5892-gv2pss.TestConcurrentOperation.func3(0xc8200110e0, 0xc82001e360, 0xc820016880, 0xc82007e120)
	/tmp/d20160126-5892-gv2pss/solution_test.go:560 +0x82
created by _/tmp/d20160126-5892-gv2pss.TestConcurrentOperation
	/tmp/d20160126-5892-gv2pss/solution_test.go:563 +0x1da

goroutine 42 [IO wait]:
net.runtime_pollWait(0x7fec76788760, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc8200c40d0, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc8200c40d0, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc8200c4070, 0xc820108000, 0x1000, 0x1000, 0x0, 0x7fec76783050, 0xc8200101c0)
	/usr/local/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc8200c2038, 0xc820108000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:172 +0xe4
net/http.noteEOFReader.Read(0x7fec76788ab8, 0xc8200c2038, 0xc8200ca058, 0xc820108000, 0x1000, 0x1000, 0xc8200c7380, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1370 +0x67
net/http.(*noteEOFReader).Read(0xc8200ae320, 0xc820108000, 0x1000, 0x1000, 0xc8200b22c0, 0x0, 0x0)
	<autogenerated>:126 +0xd0
bufio.(*Reader).fill(0xc8200c70e0)
	/usr/local/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).Peek(0xc8200c70e0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:132 +0xcc
net/http.(*persistConn).readLoop(0xc8200ca000)
	/usr/local/go/src/net/http/transport.go:876 +0xf7
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:685 +0xc78

goroutine 55 [IO wait]:
net.runtime_pollWait(0x7fec767885e0, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc820012760, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc820012760, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc820012700, 0xc820104000, 0x1000, 0x1000, 0x0, 0x7fec76783050, 0xc8200101c0)
	/usr/local/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc82002c0b0, 0xc820104000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:172 +0xe4
net/http.noteEOFReader.Read(0x7fec76788ab8, 0xc82002c0b0, 0xc8200b81b8, 0xc820104000, 0x1000, 0x1000, 0xc82001fe00, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1370 +0x67
net/http.(*noteEOFReader).Read(0xc82000ed80, 0xc820104000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	<autogenerated>:126 +0xd0
bufio.(*Reader).fill(0xc82001fb00)
	/usr/local/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).Peek(0xc82001fb00, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:132 +0xcc
net/http.(*persistConn).readLoop(0xc8200b8160)
	/usr/local/go/src/net/http/transport.go:876 +0xf7
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:685 +0xc78

goroutine 57 [IO wait]:
net.runtime_pollWait(0x7fec76787fe0, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc8200c4530, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc8200c4530, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc8200c44d0, 0xc820120000, 0x1000, 0x1000, 0x0, 0x7fec76783050, 0xc8200101c0)
	/usr/local/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc82002c0b8, 0xc820120000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:172 +0xe4
net/http.noteEOFReader.Read(0x7fec76788ab8, 0xc82002c0b8, 0xc8200ca5d8, 0xc820120000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1370 +0x67
net/http.(*noteEOFReader).Read(0xc82000ee80, 0xc820120000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	<autogenerated>:126 +0xd0
bufio.(*Reader).fill(0xc82001fe60)
	/usr/local/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).Peek(0xc82001fe60, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:132 +0xcc
net/http.(*persistConn).readLoop(0xc8200ca580)
	/usr/local/go/src/net/http/transport.go:876 +0xf7
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:685 +0xc78

goroutine 53 [runnable]:
net.runtime_pollWait(0x7fec76788520, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc8200c41b0, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc8200c41b0, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc8200c4150, 0xc820100000, 0x1000, 0x1000, 0x0, 0x7fec76783050, 0xc8200101c0)
	/usr/local/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc82002c0a8, 0xc820100000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:172 +0xe4
net/http.noteEOFReader.Read(0x7fec76788ab8, 0xc82002c0a8, 0xc8200ca108, 0xc820100000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1370 +0x67
net/http.(*noteEOFReader).Read(0xc82000ed00, 0xc820100000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	<autogenerated>:126 +0xd0
bufio.(*Reader).fill(0xc82001f9e0)
	/usr/local/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).Peek(0xc82001f9e0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:132 +0xcc
net/http.(*persistConn).readLoop(0xc8200ca0b0)
	/usr/local/go/src/net/http/transport.go:876 +0xf7
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:685 +0xc78

goroutine 33 [IO wait]:
net.runtime_pollWait(0x7fec767883a0, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc8200c4290, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc8200c4290, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc8200c4230, 0xc8200fc000, 0x1000, 0x1000, 0x0, 0x7fec76783050, 0xc8200101c0)
	/usr/local/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc82002c098, 0xc8200fc000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:172 +0xe4
net/http.noteEOFReader.Read(0x7fec76788ab8, 0xc82002c098, 0xc8200ca1b8, 0xc8200fc000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1370 +0x67
net/http.(*noteEOFReader).Read(0xc82000ec00, 0xc8200fc000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	<autogenerated>:126 +0xd0
bufio.(*Reader).fill(0xc82001f7a0)
	/usr/local/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).Peek(0xc82001f7a0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:132 +0xcc
net/http.(*persistConn).readLoop(0xc8200ca160)
	/usr/local/go/src/net/http/transport.go:876 +0xf7
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:685 +0xc78

goroutine 27 [runnable]:
net.runtime_pollWait(0x7fec76788160, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc8200c4370, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc8200c4370, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc8200c4310, 0xc8200ee000, 0x1000, 0x1000, 0x0, 0x7fec76783050, 0xc8200101c0)
	/usr/local/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc82002c080, 0xc8200ee000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:172 +0xe4
net/http.noteEOFReader.Read(0x7fec76788ab8, 0xc82002c080, 0xc8200ca318, 0xc8200ee000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1370 +0x67
net/http.(*noteEOFReader).Read(0xc82000ea60, 0xc8200ee000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	<autogenerated>:126 +0xd0
bufio.(*Reader).fill(0xc82001f3e0)
	/usr/local/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).Peek(0xc82001f3e0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:132 +0xcc
net/http.(*persistConn).readLoop(0xc8200ca2c0)
	/usr/local/go/src/net/http/transport.go:876 +0xf7
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:685 +0xc78

goroutine 28 [select]:
net/http.(*persistConn).writeLoop(0xc8200ca2c0)
	/usr/local/go/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:686 +0xc9d

goroutine 59 [runnable]:
net.runtime_pollWait(0x7fec767880a0, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc8200c4450, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc8200c4450, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc8200c43f0, 0xc82012a000, 0x1000, 0x1000, 0x0, 0x7fec76783050, 0xc8200101c0)
	/usr/local/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc82002c0c0, 0xc82012a000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:172 +0xe4
net/http.noteEOFReader.Read(0x7fec76788ab8, 0xc82002c0c0, 0xc8200ca478, 0xc82012a000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1370 +0x67
net/http.(*noteEOFReader).Read(0xc82000ef00, 0xc82012a000, 0x1000, 0x1000, 0xc82002d018, 0x0, 0x0)
	<autogenerated>:126 +0xd0
bufio.(*Reader).fill(0xc820128000)
	/usr/local/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).Peek(0xc820128000, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:132 +0xcc
net/http.(*persistConn).readLoop(0xc8200ca420)
	/usr/local/go/src/net/http/transport.go:876 +0xf7
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:685 +0xc78

goroutine 50 [select]:
net/http.(*persistConn).writeLoop(0xc8200ca160)
	/usr/local/go/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:686 +0xc9d

goroutine 54 [select]:
net/http.(*persistConn).writeLoop(0xc8200ca0b0)
	/usr/local/go/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:686 +0xc9d

goroutine 40 [IO wait]:
net.runtime_pollWait(0x7fec767886a0, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc820012680, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc820012680, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc820012620, 0xc820102000, 0x1000, 0x1000, 0x0, 0x7fec76783050, 0xc8200101c0)
	/usr/local/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc8200c2030, 0xc820102000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:172 +0xe4
net/http.noteEOFReader.Read(0x7fec76788ab8, 0xc8200c2030, 0xc8200b8108, 0xc820102000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1370 +0x67
net/http.(*noteEOFReader).Read(0xc8200ae2a0, 0xc820102000, 0x1000, 0x1000, 0xc8200c33e0, 0x0, 0x0)
	<autogenerated>:126 +0xd0
bufio.(*Reader).fill(0xc8200c6fc0)
	/usr/local/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).Peek(0xc8200c6fc0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:132 +0xcc
net/http.(*persistConn).readLoop(0xc8200b80b0)
	/usr/local/go/src/net/http/transport.go:876 +0xf7
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:685 +0xc78

goroutine 41 [select]:
net/http.(*persistConn).writeLoop(0xc8200b80b0)
	/usr/local/go/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:686 +0xc9d

goroutine 56 [select]:
net/http.(*persistConn).writeLoop(0xc8200b8160)
	/usr/local/go/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:686 +0xc9d

goroutine 43 [select]:
net/http.(*persistConn).writeLoop(0xc8200ca000)
	/usr/local/go/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:686 +0xc9d

goroutine 58 [select]:
net/http.(*persistConn).writeLoop(0xc8200ca580)
	/usr/local/go/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:686 +0xc9d

goroutine 47 [runnable]:
_/tmp/d20160126-5892-gv2pss.(*Board).StayAlive(0xc82000aea8, 0xfffffffffffffffe, 0x109358, 0x0)
	/tmp/d20160126-5892-gv2pss/solution.go:64 +0x139
_/tmp/d20160126-5892-gv2pss.(*GameOfLife).Evolve(0xc82000aea0)
	/tmp/d20160126-5892-gv2pss/solution.go:94 +0xc6
_/tmp/d20160126-5892-gv2pss.EvolveHandler(0x7fec76788d50, 0xc8200b8580, 0xc8200b0700)
	/tmp/d20160126-5892-gv2pss/solution.go:168 +0x23
_/tmp/d20160126-5892-gv2pss.(*GameOfLifeHandler).ServeHTTP(0xc82000e7a0, 0x7fec76788d50, 0xc8200b8580, 0xc8200b0700)
	/tmp/d20160126-5892-gv2pss/solution.go:207 +0x203
net/http/httptest.(*waitGroupHandler).ServeHTTP(0xc82000e820, 0x7fec76788d50, 0xc8200b8580, 0xc8200b0700)
	/usr/local/go/src/net/http/httptest/server.go:200 +0xc2
net/http.serverHandler.ServeHTTP(0xc82001e300, 0x7fec76788d50, 0xc8200b8580, 0xc8200b0700)
	/usr/local/go/src/net/http/server.go:1862 +0x19e
net/http.(*conn).serve(0xc8200ca6e0)
	/usr/local/go/src/net/http/server.go:1361 +0xbee
created by net/http.(*Server).Serve
	/usr/local/go/src/net/http/server.go:1910 +0x3f6

goroutine 48 [runnable]:
net.runtime_pollWait(0x7fec76787da0, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc8200c47d0, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc8200c47d0, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc8200c4770, 0xc820126000, 0x1000, 0x1000, 0x0, 0x7fec76783050, 0xc8200101c0)
	/usr/local/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc8200c2058, 0xc820126000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:172 +0xe4
net/http.(*liveSwitchReader).Read(0xc8200ca7d8, 0xc820126000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/server.go:219 +0xa4
io.(*LimitedReader).Read(0xc8200ae560, 0xc820126000, 0x1000, 0x1000, 0x11, 0x0, 0x0)
	/usr/local/go/src/io/io.go:427 +0xbd
bufio.(*Reader).fill(0xc8200c7500)
	/usr/local/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).ReadSlice(0xc8200c7500, 0xc81ffdef0a, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:328 +0x21a
bufio.(*Reader).ReadLine(0xc8200c7500, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:357 +0x53
net/textproto.(*Reader).readLineSlice(0xc820208ff0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/textproto/reader.go:55 +0x81
net/textproto.(*Reader).ReadLine(0xc820208ff0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/textproto/reader.go:36 +0x40
net/http.ReadRequest(0xc8200c7500, 0xc820421dc0, 0x0, 0x0)
	/usr/local/go/src/net/http/request.go:653 +0xb6
net/http.(*conn).readRequest(0xc8200ca790, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/server.go:633 +0x32f
net/http.(*conn).serve(0xc8200ca790)
	/usr/local/go/src/net/http/server.go:1319 +0x727
created by net/http.(*Server).Serve
	/usr/local/go/src/net/http/server.go:1910 +0x3f6

goroutine 60 [select]:
net/http.(*persistConn).writeLoop(0xc8200ca420)
	/usr/local/go/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:686 +0xc9d

goroutine 49 [runnable]:
_/tmp/d20160126-5892-gv2pss.(*Board).StayAlive(0xc82000aea8, 0xfffffffffffffffe, 0x10bdcc, 0x0)
	/tmp/d20160126-5892-gv2pss/solution.go:69 +0x1cb
_/tmp/d20160126-5892-gv2pss.(*GameOfLife).Evolve(0xc82000aea0)
	/tmp/d20160126-5892-gv2pss/solution.go:94 +0xc6
_/tmp/d20160126-5892-gv2pss.EvolveHandler(0x7fec76788d50, 0xc8200cafd0, 0xc8200be700)
	/tmp/d20160126-5892-gv2pss/solution.go:168 +0x23
_/tmp/d20160126-5892-gv2pss.(*GameOfLifeHandler).ServeHTTP(0xc82000e7a0, 0x7fec76788d50, 0xc8200cafd0, 0xc8200be700)
	/tmp/d20160126-5892-gv2pss/solution.go:207 +0x203
net/http/httptest.(*waitGroupHandler).ServeHTTP(0xc82000e820, 0x7fec76788d50, 0xc8200cafd0, 0xc8200be700)
	/usr/local/go/src/net/http/httptest/server.go:200 +0xc2
net/http.serverHandler.ServeHTTP(0xc82001e300, 0x7fec76788d50, 0xc8200cafd0, 0xc8200be700)
	/usr/local/go/src/net/http/server.go:1862 +0x19e
net/http.(*conn).serve(0xc8200ca840)
	/usr/local/go/src/net/http/server.go:1361 +0xbee
created by net/http.(*Server).Serve
	/usr/local/go/src/net/http/server.go:1910 +0x3f6

goroutine 66 [IO wait]:
net.runtime_pollWait(0x7fec76787c20, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc8200c48b0, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc8200c48b0, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc8200c4850, 0xc820136000, 0x1000, 0x1000, 0x0, 0x7fec76783050, 0xc8200101c0)
	/usr/local/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc8200c2068, 0xc820136000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:172 +0xe4
net/http.(*liveSwitchReader).Read(0xc8200ca938, 0xc820136000, 0x1000, 0x1000, 0xc820137000, 0x0, 0x0)
	/usr/local/go/src/net/http/server.go:219 +0xa4
io.(*LimitedReader).Read(0xc8200ae620, 0xc820136000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/io/io.go:427 +0xbd
bufio.(*Reader).fill(0xc8200c75c0)
	/usr/local/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).Peek(0xc8200c75c0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:132 +0xcc
net/http.(*conn).readRequest(0xc8200ca8f0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/server.go:629 +0x2bb
net/http.(*conn).serve(0xc8200ca8f0)
	/usr/local/go/src/net/http/server.go:1319 +0x727
created by net/http.(*Server).Serve
	/usr/local/go/src/net/http/server.go:1910 +0x3f6

goroutine 68 [runnable]:
net.runtime_pollWait(0x7fec76787aa0, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc8200c4990, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc8200c4990, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc8200c4930, 0xc82013a000, 0x1000, 0x1000, 0x0, 0x7fec76783050, 0xc8200101c0)
	/usr/local/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc8200c2078, 0xc82013a000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:172 +0xe4
net/http.(*liveSwitchReader).Read(0xc8200caa98, 0xc82013a000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/server.go:219 +0xa4
io.(*LimitedReader).Read(0xc8200ae6e0, 0xc82013a000, 0x1000, 0x1000, 0x11, 0x0, 0x0)
	/usr/local/go/src/io/io.go:427 +0xbd
bufio.(*Reader).fill(0xc8200c7680)
	/usr/local/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).ReadSlice(0xc8200c7680, 0xc81ffdef0a, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:328 +0x21a
bufio.(*Reader).ReadLine(0xc8200c7680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:357 +0x53
net/textproto.(*Reader).readLineSlice(0xc8200baab0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/textproto/reader.go:55 +0x81
net/textproto.(*Reader).ReadLine(0xc8200baab0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/textproto/reader.go:36 +0x40
net/http.ReadRequest(0xc8200c7680, 0xc820421b20, 0x0, 0x0)
	/usr/local/go/src/net/http/request.go:653 +0xb6
net/http.(*conn).readRequest(0xc8200caa50, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/server.go:633 +0x32f
net/http.(*conn).serve(0xc8200caa50)
	/usr/local/go/src/net/http/server.go:1319 +0x727
created by net/http.(*Server).Serve
	/usr/local/go/src/net/http/server.go:1910 +0x3f6

goroutine 70 [IO wait]:
net.runtime_pollWait(0x7fec75742030, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc8200c4a70, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc8200c4a70, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc8200c4a10, 0xc820142000, 0x1000, 0x1000, 0x0, 0x7fec76783050, 0xc8200101c0)
	/usr/local/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc8200c2088, 0xc820142000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:172 +0xe4
net/http.(*liveSwitchReader).Read(0xc8200cabf8, 0xc820142000, 0x1000, 0x1000, 0xc820143000, 0x0, 0x0)
	/usr/local/go/src/net/http/server.go:219 +0xa4
io.(*LimitedReader).Read(0xc8200ae7a0, 0xc820142000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/io/io.go:427 +0xbd
bufio.(*Reader).fill(0xc8200c7740)
	/usr/local/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).Peek(0xc8200c7740, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:132 +0xcc
net/http.(*conn).readRequest(0xc8200cabb0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/server.go:629 +0x2bb
net/http.(*conn).serve(0xc8200cabb0)
	/usr/local/go/src/net/http/server.go:1319 +0x727
created by net/http.(*Server).Serve
	/usr/local/go/src/net/http/server.go:1910 +0x3f6

goroutine 72 [IO wait]:
net.runtime_pollWait(0x7fec75741eb0, 0x72, 0xc8200101c0)
	/usr/local/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc8200c4b50, 0x72, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc8200c4b50, 0x0, 0x0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc8200c4af0, 0xc820146000, 0x1000, 0x1000, 0x0, 0x7fec76783050, 0xc8200101c0)
	/usr/local/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc8200c2098, 0xc820146000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:172 +0xe4
net/http.(*liveSwitchReader).Read(0xc8200cad58, 0xc820146000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/server.go:219 +0xa4
io.(*LimitedReader).Read(0xc8200ae860, 0xc820146000, 0x1000, 0x1000, 0x11, 0x0, 0x0)
	/usr/local/go/src/io/io.go:427 +0xbd
bufio.(*Reader).fill(0xc8200c7800)
	/usr/local/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).ReadSlice(0xc8200c7800, 0xc81ffddc0a, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:328 +0x21a
bufio.(*Reader).ReadLine(0xc8200c7800, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/bufio/bufio.go:357 +0x53
net/textproto.(*Reader).readLineSlice(0xc8200bb170, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/textproto/reader.go:55 +0x81
net/textproto.(*Reader).ReadLine(0xc8200bb170, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/textproto/reader.go:36 +0x40
net/http.ReadRequest(0xc8200c7800, 0xc8204461c0, 0x0, 0x0)
	/usr/local/go/src/net/http/request.go:653 +0xb6
net/http.(*conn).readRequest(0xc8200cad10, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/server.go:633 +0x32f
net/http.(*conn).serve(0xc8200cad10)
	/usr/local/go/src/net/http/server.go:1319 +0x727
created by net/http.(*Server).Serve
	/usr/local/go/src/net/http/server.go:1910 +0x3f6

goroutine 73 [runnable]:
encoding/json.stateInString(0xc8203fb638, 0x22, 0x0)
	/usr/local/go/src/encoding/json/scanner.go:331
encoding/json.(*Decoder).readValue(0xc8203fb520, 0x1, 0x0, 0x0)
	/usr/local/go/src/encoding/json/stream.go:93 +0x172
encoding/json.(*Decoder).Decode(0xc8203fb520, 0x698a40, 0xc82041cfa0, 0x0, 0x0)
	/usr/local/go/src/encoding/json/stream.go:57 +0x159
_/tmp/d20160126-5892-gv2pss.AddCellsHandler(0x7fec76788d50, 0xc8204329a0, 0xc8204155e0)
	/tmp/d20160126-5892-gv2pss/solution.go:155 +0x17d
_/tmp/d20160126-5892-gv2pss.(*GameOfLifeHandler).ServeHTTP(0xc82000e7a0, 0x7fec76788d50, 0xc8204329a0, 0xc8204155e0)
	/tmp/d20160126-5892-gv2pss/solution.go:207 +0x203
net/http/httptest.(*waitGroupHandler).ServeHTTP(0xc82000e820, 0x7fec76788d50, 0xc8204329a0, 0xc8204155e0)
	/usr/local/go/src/net/http/httptest/server.go:200 +0xc2
net/http.serverHandler.ServeHTTP(0xc82001e300, 0x7fec76788d50, 0xc8204329a0, 0xc8204155e0)
	/usr/local/go/src/net/http/server.go:1862 +0x19e
net/http.(*conn).serve(0xc8200cadc0)
	/usr/local/go/src/net/http/server.go:1361 +0xbee
created by net/http.(*Server).Serve
	/usr/local/go/src/net/http/server.go:1910 +0x3f6
exit status 2
FAIL	_/tmp/d20160126-5892-gv2pss	1.036s

История (1 версия и 0 коментара)

Екатерина обнови решението на 26.01.2016 11:44 (преди над 2 години)

+package main
+
+import (
+ "encoding/json"
+ "net/http"
+ "strconv"
+)
+
+var gol *GameOfLife
+
+type Cell struct {
+ X int64 `json:"x"`
+ Y int64 `json:"y"`
+}
+
+type Board struct {
+ cells map[Cell]bool
+ xMin, xMax int64
+ yMin, yMax int64
+}
+
+func (b *Board) IsAlive(x, y int64) bool {
+ cell := Cell{x, y}
+ _, ok := b.cells[cell]
+ return ok
+}
+
+func (b *Board) Add(x, y int64) {
+ cell := Cell{x, y}
+ b.cells[cell] = true
+
+ if b.xMin >= cell.X {
+ b.xMin = cell.X - 1
+ }
+ if b.yMin >= cell.Y {
+ b.yMin = cell.Y - 1
+ }
+
+ if b.xMax <= cell.X {
+ b.xMax = cell.X + 1
+ }
+ if b.yMax <= cell.Y {
+ b.yMax = cell.Y + 1
+ }
+}
+
+func (b *Board) GetAlive() [][2]int64 {
+ var alive [][2]int64
+ for cell := range b.cells {
+ alive = append(alive, [2]int64{cell.X, cell.Y})
+ }
+ return alive
+}
+
+func (b *Board) StayAlive(x, y int64) bool {
+ deltas := [][2]int64{
+ {-1, -1}, {0, -1}, {1, -1}, {1, 0},
+ {1, 1}, {0, 1}, {-1, 1}, {-1, 0},
+ }
+
+ var neighbours int
+ for _, delta := range deltas {
+ neighbour := Cell{x + delta[0], y + delta[1]}
+ if _, ok := b.cells[neighbour]; ok {
+ neighbours++
+ }
+ }
+
+ isAlive := b.IsAlive(x, y)
+ if neighbours == 2 && isAlive || neighbours == 3 {
+ return true
+ }
+ return false
+}
+
+type GameOfLife struct {
+ generation int64
+ board Board
+}
+
+func NewGameOfLife(coordinates [][2]int64) *GameOfLife {
+ newBoard := Board{cells: make(map[Cell]bool)}
+ g := &GameOfLife{board: newBoard}
+ for _, coord := range coordinates {
+ g.board.Add(coord[0], coord[1])
+ }
+ return g
+}
+
+func (g *GameOfLife) Evolve() {
+ newBoard := Board{cells: make(map[Cell]bool)}
+ for x := g.board.xMin; x <= g.board.xMax; x++ {
+ for y := g.board.yMin; y <= g.board.yMax; y++ {
+ if g.board.StayAlive(x, y) {
+ newBoard.Add(x, y)
+ }
+ }
+ }
+ g.board = newBoard
+ g.generation++
+}
+
+/* Handlers */
+
+type CellStatus struct {
+ Alive bool `json:"alive"`
+}
+
+func CellStatusHandler(w http.ResponseWriter, r *http.Request) {
+ q := r.URL.Query()
+ x, err := strconv.ParseInt(q.Get("x"), 10, 64)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ y, err := strconv.ParseInt(q.Get("y"), 10, 64)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ status := CellStatus{gol.board.IsAlive(x, y)}
+
+ js, err := json.Marshal(status)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+ w.Write(js)
+}
+
+type Generation struct {
+ Generation int64 `json:"generation"`
+ Living [][2]int64 `json:"living"`
+}
+
+func GenerationHandler(w http.ResponseWriter, r *http.Request) {
+ generation := Generation{gol.generation, gol.board.GetAlive()}
+ js, err := json.Marshal(generation)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+ w.Write(js)
+}
+
+func AddCellsHandler(w http.ResponseWriter, r *http.Request) {
+ cells := make([]Cell, 0)
+ decoder := json.NewDecoder(r.Body)
+ err := decoder.Decode(&cells)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ for _, c := range cells {
+ gol.board.Add(c.X, c.Y)
+ }
+ w.WriteHeader(http.StatusCreated)
+}
+
+func EvolveHandler(w http.ResponseWriter, r *http.Request) {
+ gol.Evolve()
+ w.WriteHeader(http.StatusNoContent)
+}
+
+func ResetHandler(w http.ResponseWriter, r *http.Request) {
+ gol = NewGameOfLife([][2]int64{})
+ w.WriteHeader(http.StatusNoContent)
+}
+
+type Route struct {
+ Path string
+ Method string
+ handler http.HandlerFunc
+}
+
+type GameOfLifeHandler struct {
+ Routes []Route
+}
+
+func NewGameOfLifeHandler(coordinates [][2]int64) *GameOfLifeHandler {
+ gol = NewGameOfLife(coordinates)
+ routes := []Route{
+ Route{"/cell/status/", "GET", CellStatusHandler},
+ Route{"/generation/", "GET", GenerationHandler},
+ Route{"/cells/", "POST", AddCellsHandler},
+ Route{"/generation/evolve/", "POST", EvolveHandler},
+ Route{"/reset/", "POST", ResetHandler},
+ }
+ return &GameOfLifeHandler{routes}
+}
+
+func (golh *GameOfLifeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ path := r.URL.EscapedPath()
+
+ var found bool
+ for _, route := range golh.Routes {
+ if route.Path == path {
+ found = true
+ if route.Method == r.Method {
+ route.handler(w, r)
+ } else {
+ w.WriteHeader(http.StatusMethodNotAllowed)
+ }
+ }
+ }
+
+ if !found {
+ w.WriteHeader(http.StatusNotFound)
+ }
+}