package main

import (
	"bufio"
	"log"
	"os"
	"strings"
)

type coord [2]int

type ocean struct {
	easts  []coord
	souths []coord
	grid   [][]byte
}

func (o ocean) String() string {
	ret := strings.Builder{}
	ret.WriteByte('\n')
	for _, line := range o.grid {
		for _, elem := range line {
			ret.WriteByte(elem)
		}
		ret.WriteByte('\n')
	}
	return ret.String()
}

func main() {
	if err := myMain(); err != nil {
		log.Println(err)
	}
}

func myMain() error {
	m, err := parseInput("input.txt")
	if err != nil {
		return err
	}

	log.Println(solveFirst(m))

	return nil
}

func solveFirst(o ocean) int {
	var steps int
	for ; ; steps++ {
		e := o.moveEast()
		s := o.moveSouth()
		if e == false && s == false {
			break
		}
	}

	return steps + 1
}

func (o ocean) moveSouth() bool {
	toDot := []coord{}
	toV := []coord{}
	for sIter, sCoord := range o.souths {
		down := (sCoord[0] + 1) % len(o.grid)
		if o.grid[down][sCoord[1]] == '.' {
			// log.Println(sIter, sCoord, "can move to south", down)
			o.souths[sIter] = [2]int{down, sCoord[1]}
			// o.grid[sCoord[0]][sCoord[1]] = '.'
			// o.grid[down][sCoord[1]] = 'v'
			toDot = append(toDot, coord{sCoord[0], sCoord[1]})
			toV = append(toV, coord{down, sCoord[1]})
		}
	}

	if len(toDot) == 0 && len(toV) == 0 {
		return false
	}

	for _, d := range toDot {
		o.grid[d[0]][d[1]] = '.'
	}
	for _, v := range toV {
		o.grid[v[0]][v[1]] = 'v'
	}

	return true
}

func (o ocean) moveEast() bool {
	toDot := []coord{}
	toR := []coord{}
	for eIter, eCoord := range o.easts {
		right := (eCoord[1] + 1) % len(o.grid[0])
		if o.grid[eCoord[0]][right] == '.' {
			// log.Println(eIter, eCoord, "can move to east", right)
			o.easts[eIter] = [2]int{eCoord[0], right}
			// o.grid[eCoord[0]][eCoord[1]] = '.'
			// o.grid[eCoord[0]][right] = '>'
			toDot = append(toDot, coord{eCoord[0], eCoord[1]})
			toR = append(toR, coord{eCoord[0], right})
		}
	}
	if len(toDot) == 0 && len(toR) == 0 {
		return false
	}

	for _, d := range toDot {
		o.grid[d[0]][d[1]] = '.'
	}
	for _, v := range toR {
		o.grid[v[0]][v[1]] = '>'
	}

	return true
}

func parseInput(fileName string) (ocean, error) {
	ret := ocean{}
	fd, err := os.Open(fileName)
	if err != nil {
		return ret, err
	}
	defer fd.Close()

	buf := bufio.NewScanner(fd)
	for line := 0; buf.Scan(); line++ {
		l := make([]byte, len(buf.Text()))
		for col, elem := range buf.Text() {
			l[col] = byte(elem)
			if elem == '>' {
				ret.easts = append(ret.easts, coord{line, col})
			}
			if elem == 'v' {
				ret.souths = append(ret.souths, coord{line, col})
			}
		}
		ret.grid = append(ret.grid, l)
	}

	return ret, nil
}