Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2-suhyun113 #9

Merged
merged 4 commits into from
Apr 2, 2024
Merged

2-suhyun113 #9

merged 4 commits into from
Apr 2, 2024

Conversation

suhyun113
Copy link
Collaborator

@suhyun113 suhyun113 commented Mar 29, 2024

🔗 문제 링크

본 문제 : 소수 & 팰린드롬수
https://www.acmicpc.net/problem/1747

  1. 소수 찾기
    https://www.acmicpc.net/problem/1978
  2. 팰린드롬수
    https://www.acmicpc.net/problem/1259


✔️ 소요된 시간

총 소요된 시간 : 3시간 30분

본 문제 : 약 1시간 30분
참고 문제 : 약 2시간



✨ 수도 코드

문제 설명

  1. output은 N보다 크거나 같은 수
  2. 소수 찾기
  3. 팰린드롬수 찾기

*소수 : 약수가 1과 자기자신인 수
*팰린드롬수 : 숫자의 순서를 뒤집은 수가 본래의 자신과 일치하는 수

추가 문제
이 문제를 풀기 위하여 소수를 찾는 함수와 팰린드롬 수를 찾는 함수를 구현하고자 하였다.
따라서 본 문제를 풀기에 앞서 좀 더 난이도가 낮은 두 문제를 풀고자 하였다.
위의 문제 링크란에 이 문제를 풀기 위해 먼저 풀었던 2문제의 링크도 함께 첨부해 놓았다.
이 2문제를 먼저 풀어보고 본 문제를 풀어보니 좀 더 도움이 되었기 때문에 같이 풀어보기를 추천한다.

1. 소수 찾기

Python
def is_prime_num(num):
    if num < 2:   # 1은 소수가 아님
        return False
    for i in range(2, num):
        if num % i == 0:
            return False  # 각각이 나누어 떨어지면 약수임
    return True   # 나눠 떨어지는 수 없으면 소수임

N = int(input())  # N개의 숫자
n = list(map(int, input().split())) # N개의 정수 입력받아 배열에 넣기
count = 0  # 소수의 개수 세기

for i in n:
    if is_prime_num(i): # 소수라면
        count += 1

print(count)

=> 소수 찾기 문제를 통하여 본 문제를 푸는 데 필요한 소수를 찾는데 필요한 함수를 구현할 수 있었다.

먼저 N개의 숫자를 입력받는다. 이 숫자들은 for반복문을 통해 소수인지 판별된다. 먼저 숫자 1은 약수가 1 자기 자신밖에 없으므로 소수가 아님을 if조건문을 이용한다. 따라서 1을 제외한 2부터 총 숫자의 개수만큼 반복하는 것이다.

   for i in range(2, num):
        if num % i == 0:
            return False  # 각각이 나누어 떨어지면 약수임

수가 나누어 떨어진다는 것은 약수가 존재한다는 뜻이므로, 소수가 아니다. 수가 나누어 떨어지지 않는 경우에만 소수이므로 이때 return한다.
이를 반복해서 진행하다가 prime_num(num) 함수를 이용하면, 소수가 몇개 존재하는지 알 수 있다.

2. 팰린드롬수

Python
def is_palindrome(num):
    return str(num) == str(num)[::-1]

while True:
    num = int(input())  # input 받기
    if num == 0:  # 0이 들어오면 input을 받지 않음
        break

    if is_palindrome(num):  # True라면
        print("yes")
    else:
        print("no")

=> 팰린드롬수 문제는 본 문제에서 팰린드롬인 소수를 찾는 것이기 때문에 필요하다. 따라서 본 문제를 풀기 이전에 팰린드롬수 문제를 통해 팰린드롬수 함수를 구현하고자 하였다.

처음에는 팰린드롬 함수를 구현할 때,

def is_palindrome(num):  # 팰린드롬 수 인지 확인하는 함수
    start_num = str(num)
    end_num = str(num[::-1])

    if start_num == end_num:
        return True
    else:
        return False

이렇게 구현하였다. 그러나, 이 방법보다 위의 코드에서 사용한 것처럼 한 줄로 줄일 수 있다는 것을 알게되어 더 효율적으로 코드를 짤 수 있었다.

팰린드롬수는 숫자를 입력받으면, 그 수를 문자열로 변환하고 시작한다. 슬라이스를 사용하기 위함인데, 문자열로 바꾸게 되면 맨 처음 숫자와 맨 끝 숫자를 비교하는 것이 쉽기 때문이다. 아래의 사진을 보면, 12345421이라는 숫자를 입력받았을 때 1번끼리, 2번끼리, 3번끼리 순차적으로 비교한다는 것을 알 수 있다.
image
따라서 같은 번호의 숫자끼리 비교하여 두 숫자가 같으면 반복을 지속하며, 반복이 끝났다면 그 숫자는 팰린드롬수인 것이므로 "yes"를 출력한다.
그러나, 같은 번호의 숫자끼리 비교했는데 두 숫자가 다르다면 팰린드롬수가 아닌 것이므로 "no"를 출력한다.


본 문제 분석

# 팰린드롬 수
def is_palindrome(num):
    return str(num) == str(num)[::-1]

# 소수 찾기
def is_prime_num(n):
    if n < 2:
        return False # 1은 소수가 아님
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

N = int(input())  # 어떤 수 N
# output은 N보다 크거나 같으므로 N으로 초기화
result = N # 현재

while True: # N보다 크거나 같은 수(항상)
    if is_prime_num(result) and is_palindrome(result): # 소수이면서 팰린드롬인 수       
        print(result)
        break
    result += 1

