import Foundation
func solution(_ grid:[String]) -> [Int] {
var nodes: [[Node]] = []
(0..<grid.count).forEach { _ in // nodes 행 채우기
nodes.append([])
}
let args = grid.map { $0.map { String($0) } }
for (i, arg) in args.enumerated() {
for (j, str) in arg.enumerated() {
let node = Node(Node.NType(rawValue: str)!)
if i != 0 { // 첫 행이 아니라면
node.uNode = nodes[i - 1][j]
nodes[i - 1][j].dNode = node
if i == grid.count - 1 { // 마지막 행
node.dNode = nodes[0][j]
nodes[0][j].uNode = node
}
}
if j != 0 { // 첫 열이 아니라면
node.lNode = nodes[i][j - 1]
nodes[i][j - 1].rNode = node
if j == arg.count - 1 { // 마지막 열
node.rNode = nodes[i][0]
nodes[i][0].lNode = node
}
}
nodes[i].append(node)
}
}
var result: [Int] = []
nodes.forEach {
$0.forEach {
for direction in Node.Direction.allCases {
var count = 0
var nextDirection = direction
var nextNode = $0
while let args = nextNode.next(nextDirection) {
count += 1
nextDirection = args.0
nextNode = args.1
}
if count != 0 {
result.append(count)
}
}
}
}
result = result.sorted(by: <)
return result
}
class Node {
enum NType: String {
case S = "S"
case L = "L"
case R = "R"
}
enum Direction: CaseIterable {
case left
case right
case up
case down
// 다음에 갈 방향
func next(_ type: NType) -> Direction {
switch type {
case .S:
return self
case .L:
switch self {
case .left:
return .down
case .right:
return .up
case .up:
return .left
case .down:
return .right
}
case .R:
switch self {
case .left:
return .up
case .right:
return .down
case .up:
return .right
case .down:
return .left
}
}
}
}
let type: NType
// 한번 거친 노드는 nil 대입한다.
var lNode: Node? // 왼쪽 노드
var rNode: Node? // 오른쪽 노드
var uNode: Node? // 위쪽 노드
var dNode: Node? // 아래쪽 노드
init(_ type: NType) {
self.type = type
self.lNode = self
self.rNode = self
self.uNode = self
self.dNode = self
}
func next(_ direction: Direction) -> (Direction, Node)? {
let nextDirection = direction.next(type)
switch nextDirection {
case .left:
if let nextNode = lNode {
lNode = nil
return (nextDirection, nextNode)
} else {
return nil // 한번 지나간적 있을경우
}
case .right:
if let nextNode = rNode {
rNode = nil
return (nextDirection, nextNode)
} else {
return nil
}
case .up:
if let nextNode = uNode {
uNode = nil
return (nextDirection, nextNode)
} else {
return nil
}
case .down:
if let nextNode = dNode {
dNode = nil
return (nextDirection, nextNode)
} else {
return nil
}
}
}
}
그래프에 대한 이해도가 요구되는 문제.
코드가 상당히 길어졌지만 머리속에 그래프를 그려놓고 이동되는걸 상상하면서 차근차근 풀었다.
아직 따끈따끈한 문제인지 몰라도 프로그래머스 다른사람의 풀이에서 Swift 부분 21번째로 올려졌다!
내가 전체 Swift 개발자 중에서 21번째로 푼 사람인 듯 하다!ㅋㅋ