161 lines
4.0 KiB
Go
161 lines
4.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
func findPosition(layout [][]string) []int {
|
|
position := []int{}
|
|
for i := range layout {
|
|
for j := range layout[i] {
|
|
if layout[i][j] == "^" {
|
|
position = append(position, i, j)
|
|
}
|
|
}
|
|
}
|
|
return position
|
|
}
|
|
|
|
func findObstacles(layout [][]string) [][]int {
|
|
positions := [][]int{}
|
|
for i := range layout {
|
|
for j := range layout[i] {
|
|
if layout[i][j] == "#" {
|
|
positions = append(positions, []int{i,j})
|
|
}
|
|
}
|
|
}
|
|
return positions
|
|
}
|
|
|
|
func calcPath(layout [][]string) ([][]int, bool) {
|
|
circle := false
|
|
direction := "up"
|
|
guardPosition:=findPosition(layout)
|
|
inBound := true
|
|
currentPosition := guardPosition
|
|
path := [][]int{currentPosition}
|
|
for inBound && !circle {
|
|
if direction == "up" {
|
|
if currentPosition[0] == 0 {
|
|
inBound = false
|
|
break
|
|
} else if layout[currentPosition[0]-1][currentPosition[1]] == "#" {
|
|
direction = "right"
|
|
continue
|
|
} else {
|
|
currentPosition = []int{currentPosition[0]-1, currentPosition[1]}
|
|
if checkCircle(path, currentPosition) {
|
|
circle = true
|
|
} else {
|
|
path = append(path, currentPosition)
|
|
}
|
|
}
|
|
}
|
|
if direction == "right" {
|
|
if currentPosition[1] == len(layout)-1 {
|
|
inBound = false
|
|
break
|
|
} else if layout[currentPosition[0]][currentPosition[1]+1] == "#" {
|
|
direction = "down"
|
|
continue
|
|
} else {
|
|
currentPosition = []int{currentPosition[0], currentPosition[1]+1}
|
|
if checkCircle(path, currentPosition) {
|
|
circle = true
|
|
} else {
|
|
path = append(path, currentPosition)
|
|
}
|
|
}
|
|
}
|
|
if direction == "down" {
|
|
if currentPosition[0] == len(layout)-1 {
|
|
inBound = false
|
|
break
|
|
} else if layout[currentPosition[0]+1][currentPosition[1]] == "#" {
|
|
direction = "left"
|
|
continue
|
|
} else {
|
|
currentPosition = []int{currentPosition[0]+1, currentPosition[1]}
|
|
if checkCircle(path, currentPosition) {
|
|
circle = true
|
|
} else {
|
|
path = append(path, currentPosition)
|
|
}
|
|
}
|
|
}
|
|
if direction == "left" {
|
|
if currentPosition[1] == 0 {
|
|
inBound = false
|
|
break
|
|
} else if layout[currentPosition[0]][currentPosition[1]-1] == "#" {
|
|
direction = "up"
|
|
continue
|
|
} else {
|
|
currentPosition = []int{currentPosition[0], currentPosition[1]-1}
|
|
if checkCircle(path, currentPosition) {
|
|
circle = true
|
|
} else {
|
|
path = append(path, currentPosition)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return path, circle
|
|
}
|
|
|
|
func checkCircle(path [][]int, position []int) bool {
|
|
result := false
|
|
for i:=1;i<len(path);i++ {
|
|
if path[i][0] == position[0] && path[i][1] == position[1] {
|
|
if i < len(path)-1 && path[i-1][0] == path[len(path)-1][0] && path[i-1][1] == path[len(path)-1][1] {
|
|
result = true
|
|
}
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func main() {
|
|
file, _ := os.Open("input")
|
|
defer file.Close()
|
|
scanner := bufio.NewScanner(file)
|
|
layout := [][]string{}
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
layout = append(layout, strings.Split(line, ""))
|
|
}
|
|
// fmt.Println(path)
|
|
// fmt.Println(len(path))
|
|
path, _ := calcPath(layout)
|
|
pathOccurances := make(map[[2]int]int)
|
|
for _, tuple := range path {
|
|
key := [2]int{tuple[0],tuple[1]}
|
|
pathOccurances[key]++
|
|
}
|
|
fmt.Println(len(pathOccurances))
|
|
circleSpots := [][]int{}
|
|
for i:=1;i<len(path);i++ {
|
|
if path[i][0] == path[0][0] && path[i][1] == path[0][1] {
|
|
continue
|
|
} else {
|
|
tempValue := layout[path[i][0]][path[i][1]]
|
|
layout[path[i][0]][path[i][1]] = "#"
|
|
_, circle := calcPath(layout)
|
|
if circle {
|
|
circleSpots = append(circleSpots, path[i])
|
|
}
|
|
layout[path[i][0]][path[i][1]] = tempValue
|
|
}
|
|
}
|
|
uniqueCircles := make(map[[2]int]int)
|
|
for _, tuple := range circleSpots {
|
|
key := [2]int{tuple[0],tuple[1]}
|
|
uniqueCircles[key]++
|
|
}
|
|
fmt.Println(len(uniqueCircles))
|
|
}
|