위의 2문제에서 구현한 함수들을 이용하여 이 문제를 풀고자 하였다.

  1. 함수 정의하기
    앞에서 했던 팰린드롬수 문제에서 구현한 것과 같은 팰린드롬수 함수를 정의한다.
    그리고, 소수 찾기를 위해 앞에서 사용했던 is_prime_num(n)함수를 이용하고자 하였는데, 실행결과 문제가 있었다. 시간이 초과된다는 것이다. 그래서 이전에 푼 문제와 달리 반복의 범위가 조금 바뀌었다. 바뀐 코드로 실행하면 시간초과가 발생하지 않는다.

  2. 입출력 받기
    어떤 수를 받을 것인지 입력을 받은 후, 결과값으로 낼 result를 N으로 초기화해준다. 문제에서 result는 N보다 크거나 같다고 했기 때문이다.

  3. 함수 호출하여 가장 작은 수 구하기
    while문의 무한루프를 이용한다. 앞에서 정의한 2개의 함수인 is_prime_num()과 is_palindrome()를 동시에 만족한다면 N보다 크거나 같고, 소수이면서, 팰린드롬수가 된다. 따라서 이 경우를 출력해준다.

📚 새롭게 알게된 내용

소수 찾기 함수를 구현할 때 '에라토스테네스의 체' 알고리즘을 사용하면 훨신 더 효율적으로 구현이 가능하다는 것을 알게되었다. 그러나, 이 알고리즘을 이해하기 힘들었기 때문에 이번 PR에서 사용하지 못 했다. 좀 더 이해하여 다음번에는 이 알고리즘을 사용하여 코드를 구현해보고 싶다.
또한 소수 찾기 문제에서는 아무런 문제가 없었기 때문에 당연히 소수 & 팰린드롬 문제에서도 같은 함수를 사용하더라도 문제가 없을 것이라고 생각했다. 그러나, 시간초과라는 것 때문에 생각보다 시간을 많이 사용했다. 그래도 시간을 줄일 수 있는 코드 구현도 해볼 수 있어서 좋았다.

Copy link
Member

@oesnuj oesnuj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR에 흐름이 있어 이해하기 쉬웠어요!! 풀이 잘 봤습니다👍
저는 소수 찾기 알고리즘하면 아리스토텔레스의 체 방식만 생각했었는데
수현님 코드를 보고 제곱근까지만 나누어 소수를 판별하는 방식도 추가로 알아가요!!

찾아보니 이 문제는 특정 수가 소수인지 판별하는 문제라서 아리스토텔레스의 체보다는 제곱근까지만 나누어 소수찾는 로직이 좀 더 효율적이라고 하네요

아리스토텔레스의 체 : 특정 범위 내의 모든 소수를 찾을때 유리
제곱근까지 나누어 판별 : 특정 수가 소수인지 확인할때 유리

Copy link
Collaborator

@pu2rile pu2rile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

소수 판별 방식으로 n의 제곱근까지 나누는 알고리즘은 처음 보는데 정말 신기하네요!!
저는 코드만으로는 이해가 잘 되지 않아서 블로그에 찾아봤어요

  • 만약 N이 12라고 할 때, 12의 제곱근은 약 3.46이고, 12의 약수는 1, 2, 3, 4, 6, 12 이다. 이때 1과 12를 제외했을 때 이는 2 * 6, 3 * 4, 4 * 3, 6 * 2의 결과이다.
  • 이들의 관계는 몫이 커지면 나누는 값이 작아지거나 나누는 값이 커지만 몫이 작아지는 반비례 관계이다. 결국 N의 절반(제곱근)까지 향하게 되면 이후 몫과 나누는 값이 반대로 바뀌게만 되는 상황이다.
  • 따라서 N의 제곱근까지 나누어 떨어지는지 여부를 조사하면 더 빠르게 소수판별을 할 수 있다.

덕분에 효율적인 알고리즘 하나 배워갑니다! PR 고생하셨어요!~

@Ghdrn1399
Copy link
Contributor

소수 구하는 알고리즘은 %연산자를 이용한 알고리즘만 생각했었는데, 팰린드 롬수라는 개념도 이번에 수현님이 PR적어 주신 덕분에 배우고 가는것 같아요!! 또한 팰린드롬수는 숫자를 입력받으면, 그 수를 문자열로 변환하고 시작한다는 내용도 새로 알고 갑니다!!

@suhyun113
Copy link
Collaborator Author

PR에 흐름이 있어 이해하기 쉬웠어요!! 풀이 잘 봤습니다👍 저는 소수 찾기 알고리즘하면 아리스토텔레스의 체 방식만 생각했었는데 수현님 코드를 보고 제곱근까지만 나누어 소수를 판별하는 방식도 추가로 알아가요!!

찾아보니 이 문제는 특정 수가 소수인지 판별하는 문제라서 아리스토텔레스의 체보다는 제곱근까지만 나누어 소수찾는 로직이 좀 더 효율적이라고 하네요

아리스토텔레스의 체 : 특정 범위 내의 모든 소수를 찾을때 유리 제곱근까지 나누어 판별 : 특정 수가 소수인지 확인할때 유리

저는 에라토스테네스의 체 개념을 제대로 이해하지 못 해서 제곱근을 이용하는 방법을 선택한 거였지 제곱근까지만 나누어 소수를 찾는 로직이 좀 더 효율적이었다는 것은 몰랐네요! 다행히 잘 사용했군요^^

에라토스테네스의 체가 어떨 때 사용하는지 각각이 언제 유리한지도 잘 몰랐는데 준서님 덕분에 알게되었습니다.
앞으로 코드를 구현할 때 어떤 방법이 더 효율적인지도 조금 더 알아보면서 해야겠어요~

@suhyun113 suhyun113 merged commit c2875e7 into main Apr 2, 2024
@suhyun113 suhyun113 deleted the 2-suhyun113 branch April 2, 2024 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants