파이썬 격자 미로 문제
조회수 512회
파이썬 정말 초보입니다. 시작한 지도 얼마 안 됐고요.
스터디 모임에서 문제를 하나 내줬는데 아직 안 친하고 물어보기 그래서 문제 하나만 파이썬 선배님들이 풀어주시면 그거 보고 하나하나 분석해 보겠습니다.
2 답변
-
방금 적었던 비생산적인 댓글은 지웠습니다. 대신 문제 자체를 좀 생각을 해볼까 합니다. 참고로 실제 코딩까지는 오래 걸리는 어려운 문제입니다.
이론상으로는...
- 일단은 (0, 0), (0, 1), ..., (4, 4) 총 25개 좌표에 대해서 검사를 하면 됩니다.
- 무슨 검사를 하느냐? 그 좌표의 알파벳보다 사전 순서상 더 뒤에 있는 알파벳이 상하좌우 좌표에 있는지를 무한히 찾는 검사입니다. 발견되면
score += 1
한 다음 그 칸을 "현재 칸"으로 삼고 다시 검사합니다. 1칸 이동할 때마다 4번 검사, 2칸 이동할 때마다 4*4=16번 검사, ... 하는 식으로 무한히 늘어나겠군요. 물론 "현재위치"가 예컨대 왼쪽 위 구석이라면 4방향 전부를 검사할 리는 없겠습니다만. - 상하좌우 어느 위치에도 더 뒤에 있는 알파벳이 없다면,
chanceUsed = False
를True
로 바꾼 다음 상하좌우 각 위치로 이동해서 다시 상하좌우를 탐색해 봅니다. 그때도 더 진행할 칸이 안 보인다면, 찬스를 썼는데도 불구하고 다음 칸 이동을 못 했으므로, 막다른 골목에 이른 것이지요. 이때마다, 즉 더 이상 이동이 불가능할 때마다score
를 어딘가에 저장해 둡니다. - 그리하여 지금껏 나온 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)
댓글 입력