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