1. 페어프로그래밍 - OX 퀴즈
문제점
https://school.programmers.co.kr/learn/courses/30/lessons/120907
시도해 본 것들
네비게이터로 문제 분석
# quiz는 "X [연산자] Y = Z"를 원소로 n만큼 가진 리스트
# return은 X [연산자] Y == Z면 O, else X
# 공백으로 구분됨 <= split 사용
# eval()함수 사용 가능
문제를 해석했을 때 split()과 eval()함수를 사용하면 풀이가 가능해 보였음
팀원의 코드 구현 eval() 사용
def solution(quiz):
answer = []
# "X [연산자] Y = Z"를 원소로 n만큼 가진 리스트
# return은 X [연산자] Y == Z면 O, else X
# for문으로 quiz의 인덱스를 split한 리스트 num 만들기
for n in quiz:
num = n.split()
# eval로 X [연산자] Y 계산하기
eval_num = eval(''.join(num[0:3]))
# if문으로 X [연산자] Y 과 Z 비교하기
if eval_num != int(num[4]):
answer.append('X')
else:
answer.append('O')
return answer
어렵지 않게 문제를 풀 수 있었지만, eval의 사용법과 함께 알게된 보안상의 이슈 문제로 eval() 함수를 제거한 방식도 시도했다.
팀원의 리팩토링 eval() 제거
def solution(quiz):
answer = []
for n in quiz:
num = n.split()
# eval 대신 if문으로 연산자 확인
if num[1] == '-':
an = int(num[0]) - int(num[2])
elif num[1] == '+':
an = int(num[0]) + int(num[2])
if an != int(num[4]):
answer.append('X')
else:
answer.append('O')
return answer
코드가 길어지긴 했지만 eval로 한 번 풀어보고 코드를 재활용해서 리팩토링하면서 금방할 수 있었다.
해결 방법
def solution(quiz):
answer = []
for n in quiz:
num = n.split()
if num[1] == '-':
an = int(num[0]) - int(num[2])
elif num[1] == '+':
an = int(num[0]) + int(num[2])
if an != int(num[4]):
answer.append('X')
else:
answer.append('O')
return answer
알게 된 점
한 번에 좋은 코드를 만드는 것 보다 적당한 코드를 만든 뒤 그것을 개선하는 게 이해하기도 편하고 시간도 조금 쓰는 것 같다.
1. 백준 알고리즘 - 꼬리를 무는 숫자 나열
문제점
https://www.acmicpc.net/submit/1598/60171490
시도해 본 것들
while문 사용
# N, M = map(int, input().split())
N, M = 11, 33
width = (M-1)//4+1
length = N-width
count = 0
while True:
M -= 4
count += 1
if width == M:
break
print(count+length)
- 의도
width로 M의 가로 칸 구하기
length로 N이 과 M의 세로 칸 차이 구하기
while문으로 M을 한칸씩 당기면서 M의 가로 칸 - N의 가로 칸 - 실제
length값이 11, 33의 경우만 가능한 이상한 값 배출
while문 if문 설정도 이상해서 무한루프 발생, 무한루프가 아니어도 길이가 10,000,000까지 가능하므로 사용 불가능 해보임
수식 수정하기 & 반례 찾기 1
N, M = 4, 12
width = (M-1)//4+1
length = N-width
count = (M-width)//4
print(count+length) # 정답 : 2 출력 : 3
4 ,12의 경우 같은 세로칸에 존재하지만 세로칸을 뜻하는 length의 값이 1이나옴
수식 수정하기 & 반례 찾기 2
N, M = 20, 39
N, M = 7, 32
width = M//4 - (N//4)
length = width*4+N - M
print(width+length)
4, 12의 경우는 2로 잘 출력하지만 20과 39에서 length가 1칸 차이인데 -3으로 음수로 바뀜
7과 32의 경우 width = 6, length = 1이지만 7과 3으로 출력함 width의 수식도 수정해야함을 찾음
수식 수정하기 & 반례 찾기 3
N, M = map(int, input().split())
width = (M-1)//4 - (N-1)//4
length = abs(width*4+N - M)
print(width+length)
(M-1)을 해줘야 M이 4의 배수일 때 이동한 칸 계산 가능
(N-1)을 해줘야 N이 4의 배수일 때 이동한 칸 계산 가능
abs를 사용하면서 N이 더 높은 위치에 있는 경우 포함시키기
기존에 작성한 테스트 코드 모두 통과
제출시 실패
수식 수정하기 & 반례 찾기 4
N, M = 39, 20
if N > M:
N, M = M, N
width = (M-1)//4 - (N-1)//4
length = abs(width*4+N - M)
print(width, length)
print(width+length)
문제를 다시 읽어보자 N이 시작점이고 M이 종료지점이라는 말은 없었다.
그래서N과 M을 뒤집어 봤을 때 당연히 전혀 다른 결과가 나왔고 if문을 사용해서 큰 숫자가 M이 되도록 고정
제출 통과
해결 방법
N, M = map(int, input().split())
if N > M:
N, M = M, N
width = (M-1)//4 - (N-1)//4
length = abs(width*4+N - M)
print(width+length)
최초의 while문부터 왜 저렇게 썼을까? 싶은 상태로 시작해서 일단 만들고 틀리면 수정하고 반복해서 이해도 없이 시간으로 푼 것 같다.
알게 된 점
지금 이 글을 작성하기 위해서 코드를 다시 들여다 보며 수식이 이제야 이해됐다.
의도한 바는 아니지만 문제에대한 이해도가 없이 코드를 구현하려면 어떤일이 벌어지는지 직접 체험했다.
'개발일지 > TIL' 카테고리의 다른 글
TIL 23-05-04 팀원과의 코드 리뷰 - ad 제거하기 (1) | 2023.05.04 |
---|---|
TIL 23-05-03 팀원과의 코드 리뷰 - 전국 대회 선발 고사 (0) | 2023.05.03 |
TIL 23-05-01 팀원과의 코드리뷰 - 한 번만 등장한 문자 (0) | 2023.05.01 |
TIL 23-04-30 백준 알고리즘 - 수들의 합 (0) | 2023.04.30 |
TIL 23-04-29 백준 알고리즘 - 숫자 카드 (0) | 2023.04.29 |