barcode

팩토리얼 로직 또 수정

Coding/Python

이건 또 언제 떠올랐냐면 밥 사러 편의점 가다가 떠오름... ㅋㅋㅋㅋㅋㅋㅋㅋ 

아니 농담 아니고 진짜로 그래요 뜬금없이 샐러드 고르고 계산하다가 아 근데 자연수 아닌거 어캄? 이러고 떠오름 


들어가기 전에... 팩토리얼이 되는 범위가 어디까지인가에 대해 설명을 좀 하자면... 팩토리얼(n!)은 n부터 1까지 쫙 곱하는 그게 맞는데, 0!은 0이 아니라 1이고(...) 음수에 대해서는 정의가 안 되어 있다. 그리고 정수가 아닌 유리수(즉 q/p꼴로 나타내는 수 중 p가 1이 아닌 것...아니 음수도 아냐 치워)에 대해서는 일반적으로 고등학교 과정에서 배우는 팩토리얼이 아니라 감마 함수를 써서 계산한다. 그러니까

저기다 때려박으면 된다. 수기로 하지 말고 알파신 부르자. (울프램알파도 저거 해준다) 

감마(n)은 (n-1)!, 즉 감마(3) 하면 2!이고 감마(4) 하면 3!이다. 
그리고 저기에 소수를 넣으면... 어...... 나 루트 파이 본 거 같음... 
복소수? 된다. 허수부가 0이 아니어도 되는데 실수부는 0보다 커야 한다. 

아무튼 저기다 때려박으려면 일단 0보다 커야 한다. 0보다 작으면 감마함수 할아버지가 와도 답이 없다. 아무튼, 그래서 일차적으로 음수가 들어가면 팩토리얼이 없다고 나오는것. 그럼 이번에는 뭐때문에 수정했냐고? 아니 정수가 아닌 유리수 처리때문에 했다니까요. 저건 코딩 못해... 


For문

import sys
a = float(sys.stdin.readline())
# Factorial(계승): 일반적으로 n! = 1*2*3*...*n-1*n이다. (5!=1*2*3*4*5)
factorial = 1
if a < 0:
    print("Can't calculate factorial")
    # 음수는 factorlal이 없음
elif a == 0:
    print(factorial)
    # 0! = 1
elif a % 1 != 0:
    print("정수가 아닌 유리수는 일반적인 방법으로 팩토리얼을 구할 수 없습니다. ")
else:
    for i in range(int(a),0,-1):
        factorial *= i
    print(factorial)

기본적인 로직은 비슷하고 밑에 정수가 아닌 유리수를 판별하는 코드가 추가되었다. 정확히는 0보다 크면서 정수가 아닌 유리수(음수는 위에서 거른다). 저것도 밥 먹다가 0.5 이런건 1보다 작은거니까 1로 나누면 나머지가 나오겠지? 해서 시험삼아 해 보고 오케이 가릿 한 거. 회사에서 점심먹다 한 거라 노션에 올린 코드도 수기로 적은 거다. 날코딩에 이은 손코딩인가 

참고로 입력이 float로 받는거라 for문 돌릴 때는 int로 형변환 한번 해 줘야 한다. 안그러면 에러난다. 

 

While문

import sys
a = float(sys.stdin.readline())
# 와 팩토리얼이 생각보다 빡센거였구나... 
# Factorial(계승): 일반적으로 n! = 1*2*3*...*n-1*n이다. (5!=1*2*3*4*5)
factorial = 1
if a < 0: 
    print("Can't calculate factorial")
    # 음수는 factorial이 없음
elif a == 0: 
    factorial = 1
    # 0! = 1
elif a % 1 != 0:
    print("정수가 아닌 유리수는 일반적인 방법으로 팩토리얼을 구할 수 없습니다. ")
else: 
    while a >= 1:
        factorial *= a
        a -= 1
    print(factorial)

While은 for문과 달리 조건부 반복문이라 팩토리얼을 구하는 로직 자체가 달라서, a가 양수(자연수)이면 factorial이라는 변수에 a를 곱하고 a에 1을 빼는 걸 a가 1이 될 때까지(그래서 조건에 a >= 1이라고 되어 있다) 하면 된다. 그래서 따로 형변환을 할 필요가 없다. 

대신 저대로 출력하면 소수점이 붙어서 나오니까 그거 뵈기 싫으면 출력문에서 형변환 하면 된다. 

 

함수 이식판

def factorial(a):
    factorial = 1
    if a < 0:
        return False
    elif a == 0:
        factorial = 1
        return factorial
    elif a % 1 != 0:
        return False
    else:
        for i in range(int(a),0,-1):
            factorial *= i
        return factorial
# Factorial 구하는 로직(...)

어째서인지는 모르겠으나 함수와 클래스(얘도 근데 안에 함수 들었잖음...)에는 print 말고 return이 국룰이다. print는 화면에 출력하라는 얘기이고 return은 반환하라는 얘기. 즉 함수 다 돌리고 결과 반환하라는 얘기다. 덕분에 for나 while보다는 짜기가 편해진게 팩토리얼이 정의가 안 되는 케이스면 걍 return false 때려버리면 돼서 편하다. 

해당 함수는 순열/조합/계승소수 코드에 삽입되어 있다. 

'Coding > Python' 카테고리의 다른 글

감마 함수+팩토리얼 코드에서 유리수 처리  (0) 2022.08.22
이중계승 추가  (0) 2022.08.22
팩토리얼 로직 수정+계승 소수  (0) 2022.08.22
순열조합  (0) 2022.08.22
워드클라우드 코드에 기능 추가  (0) 2022.08.22