파이썬 격자 미로 문제

조회수 512회

파이썬 정말 초보입니다. 시작한 지도 얼마 안 됐고요.

스터디 모임에서 문제를 하나 내줬는데 아직 안 친하고 물어보기 그래서 문제 하나만 파이썬 선배님들이 풀어주시면 그거 보고 하나하나 분석해 보겠습니다.

이미지

  • 네...죄송합니다..스터디 모임 날짜도 많이 남아서 한번 가기전에 천천히 풀어보고 싶었는데 의욕만 너무 컸네요..불편하셨다면 죄송합니다.. 신동민 2022.5.25 16:14
  • 문제는 재밌네요. nowp 2022.5.26 12:10

2 답변

  • 방금 적었던 비생산적인 댓글은 지웠습니다. 대신 문제 자체를 좀 생각을 해볼까 합니다. 참고로 실제 코딩까지는 오래 걸리는 어려운 문제입니다.

    이론상으로는...

    1. 일단은 (0, 0), (0, 1), ..., (4, 4) 총 25개 좌표에 대해서 검사를 하면 됩니다.
    2. 무슨 검사를 하느냐? 그 좌표의 알파벳보다 사전 순서상 더 뒤에 있는 알파벳이 상하좌우 좌표에 있는지를 무한히 찾는 검사입니다. 발견되면 score += 1 한 다음 그 칸을 "현재 칸"으로 삼고 다시 검사합니다. 1칸 이동할 때마다 4번 검사, 2칸 이동할 때마다 4*4=16번 검사, ... 하는 식으로 무한히 늘어나겠군요. 물론 "현재위치"가 예컨대 왼쪽 위 구석이라면 4방향 전부를 검사할 리는 없겠습니다만.
    3. 상하좌우 어느 위치에도 더 뒤에 있는 알파벳이 없다면, chanceUsed = FalseTrue로 바꾼 다음 상하좌우 각 위치로 이동해서 다시 상하좌우를 탐색해 봅니다. 그때도 더 진행할 칸이 안 보인다면, 찬스를 썼는데도 불구하고 다음 칸 이동을 못 했으므로, 막다른 골목에 이른 것이지요. 이때마다, 즉 더 이상 이동이 불가능할 때마다 score를 어딘가에 저장해 둡니다.
    4. 그리하여 지금껏 나온 25+개의 score들 중 가장 큰 것을 반환하면...

    ...문제를 풀 수 있습니다.

    여기까지가 아주 소박한 형태의 이론이고 실제로는 더 고려해야 할 게 많을 겁니다. 위의 이론 자체가 허점이 있을 여지도 많고요. 애초에 오만 잡다한 응용을 다 요구하는 종합 선물세트 같은 문제에요. 저보고 지금 당장 코딩하라고 하면 제 수준으로는 1주일은 써야 할 거 같네요.

    행운이 있기를.

  • 원래 남의 숙제는 안해주는데..가 아니라 실력이 안되서 모르는데.. 재밌어보여서 해봤습니다.

    어차피 제 숙제도 아니니까 틀려도 상관 없지 않습니까. ㅋㅋ

    뭔가 다른 모듈을 써야할 것 같은데 쓸 줄 몰라서 대충 해봤습니다.

    from random import randrange
    
    list_a = [
        ['a', 'b', 't', 't', 't'],
        ['t', 'c', 'd', 'e', 't'],
        ['t', 't', 't', 'f', 't'],
        ['b', 'a', 'h', 'g', 'f'],
        ['c', 'd', 'e', 'f', 'g'],
    ]
    
    
    
    count = 1
    move = 0
    
    num1 = randrange(0, 4)
    num2 = randrange(0, 4)
    
    print(num1, num2)
    
    a = list_a[num1][num2]
    
    print('기준값', a, ord(a))
    
    
    while 1:
        dict_a = {}
        a = list_a[num1][num2]
        print(f'현재 위치 : {num1}, {num2}, {a}')
        for i in list_a:
            print(i)
    
        try:
            if num1 + 1 > 4:
                raise
            dict_a[ord(list_a[num1 + 1][num2])] = [num1 + 1, num2]
        except:
            pass
        try:
            if num1 - 1 < 0:
                raise
            dict_a[ord(list_a[num1 - 1][num2])] = [num1 - 1, num2]
        except:
            pass
        try:
            if num2 + 1 > 4:
                raise
            dict_a[ord(list_a[num1][num2 + 1])] = [num1, num2 + 1]
        except:
            pass
        try:
            if num2 - 1 < 0:
                raise
            dict_a[ord(list_a[num1][num2 - 1])] = [num1, num2 - 1]
        except:
            pass
    
        print('dict_a', dict_a)
    
        if count:
            print('이동 기회 있음')
            r = randrange(0, 1)
            if r:
                print('이동 기회 사용')
                count -= 1
                b = {i:dict_a[i] for i in dict_a if i < ord(a)}
            else:
                print('이동 기회 미사용')
                b = {i:dict_a[i] for i in dict_a if i > ord(a)}
        else:
            print('이동 기회 없음')
            b = {i:dict_a[i] for i in dict_a if i > ord(a)}
    
        print(b)
    
        bb = 0
        print(f'이전 위치 : {num1}, {num2}, {a}')
        if b:
            num_b = randrange(0, len(b))
            print('num_b', num_b)
            for n, i in enumerate(dict_a.keys()):
                c = i
                if n == num_b:
                    break
            bb += 1
            print('c', c)
            num1 = dict_a[c][0]
            num2 = dict_a[c][1]
        else:
            print('이동 가능 위치 없음')
            if count:
                print('이동 기회 사용')
                count -= 1
                b = {i:dict_a[i] for i in dict_a if i < ord(a)}
                if b:
                    num_b = randrange(0, len(b))
                    print('num_b', num_b)
                    for n, i in enumerate(dict_a.keys()):
                        c = i
                        if n == num_b:
                            break
                    bb += 1
                    print('c', c)
                    num1 = dict_a[c][0]
                    num2 = dict_a[c][1]
    
    
        if not bb:
            print('이동 종료')
            break
        move += 1
        print('이동 수 :', move)
    
        input()
    print('최종 이동 수 :', move)
    

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)