• [코테 연습]조이스틱 Python

    2020. 7. 23. 22:06

    by. 위지원

     

    1차 시도 

    ['N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M']

    A를 가운데에 두는 list를 둬서 

    "JAN"과 같은 문자가 들어왔을 때,

    좌 우 문자중 A와 가까운 문자를 선택할 수 있도록 함(위아래로 움직일 수 있다고 하였으므로 abs())

     

    from string import ascii_uppercase
    
    def solution(name):
        answer = 0
        name = name.replace("A", "")
        alpah_list = ascii_uppercase[13:] + ascii_uppercase[:13]
        idx_A = alpah_list.index("A")
    
        i = 0
        while True:
            l = len(name)
            answer += abs(alpah_list.index(name[i]) - idx_A)
            if l < 3:
                name = name[:i] + name[i + 1:]
                for i in name:
                    answer += abs(alpah_list.index(i) - idx_A)
                return answer + 1
    
            if i == 0:
                tmp1 = alpah_list.index(name[-1]) - idx_A
            else:
                tmp1 = alpah_list.index(name[i+1]) - idx_A
    
            if i == l - 1:
                tmp2 = alpah_list.index(name[0]) - idx_A
            else:
                tmp2 = alpah_list.index(name[i+1]) - idx_A
    
            name = name[:i]+name[i+1:]
    
            if abs(tmp1) < abs(tmp2):
                i -= 1
    
            answer += 1

     

    너무 생각을 안하고 하네 위지원.. 

    테스트 1 통과 (0.04ms, 10.7MB)
    테스트 2 통과 (0.05ms, 10.8MB)
    테스트 3 〉 실패 (0.17ms, 10.8MB)
    테스트 4 〉 실패 (시간 초과)
    테스트 5 〉 실패 (시간 초과)
    테스트 6 〉 실패 (시간 초과)
    테스트 7 〉 실패 (시간 초과)
    테스트 8 〉 실패 (0.21ms, 10.8MB)
    테스트 9 〉 실패 (시간 초과)
    테스트 10 통과 (0.04ms, 10.8MB)
    테스트 11 〉 실패 (0.21ms, 10.8MB)

    생각을 더 깊게 해보렴..

     

    1. A를 없에면 안된다.

    2. 각 자리의 알파벳과 A의 차이를 미리 계산해놓고 이걸 풀이에 사용할 리스트로 ..

    3. A를 만나면 돌아가는게 나을거같다. 어쨋든 다 만나야하는거긴해서..

     

    그래서 A를 그룹핑할려고 했다.

    AABBAAC면

     

    2A112A2 이런식으로 데이터 자체를 변환해서 나중에 계산하려고했는데,

    이러면 for문을 돌아야 할테고,, replace를 쓰거나 정규표현식을 사용하려했는데,, 

    그냥 그시간에 최대 길이가 20이니까 양쪽으로 A가 아닌 문자를 빨리 만나는 곳을 찾는게 낫다고 생각했다.(능력부족)

     

    아래와 같이... replace를 써서 같은 알파벳에 대해 한번에 변환하려 했으나 ,, 예를들어 A와 차이가 10이상이 나는 N과 같은경우는 2312이렇게 되어서 str로 하면 index 잡기가 애매했다.

        alpah_in_name = set(name) - set("A")
    
        for alpah in alpah_in_name:
            name = name.replace(alpah, str(abs(alpah_list.index(alpah)-idx_A)))

     

    두번째 시도.. 

    from string import ascii_uppercase
    
    
    def check(lis, direction="right"):
        i = 1
        l = len(lis)
    
        if direction == "left":
            i *= (-1)
            l *= (-l)
    
        for i in range(0, l, i):
            if lis[i] != "A":
                break
    
        return i
    
    
    def solution(name):
        answer = 0
        alpah_list = ascii_uppercase[13:] + ascii_uppercase[:13]
        idx_A = alpah_list.index("A")
    
        nameList = []
        for word in name:
            if word == "A":
                nameList.append("A")
            else:
                nameList.append(abs(alpah_list.index(word) - idx_A))
    
        idx = 0
        while True:
    
            if "A" not in nameList:
                for i in nameList:
                    answer += i
                return answer + len(nameList) - 1
            if set(nameList) == {'A'}:
                return answer
    
            if nameList[idx] == "A":  # 만약에 A라면 양옆으로 확인
                left = check(nameList, "left")
                right = check(nameList)
    
                if abs(left) < right:
                    idx = left
                    answer += 1
                else:
                    idx = right
                    answer += 1
            else:
                answer += nameList[idx]
                nameList[idx] = "A"
                idx += 1

    정확성 테스트

    테스트 1 통과 (0.04ms, 10.6MB)
    테스트 2 통과 (0.04ms, 10.8MB)
    테스트 3 〉 실패 (0.21ms, 10.9MB)
    테스트 4 〉 실패 (0.18ms, 10.8MB)
    테스트 5 〉 실패 (0.19ms, 10.7MB)
    테스트 6 통과 (0.04ms, 10.8MB)
    테스트 7 〉 실패 (0.21ms, 10.8MB)
    테스트 8 통과 (0.05ms, 10.8MB)
    테스트 9 통과 (0.04ms, 10.8MB)
    테스트 10 통과 (0.05ms, 10.8MB)
    테스트 11 〉 실패 (0.20ms, 10.7MB)

    직전 코드보다는 나아진 모습이지만 여전히 많이 틀리고있다.

     

    ㅠㅠ 이 문제는 결국 포기다.. 어떻게 풀어야할지는 알겠는데 구현을 못하겠다.. 

    좌<->우로 A개수가 최소로 중복되는 곳 방향을 찾아서 그쪽으로 움직이는건데 ,, 

    꼴통 진촤..ㅠ 

    아래분의 글을 내일 참고해서 다시해봐야겠다.

     

    https://hellominchan.tistory.com/350

     

    [programmers] 프로그래머스 조이스틱(Python)

    [programmers] 프로그래머스 조이스틱 (Python) (글쓴날 : 2020.06.19) * programmers, 프로그래머스 문제 Python 언어 풀이입니다. * 소스 코드의 저작권은 글쓴이에게 있습니다. 프로그래머스 조이스틱 1) 문..

    hellominchan.tistory.com

     

    그리디 다른거 풀어보고 다시와서 풀어보자 

     

    푸럭따.

    정말 쉬운거였다. 양 옆을 그때, 그때가 아니라 

    왼쪽으로 쭉 오른쪽으로 쭉 그리고 나서 비교 ...... 

    def solution(name):
        tmp = [i for i in name]
        answer = 0
        idx = 0
        while True:
            answer += min(ord(tmp[idx]) - ord('A'), ord('Z') - ord(tmp[idx]) + 1)
            tmp[idx] = 'A'
            if set(tmp) == {'A'}:
                break
    
            left, right = 1, 1
            while tmp[idx + right] == 'A':
                right += 1
            while tmp[idx - left] == 'A':
                left += 1
    
            if right <= left:
                answer += right;
                idx += right
            else:
                answer += left;
                idx -= left
    
        return answer