본문 바로가기

Go

프로그래머스 2024 KAKAO WINTER INTERNSHIP 도넛과 막대 그래프

package main

import "fmt"

func main() {
	edges := [][]int{{2, 1}, {2, 5}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 3}, {3, 8}, {8, 9}, {9, 10}, {10, 11}, {11, 3}}
	//edges := [][]int{{4, 7}, {1, 12}, {8, 3}, {12, 7}, {4, 2}, {7, 11}, {4, 8}, {9, 6}, {10, 11}, {6, 10}, {3, 5}, {11, 1}, {5, 3}, {11, 9}, {3, 8}}
	fmt.Println(solution(edges))

}

func solution(edges [][]int) []int {

	result := make([]int, 4)

	edgesMap := make(map[int][]int)
	// 간선들을 map 에 저장
	for _, edge := range edges {
		start := edge[0]
		end := edge[1]
		edgesMap[start] = append(edgesMap[start], end)
	}

	fmt.Println(edgesMap)
	mapPointNum := make(map[int]int, 0)
	// 먼저 edges 중 edge[0] -> edge[1] 로 나가는 것들 카운트
	for _, edge := range edges {
		if value, ok := mapPointNum[edge[0]]; !ok {
			mapPointNum[edge[0]] = 1
		} else {
			mapPointNum[edge[0]] = value + 1
		}
	}

	// 나가는것들 중 value 가 제일 높은 값 가져온후
	var newNum, biggestValue int
	for _, value := range mapPointNum {
		if biggestValue < value {
			biggestValue = value

		}
	}

	// 새로운 맵 키에 해당 value 를 넣고 0 업데이트 한후
	calMap := make(map[int]int, 0)
	for key, value := range mapPointNum {
		if value == biggestValue {
			calMap[key] = 0
		}
	}

	// 그중에 기존 edges 에 나가는것 +1 들어오는것 -1
	for key, _ := range calMap {
		for _, edge := range edges {
			if edge[0] == key {
				calMap[key] = calMap[key] + 1
			}
			if edge[1] == key {
				calMap[key] = calMap[key] - 1
			}
		}
	}
	// 새로생긴 임의의 정점 업데이트
	biggestValue = 0
	for key, value := range calMap {
		if biggestValue < value {
			biggestValue = value
			newNum = key
		}
	}

	fmt.Println(calMap)
	fmt.Println("------------")
	fmt.Println("새로생긴 임의의 정점 :", newNum)

	result[0] = newNum
	// 임의의 정점에서 나온 방향들의 집합
	fmt.Println("임의의 정점에서 나온 방향 맵 : ", edgesMap[newNum])

	// 방향들을 시작으로 잡고 그래프 순환
	for _, start := range edgesMap[newNum] {
		fmt.Println("그 방향의 도착지에 대한 기존 방향:", start)

		// tmpArray 의 길이가 2인경우는 무조건 8자 모양 그래프
		if len(edgesMap[start]) == 2 {
			result[3] = result[3] + 1
			continue
		}
		// tmpArray 의 길이가 0인경우는 나가는 방향이 없기에 크기가 1인 막대 모양 그래프
		if len(edgesMap[start]) == 0 {
			result[2] = result[2] + 1
			continue
		}

		// tmpArray 의 길이가 1인 경우
		if len(edgesMap[start]) == 1 {

			// 도넛모양 그래프인 경우
			// 1. 크기가 1인 도넛모양 그래프
			if start == edgesMap[start][0] {
				result[1] = result[1] + 1
				continue
			}

			mapCount := make(map[int]bool)

			shape := recursive(edgesMap, start, edgesMap[start][0], mapCount)
			result[shape] = result[shape] + 1

		}

	}

	return result
}

func recursive(edgesMap map[int][]int, current, next int, mapCount map[int]bool) int {
	fmt.Println("현재지점:", current, "다음지점:", next)
	mapCount[current] = true

	// 그 다음이 가진 맵의 value 가 2개면
	if len(edgesMap[next]) == 2 {
		return 3
	}
	// 그 다음이 가진 맵의 value 가 0개면
	if len(edgesMap[next]) == 0 {
		return 2
	}
	// 끝이 없는경우 mapCount 에 결국 걸림, 도넛모양 result[1]
	if _, ok := mapCount[next]; ok {
		return 1
	}

	// 그 다음이 가진 맵의 value 가 1개면 순환
	return recursive(edgesMap, next, edgesMap[next][0], mapCount)
}