알고리즘/Python

[프로그래머스] 파이썬 python - 방문 길이

조이은 2023. 11. 24. 17:20

https://school.programmers.co.kr/learn/courses/30/lessons/49994

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

Level 2. 방문 길이

Summer/Winter Coding(~2018) 

 

접근 방식
1. dirs을 돌면서, 방문 경로를 차례대로 저장한다. 이때, 유효한 좌표평면인지 확인한다. 
  나의 경우에는 가장 최근의 좌표를 알기 위해 stack을 사용하였다. 
2. 그 후 스택을 다시 반복하면서 해당 경로에 온적 있는지 확인한다.
   이 경우에는 중복을 확인하기 위해 set을 사용하였으며, 중요한 점(!!!)은 반대 방향까지 확인해야 한다.

 

시행착오 1. 
from collections import deque
dirs = "ULURRDLLU"

def isvalid(x,y) :
    if x<-5 or y<-5 or x>5 or y>5:
        return False
    else:
        return True

def solution(dirs):
    answer = 0
    
    road = deque()
    now = ((0,0))
    road.append(now)
    for d in dirs:
        nowx, nowy = road[-1]
        print(d, nowx, nowy)
        
        if d == 'U':
            if isvalid(nowx, nowy+1) == False:
                continue
                
            elif isvalid(nowx, nowy+1) == True:
                if ((nowx,nowy+1)) in road:
                    continue
                else:
                    road.append((nowx, nowy+1))
                    
                
        elif d == 'D':
            if isvalid(nowx, nowy-1) == False:
                continue
            elif isvalid(nowx, nowy-1) == True:
                if ((nowx, nowy-1)) in road:
                    continue
                else:
                    road.append((nowx, nowy-1))
            
        elif d == 'R' :
            if isvalid(nowx+1, nowy) == False:
                continue
            elif isvalid(nowx+1, nowy) == True:
                if((nowx+1, nowy)) in road:
                    continue
                else:
                    road.append((nowx+1, nowy))
            
        elif d == 'L' :
            if isvalid(nowx-1, nowy) == False:
                continue
            elif isvalid(nowx-1, nowy) == True:
                if ((nowx-1, nowy)) in road:
                    continue
                else:
                    road.append((nowx-1, nowy))
       
    print(len(road))
    answer = len(road)-1
    
    return answer


print(solution(dirs))

시행착오 1. 그냥 좌표만 집어넣었었는데 이러니까 당연히 절대 안됨

 

시행 착오 2.
from collections import deque

def isvalid(x,y) :
    if x<-5 or y<-5 or x>5 or y>5:
        return False
    else:
        return True

def solution(dirs):
    
    road = deque()
    
    if dirs[0] == 'U':
        road.append((0,0,0,1))
    elif dirs[0] == 'D':
        road.append((0,0,0,-1))
    elif dirs[0] == 'R':
        road.append((0,0,1,0))
    elif dirs[0] == 'L':
        road.append((0,0,-1,0))
        
    dirs = dirs[1:]
    
    for d in dirs:
        nowx, nowy = road[-1][2], road[-1][3]
        
        if d == 'U':
            if isvalid(nowx, nowy+1) == False:
                continue
            elif isvalid(nowx, nowy+1) == True:
               road.append((nowx, nowy, nowx, nowy+1))
                    
                
        elif d == 'D':
            if isvalid(nowx, nowy-1) == False:
                continue
            elif isvalid(nowx, nowy-1) == True:
                road.append((nowx, nowy, nowx, nowy-1))
            
        elif d == 'R' :
            if isvalid(nowx+1, nowy) == False:
                continue
            elif isvalid(nowx+1, nowy) == True:
                road.append((nowx, nowy, nowx+1, nowy))
            
        elif d == 'L' :
            if isvalid(nowx-1, nowy) == False:
                continue
            elif isvalid(nowx-1, nowy) == True:
                road.append((nowx, nowy, nowx-1, nowy))
    
    road = set(road)
    road = list(road)
    return len(road)

 

이제야 아! set에 넣으면 자동으로 중복을 제거할 수 있겠구나 생각했다.

근데 더 생각해보니까.. 반대 방향이 있다는 것을 까먹고 있다는 것을 깨달음. 

 

최종 코드
from collections import deque

def isvalid(x,y) : #유효한 좌표평면인지 확인
    if x<-5 or y<-5 or x>5 or y>5:
        return False
    else:
        return True

def solution(dirs):
    
    road = deque()
    
    if dirs[0] == 'U': #최초 방문 road에 append
        road.append((0,0,0,1))
    elif dirs[0] == 'D':
        road.append((0,0,0,-1))
    elif dirs[0] == 'R':
        road.append((0,0,1,0))
    elif dirs[0] == 'L':
        road.append((0,0,-1,0))
        
    dirs = dirs[1:] #초기 방문은 확인했으니 그 후부터 확인한다
    
    for d in dirs:
        nowx, nowy = road[-1][2], road[-1][3] 
        
        if d == 'U':
            if isvalid(nowx, nowy+1) == False: #유효하지 않다면 해당 방문은 무시한다
                continue
            elif isvalid(nowx, nowy+1) == True: #유효하다면 방문 경로를 일단 저장한다
               road.append((nowx, nowy, nowx, nowy+1))
                
        elif d == 'D':
            if isvalid(nowx, nowy-1) == False:
                continue
            elif isvalid(nowx, nowy-1) == True:
                road.append((nowx, nowy, nowx, nowy-1))
            
        elif d == 'R' :
            if isvalid(nowx+1, nowy) == False:
                continue
            elif isvalid(nowx+1, nowy) == True:
                road.append((nowx, nowy, nowx+1, nowy))
            
        elif d == 'L' :
            if isvalid(nowx-1, nowy) == False:
                continue
            elif isvalid(nowx-1, nowy) == True:
                road.append((nowx, nowy, nowx-1, nowy))
    
    set_road = set() #set 생성
    for r in road:
        oldx, oldy, newx, newy = r #현재는 방향이 존재하는 방문 경로를 저장해둠
        
        if (oldx, oldy, newx, newy) in set_road or (newx, newy, oldx, oldy) in set_road: #반대 방향까지 확인한다.
            continue
        else:
            set_road.add((oldx, oldy, newx, newy))
    
    
    return len(set_road)

최종 코드는 위와 같다.

 

그래도 생각보다 쉽게 풀었는데, 아주 잘 푼 코드인지는 모르겠다. 그래도 바로 내가 무엇을 잘못하고 있는지를 바로 깨닫고 고칠 수 있었음에..... 감사하며....

무슨 알고리즘인지 생각해본다면,, 아마 구현이 아닐까 싶다. 문제에서 말하는 그대로 코드로 작성할 수 있는지를 묻는 것 같다. 공부를 열심히 해야지..........