package main import ( "math" log "github.com/sirupsen/logrus" ) const ( SPACE = '.' V_MIRROR = '|' H_MIRROR = '-' F_MIRROR = '/' B_MIRROR = '\\' ) const ( N = iota S W E ) // only for debugging var steps int var dirs = []string{"N", "S", "W", "E"} func runner(move *mover, lines []string) { for steps < math.MaxInt && move.Y >= 0 && move.Y < len(lines) && move.X >= 0 && move.X < len(lines[move.Y]) { //log.Debug(move.X, ":", move.Y, " ", string(lines[move.Y][move.X]), " ", dirs[move.direction()]) //log.Debug(move.nodes) if nodeInNodes(move.node, move.nodes) { log.Debug(move.node, " in nodes, breaking.") break } move.nodes = append(move.nodes, move.node) switch lines[move.Y][move.X] { case SPACE: // '.' //log.Debug("we have space and direction is ", dirs[move.direction()]) move.move() case F_MIRROR: // '/' //log.Debug("we have forward mirror and direction is ", dirs[move.direction()]) switch move.direction() { case N: move.setDirection(E) case S: move.setDirection(W) case W: move.setDirection(S) case E: move.setDirection(N) } //log.Debug("step: ", steps, " ", string(F_MIRROR), " direction changed to ", dirs[move.direction()]) move.move() case B_MIRROR: // '\' //log.Debug("we have backwards mirror and direction is ", dirs[move.direction()]) switch move.direction() { case N: move.setDirection(W) case S: move.setDirection(E) case W: move.setDirection(N) case E: move.setDirection(S) } //log.Debug("step: ", steps, " ", string(B_MIRROR), " direction changed to ", dirs[move.direction()]) move.move() case V_MIRROR: // '|' //log.Debug("we have vertical mirror and direction is ", dirs[move.direction()]) if move.direction() == N || move.direction() == S { move.move() continue } if move.direction() == W || move.direction() == E { c := move.coords move.setDirection(N) move.move() runner(move, lines) move.coords = c move.setDirection(S) move.move() runner(move, lines) } case H_MIRROR: // '-' //log.Debug("we have horizontal mirror and direction is ", dirs[move.direction()]) if move.direction() == W || move.direction() == E { move.move() continue } if move.direction() == N || move.direction() == S { c := move.coords move.setDirection(W) move.move() runner(move, lines) move.coords = c move.setDirection(E) move.move() runner(move, lines) } default: log.Fatal("unknown node") } } steps++ } // one func one(lines []string) int { move := newMover(newNode(0, 0, E)) runner(move, lines) if log.GetLevel() == log.DebugLevel { n := printDebug(move, lines) log.Debug("total: ", n) } return uniqueNodes(move) }