본문 바로가기

개발일지/TIL

TIL 23-05-17 백준 알고리즘 - 암호, 반올림

https://github.com/sdoram/algorithm_solving_process/tree/main/23-05-17

 

GitHub - sdoram/algorithm_solving_process: 알고리즘 풀이 과정 python 파일

알고리즘 풀이 과정 python 파일. Contribute to sdoram/algorithm_solving_process development by creating an account on GitHub.

github.com

1. 백준 알고리즘 - 암호

 문제점

 

1855번: 암호

준표와 세준이는 서로 솔루션을 토론 하면서 다른 사람이 자신들의 솔루션을 듣지 못하게 하도록 서로 메시지를 주고받을 때 메시지를 암호화 하여서 주고받았다. 암호를 만드는 방법은 다음과

www.acmicpc.net

 시도해 본 것들

zip 사용을 위해 억지로 꼬아서 만든 코드 

K = 3
WORD = "aeijfbcgklhd"
NEW_WORD = []
for n in range(len(WORD) // K):
    if n % 2 == 0:
        # 홀수는 정방향 입력받기
        NEW_WORD.append(WORD[n * K : (n + 1) * K])
    else:
        # 짝수는 역방향 입력받기
        REVERSE_WORD = WORD[n * K : (n + 1) * K]
        NEW_WORD.append(REVERSE_WORD[::-1])
WORD_LIST = []
# 각 원소를 분리하기 위해 2중 for문
for nw in NEW_WORD:
    word = []
    for w in nw:
        word.append(w)
    WORD_LIST.append(word)
# 분리된 원소를 가지고 zip으로 묶기
WORD_LIST = list(zip(*WORD_LIST))
FIRST_WORD = ""
# WORD_LIST의 원소가 튜플이라서 풀기 위해 for문
for word in WORD_LIST:
    FIRST_WORD += "".join(word)
print(FIRST_WORD)
# zip 써보겠다고 무슨 코드를 만든거냐

 해결 방법

zip 없이 만든 코드 

K = int(input())
WORD = input()
NEW_WORD = []
for n in range(len(WORD) // K):
    if n % 2 == 0:
        # 홀수는 정방향 입력받기
        NEW_WORD.append(WORD[n * K : (n + 1) * K])
    else:
        # 짝수는 역방향 입력받기
        REVERSE_WORD = WORD[n * K : (n + 1) * K]
        NEW_WORD.append(REVERSE_WORD[::-1])
ANSWER = ""
# 2중 for문으로 각 원소의 index순서에 맞게 뽑아오기
for NW in range(len(NEW_WORD[0])):
    for N in NEW_WORD:
        ANSWER += N[NW]
print(ANSWER)

 알게 된 점

zip이 딱 맞을 것 같아서 사용했는데 오히려 없는 코드가 더 짧은데 결과가 동일했다. 

리팩토링 과정에서 오히려 zip이 빠져버리긴 했지만, 이렇게 한 번씩 사용해보면 나중에는 적절한 순간에 사용할 수 있을 것 같다. 

 

1. 백준 알고리즘 - 반올림

 문제점

https://www.acmicpc.net/problem/2033

 

2033번: 반올림

정수 N이 주어져 있을 때 이 수가 10보다 크면 일의 자리에서 반올림을 하고, 이 결과가 100보다 크면 다시 10의 자리에서 반올림을 하고, 또 이 수가 1000보다 크면 100의 자리에서 반올림을 하고.. (

www.acmicpc.net

 시도해 본 것들

최초 제출 코드 

N = int(input())
for i, n in enumerate(range(1, len(str(N))), 1):
    if N % 10**i // 10 ** (i - 1) >= 5:
        N += 10**i - (N % 10**i)
    else:
        N -= N % 10**i
print(N)

몇 번 보면서 나름 익숙해진 나머지를 원하는 값으로 만들어서 사용하기 

 해결 방법

리팩토링, 주석달기 

# enumerate() 제거, 주석 달기
N = int(input())
# range(1,로 가장 앞자리는 제외하기)
for i in range(1, len(str(N))):
    # N % 10**i 해당하는 자리 수 뽑아오기
    # 10 ** (i - 1)로 일의 자리로 만들기
    if N % 10**i // 10 ** (i - 1) >= 5:
        # 올림하고 0으로 만들기
        N += 10**i - (N % 10**i)
    else:
        # 내림하고 0으로 만들기
        N -= N % 10**i
print(N)

완성한 코드를 확인해 본 결과, i와n이 완전히 동일하고 하나만 사용되는 것을 알았다.

작성된 코드를 보고 바로 이해할 수 있도록 주석 추가 

 알게 된 점

if N % 10**i // 10 ** (i - 1) >= 5:

이런 코드는 내가 작성했음에도 불구하고 바로 이해하는 게 아직 어려운 느낌이 있다. 

이글을 작성하며 10**(i-1)에서 i가 1이면 에러가 나지 않을까 했는데, 0제곱은 1이 된다는 것을 알 수 있었다.

수학적 지식을 하나씩 쌓으며 부족한 점을 실감한다.