package one import ( "strings" ) type graph struct { robot point boxes map[point]struct{} data []string } func newGraph() *graph { return &graph{boxes: make(map[point]struct{})} } func (g *graph) String() string { return strings.Join(g.data, "\n") } func (g *graph) valueAt(point point) rune { return rune(g.data[point.y][point.x]) } func (g *graph) updateRobot(dir direction) { new := neighbours(g.robot)[dir] g.updateEach(g.robot, '.') g.updateEach(new, '@') g.robot = new } func (g *graph) updateBox(point point, dir direction) { g.deleteBox(point) g.addBox(neighbours(point)[dir]) } func (g *graph) deleteBox(point point) { delete(g.boxes, point) g.updateEach(point, '.') } func (g *graph) addBox(point point) { g.boxes[point] = struct{}{} g.updateEach(point, 'O') } func (g *graph) updateEach(point point, r rune) { g.data[point.y] = replaceAtIndex(g.data[point.y], r, point.x) }