[이코테] 04.구현

Nam_JU·2023년 7월 18일
0

Algorithm

목록 보기
10/20

04. 구현

머릿속에 있는 알고리즘을 소스코드로 바꾸는 과정

구현 예시

  • 알고리즘은 간단한데 코드가 지나칠 만큼 길어지는 문제
  • 실수 연산을 다루고, 특정 소수점 자리까지 출력해야 하는 문제
  • 문자열을 특정한기준에 따라서 끊어 처리해야 하는 문제
  • 적절한 라이브러리를 찾아서 사용해야하는 문제

4-1. 상하좌우


  • 에러
n = int(input())
map_list = list(map(str, input().split()))
x ,y = 1,1
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]

for d in map_list:
    if x>=1 and y>=1 and x<n and y<n:
        if d=='U':
            x = x + dx[0]
            y = y + dy[0]
        elif d=='R':
            x = x + dx[1]
            y = y + dy[1]
        elif d=='D':
            y = y + dy[3]
            x = x + dx[3]
        elif d=='L':
            x = x + dx[4]
            y = y + dy[4]
    else:
        continue #[0,4]로 막힘 

    print(x, y)

R(1,2)-> R(1,3)-> R(1,4)-> U(0,4)
U는 값이 바뀌고 if문에 튕기기 때문에 바뀌기 전 문자열(R)에 해당하는 값으로 유지해야하는데 이부분이 막힘.

  • 정답
dx=[-1, 0, 1, 0]
dy=[0, 1, 0, -1]
dir = ['U','R','D','L']
def solution(n, m):
    x,y=1,1

    for c in m:
        for k in range(4):
            if c==dir[k]:
                nx = x+dx[k]
                ny = y+dy[k]
        if nx<1 or ny<1 or nx>=n or ny>=n:
            continue
        x = nx
        y = ny
    return [nx, ny]

print(solution(5, "RRRUDD"))
  1. 개선된 부분
    문자열 비교후 dir=[상,오,하,왼] 위치값 인덱스를 사용해 코드 축약
  2. 놓친 부분
    통과 조건이 아닌 불통 조건을 cotinue로 두고 변수 두개를 사용해 (nx, x)로 변경 전, 변경 후로 나눠 위의 에러 부분이 해결될 수 있다.

4-2. 시간


문제 아이디어/ 알고리즘을 생각하지 못함
00:13:30 , 00:23:30이 1개로 치는지 따로 2개로 계산인가??

def solution(n):
    answer=0
    for i in range(n+1):
        for m in range(60):
            for s in range(60):
                if '3' in str(i) + str(m) + str(s):
                    answer+=1
    return answer
print(solution(5))

문자열 결합으로 3과 관련 문자열 있는지 count하기
시간(0~24), 분(0~59), 초(0~59)범위


4-3. 왕실의 나이트


아이디어
x행은 1~8 범위, y행은 alpha 배열로 [a-h]까지 만들어서 이중 배열로 체스판을 전부 순회하려고 했음
위의 시간문제에서 문자열 합 아이디어가 생각나서 사용함.
하지만 가장 중요한 나이트 이동부분에서 막힘

  • 에러 - 막힘...
def solution(night):
    answer=0
    alpha = ['a','b','c','d','e','f','g','h']
    dx = [-1, 0, 1, 0]
    dy = [0, 1, 0, -1] #y좌표이동은 어떻게? -> alpha[j]

    #체스판 만들기 (숫자행, 알파뱃열)
    for i in range(1,9):
        for j in alpha:
            if night == j+str(i):
                x=i
                y=alpha[j]
                for k in range(4): #한번더 어떻게 갈까? #그후 좌우도 살펴야함
                    nx = x+dx[k]
                    ny = y+dy[k]

    #나이트 이동경로 & 이동제약사항 넣기
    # x>=1 and x<=8 and y>=a and y<=h
    return answer
print(solution("a1"))
  • 다시풀이
def solution(night):
    answer=0
    alpha = ['0','a','b','c','d','e','f','g','h']
    dx = [-2, -1, 1, 2, 2, 1, -1, -2]
    dy = [-1, -2, -2, -1, 1, 2, 2, 1]

    #체스판 만들기 (숫자행, 알파뱃열)
    for i in range(1,9):
        for j in alpha:
            if night == j+str(i):
                x=i
                y=alpha.index(j)
                for k in range(8):
                    nx = x+dx[k]
                    ny = y+dy[k]
                    if nx>=1 and nx<=8 and ny>=1 and ny<=8:
                        answer+=1
    return answer
print(solution("a1"))

책보고 아이디어를 얻어 다시 수정함.
알파벳 열의 위치를 숫자로 넣기 위해 index값을 넣어줌
나이트의 이동 경로자체를 dx, dy값에 넣은게 새로웠다

  • 정답코드
def solution(night):
    answer=0
    x = int(night[1])
    y = int(ord(night[0])) - int(ord('a'))+1
    map_list = [(-2,-1), (-2,1), (-1,+2),(1,2),(2,1),(2,-1),(1,-2),(-1,-2)]
    for step in map_list:
        nx = x+step[0]
        ny = y+step[1]
        if nx>=1 and nx<=8 and ny>=1 and ny<=8:
            answer+=1

    return answer
print(solution("a1"))

아스키 코드를 사용해서 코드가 더 짧아짐


🍎 파이썬 아스키코드

  • A - Z = 65 - 90
  • a - z = 97 - 122
    int(ord('c')) - int(ord('a'))+1
    아스키코드 a의 값은 알파벳 숫자중 가장 작은 아스키값이기 때문에 비교하고자 하는 [아스키 문자]- 아스키 문자(a)+1를 하면 [아스키 문자]의 알파벳 순서를 구할 수 있다.
n = int(ord('c')) - int(ord('a'))+1
    print(n) #3

4-4. 게임개발


주어진 방향에서부터 반시계방향으로 탐색을 한다는 소리인가?
조건자체가 이해가 되지 않으니 코드를 한참 보고 디버깅을 하고 난뒤에야 문제 이해가 됐다.
결국 정답 코드는 조건 그대로 구현을 한 것인데 아직도 제대로 이해한게 맞나 의심쩍음.

"""
게임 개발

dir = [0,1,2,3] 상하좌우
map_list = [0,1] 육지,바다

4 4
1 1 0
1 1 1 1
1 0 0 1
1 1 0 1
1 1 1 1
"""
# 입력
n, m = map(int, input().split())
d = [[0]*m for _ in range(n)]
x, y, direction = map(int, input().split())
array=[]
for i in range(n):
    array.append(list(map(int, input().split())))

dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
d[x][y] = 1 #최초 시작값 방문체크하기

# 왼쪽 회전
def turn_left():
    global direction
    direction -=1 #-1을 줌으로써 왼쪽 회전이 됨
    if direction == -1: #음수일경우 [0,1,2,3]위치에서 제일 마지막 3으로 이동
        direction = 3

# 시뮬레이션
cnt=1
turn_time=0
while True:
    turn_left()
    nx = x + dx[direction]
    ny = y + dy[direction]
    # 안가본곳[0]일 경우
    if d[nx][ny]==0 and array[nx][ny]==0:
        d[nx][ny]=1 #1체크
        x = nx
        y = ny
        cnt +=1 #카운트
        turn_time = 0
        continue
    else: #가본곳[1]일 경우
        turn_time +=1
    if turn_time == 4:
        nx = x - dx[direction]
        ny = y - dy[direction]
        if array[nx][ny]==0:
            x = nx
            y = ny
        else:
            break
        turn_time=0
print(cnt)
profile
개발기록

0개의 댓글