var map = Array(repeating: Array(repeating: 0, count: 10), count: 10)
문제접근
단순히 좌표만 볼게 아니였고, 같은 길을 타는지를 묻는거라 <같은 길을 지난다>의 의미를 한번 짚고 가자면..
1. 출발지가 이미 왔던 곳
2. 도착지도 이미 왔던 곳
3. 출발지 -> 도착지 순서로 이전에 왓었는지 혹은 반대도 가능 (아무튼 붙어있어야함)
그럼 이제 이거를 어떻게 구하지? 생각했을 때 지금 생각 나는 것은..
1. 지나오는 길을 전부 좌표로서 기록을 해두고 싶었다.
2. 혹은 커맨드랑 현재 도착을 묶어서 "R"로 3,3에 왔어요! 이런식으로 구분할 수 있게 해주고 싶었다.
var current: [Character: (Int, Int)] = ["N": (0, 0)]
이런 말도 안되는 기록 방식 집어치우고 그냥 어딘가 도착했을때 (현재->다음위치)
뿐만 아니라 (다음 위치 -> 현재 )
이걸 둘다 판단해주는 방식으로 해줄 것이다 !
완성 코드
import Foundation
var command_dict: [String: (Int, Int)] = [
"U": (1, 0),
"D": (-1, 0),
"L": (0, -1),
"R": (0, 1)
]
func solution(_ dirs: String) -> Int {
var answer = 0
var CONSTRAINT = 5 // 맵의 크기
var commands = Array(dirs) // 명령어 분리
// 명령어랑 현재도착지 같이 새겨주기
var current = (0, 0)
var visitedLoad = Set<String>()
for command in commands {
let lastPosition = current
let direction = command_dict[String(command)]!
// 튜플 끼리 덧셈
let nextPosition = (lastPosition.0 + direction.0, lastPosition.1 + direction.1) // 다음 위치가 나왔음
if nextPosition.0 < -CONSTRAINT || nextPosition.0 > CONSTRAINT || nextPosition.1 < -CONSTRAINT || nextPosition.1 > CONSTRAINT {
continue
}
else {
// 이제 방향키랑 위치를 같이 넣어준다 !
if
visitedLoad
.contains("\(current)to\(nextPosition)") || visitedLoad
.contains("\(nextPosition)to\(current)")
{
current = nextPosition
continue
}
else { // 왔던길이 아닐 때
visitedLoad.insert("\(current)to\(nextPosition)")
current = nextPosition
answer += 1
}
}
}
return answer
}
1.SET
로 저장을 해주는데 \(nextPosition)to\(current)
구분하기 쉽게 이렇게 그냥 문자열로서 경로를 저장해주었다 억지로 튜플 두개 쓰고 하면 복잡해지다보니, 더 간단한 해결책을 찾고자했다 !
2. SET
로 저장해주면 찾는데 걸리는 시간이 상수 시간대니까 배열로 억지로 찾는거보다 더 효율적이겠다 싶었다.
타인의 코드
import Foundation
struct Point: Hashable {
let x: Int
let y: Int
func move(to: Character) -> Point? {
switch to {
case Character("U"):
guard self.y < 5 else {
return nil
}
return Point(x: self.x, y: self.y+1)
case Character("D"):
guard self.y > -5 else {
return nil
}
return Point(x: self.x, y: self.y-1)
case Character("L"):
guard x > -5 else {
return nil
}
return Point(x: self.x-1, y: self.y)
case Character("R"):
guard x < 5 else {
return nil
}
return Point(x: self.x+1, y: self.y)
default:
return nil
}
}
}
struct Path: Hashable {
let start: Point
let end: Point
}
func solution(_ dirs:String) -> Int {
var current = Point(x: 0, y: 0)
var paths: Set<Path> = Set()
for d in dirs {
if let next = current.move(to: d) {
paths.insert(Path(start: current, end: next))
paths.insert(Path(start: next, end: current))
current = next
}
}
return paths.count / 2
}