func main() {
points := [][]int{{2, 2}, {2, 3}, {2, 7}, {6, 6}, {5, 2}}
routes := [][]int{{2, 3, 4, 5}, {1, 3, 4, 5}}
fmt.Println(solution(points, routes))
}
func solution(points [][]int, routes [][]int) int {
// 충돌 횟수
result := 0
// 경과 시간
cnt := 0
// 각각의 초단위 로봇별 지점 확인 key : [로봇넘버] value : 로봇의 좌표
pointsMap := make(map[int][2]int, 0)
// [지나간 포인트의 갯수,지금 가고 있는 방향]
currentHeadingRoute := make([][2]int, 0)
for i := 0; i < len(routes); i++ {
initPointAndDirection := [2]int{2, routes[i][1]}
currentHeadingRoute = append(currentHeadingRoute, initPointAndDirection)
var tmp [2]int
tmp[0] = points[routes[i][0]-1][0]
tmp[1] = points[routes[i][0]-1][1]
pointsMap[i] = tmp
}
pointChan := make(chan [][2]int)
//cnt 를 늘리는 루프 설정
go func() {
for {
// 0초일때 예외 설정
if cnt == 0 {
tmpArray := make([][2]int, 0)
for _, value := range pointsMap {
tmpArray = append(tmpArray, value)
}
pointChan <- tmpArray
cnt++
continue
}
// 시간별 각 로봇의 위치 계산
tmpArray := make([][2]int, 0)
outerLoop:
for i := 0; i < len(routes); i++ {
//time.Sleep(time.Second)
previousPoint := pointsMap[i]
var destinationPoint [2]int
destinationPoint[0] = points[currentHeadingRoute[i][1]-1][0]
destinationPoint[1] = points[currentHeadingRoute[i][1]-1][1]
currentPoint := previousPoint
// 현재 지점과 도착지점이 같을떄
// 없다면 continue 로 escape
if currentPoint == destinationPoint {
// destinationPoint 가 마지막인지 아닌지
if len(routes[i]) == currentHeadingRoute[i][0] {
continue outerLoop
} else {
// 지나간 포인트의 갯수 + 1
currentHeadingRoute[i][0] = currentHeadingRoute[i][0] + 1
// 현재 지나갈 방향 다시 업데이트
currentHeadingRoute[i][1] = routes[i][currentHeadingRoute[i][0]-1]
// 현재 가야하는 좌표 업데이트
destinationPoint[0] = points[currentHeadingRoute[i][1]-1][0]
destinationPoint[1] = points[currentHeadingRoute[i][1]-1][1]
}
}
// x 축 체크 destinationPoint[0] = x 축 , [1] = y축
if previousPoint[0] != destinationPoint[0] {
// 목적지의 x 축이 더 작다면 -
if previousPoint[0] > destinationPoint[0] {
currentPoint[0] = previousPoint[0] - 1
} else {
// 목적지의 x 축이 더 크다면 +
currentPoint[0] = previousPoint[0] + 1
}
tmpArray = append(tmpArray, currentPoint)
// 현재 for 문 escape
//fmt.Println("x축 이후")
// 현재 로봇의 위치 업데이트
pointsMap[i] = currentPoint
//fmt.Println(fmt.Sprintf("%d초에 %d번쨰 로봇의 위치", cnt, i+1), currentPoint)
continue
}
// y 축 체크
if previousPoint[1] != destinationPoint[1] {
// 목적지의 y 축이 더 작다면 -
if previousPoint[1] > destinationPoint[1] {
currentPoint[1] = previousPoint[1] - 1
} else {
// 목적지의 y 축이 더 크다면 +
currentPoint[1] = previousPoint[1] + 1
}
tmpArray = append(tmpArray, currentPoint)
// 현재 for 문 escape
//fmt.Println("y축 이후")
// 현재 로봇의 위치 업데이트
pointsMap[i] = currentPoint
//fmt.Println(fmt.Sprintf("%d초에 %d번쨰 로봇의 위치", cnt, i+1), currentPoint)
continue
}
}
//
if len(tmpArray) == 0 {
close(pointChan)
break
}
pointChan <- tmpArray
cnt++
}
}()
for {
select {
case tmpPoints, ok := <-pointChan:
if !ok {
return result
}
// map을 통해 몇번의 충돌이 있었는지 계산
duplicateMap := make(map[[2]int]int, 0)
// map key : 현재 로봇의 위치 , value : 겹쳐있는 숫자
for _, value := range tmpPoints {
if _, exists := duplicateMap[value]; !exists {
duplicateMap[value] = 1
} else {
duplicateMap[value] = duplicateMap[value] + 1
}
}
// value 가 2 이상일 경우 모두 충돌 간주
for _, value := range duplicateMap {
if value >= 2 {
result = result + 1
}
}
}
}
}