한가하게 백준 문제를 풀다가 갑자기 엉뚱한 생각이 들었다.
s1 = 7 / 2 # 3.5
s2 = 7 // 2 # 3
s3 = 7 % 2 # 1
위처럼 나누기 코드들은 각각 전체 결과, 몫, 나머지를 반환한다. //와 %를 사용하지 않고, 몫과 나머지로 결과를 분류할 수 있을까.
몫을 구하는 데에 가장 먼저 생각한 방법은 이거다.
s1 = 7 / 2
s2 = int(s1)
당연하게도, 정수부분만 남기는 것. 이것 외의 방법은 사실 떠오르지 않는다.
그렇다면, 여기서 한 단계 더 나아가서, /까지 사용하지 않는다면? 아래처럼 쓸 수 있을 것이다.
a = 7
b = 2
a_save = a
quo = 0 #몫
while True :
if ( a >= b ) :
quo += 1
a -= b
else :
break
print("{0}을 {1}로 나눈 몫은 {2}이다.".format(a_save, b, quo))
나눗셈의 정의를 이용한 코드이다. 큰 수에서 작은 수를 계속 빼 가며, 뺸 값이 1보다 작아지면 그때까지 뺀 양을 몫으로 한다. 반대로 곱셈의 정의를 이용한 방법도 가능하다.
a = 7
b = 2
b_save = b
p = 0
quo = 0 #몫
while True :
if ( a >= p + b ) :
quo += 1
p += b
else :
break
print("{0}을 {1}로 나눈 몫은 {2}이다.".format(a, b, quo))
b에 2를 한번씩 더해가면서 a보다 커지는 지점을 확인하고, 그 전까지의 값을 몫으로 하는 것이다.
몫은 이정도로 하고, 이제 나머지에 대해 알아보자.
바로 위에서 햇던 것을 변형하여 아래와 같이 쓸 수 있을 것이다.
a = 7
b = 2
a_save = a
rem = 0 #나머지
while True :
if ( a >= b ) :
a -= b
else :
rem = a
break
print("{0}을 {1}로 나눈 나머지는 {2}이다.".format(a_save, b, rem))
나누기를 이용하면 위와 같고,
a = 7
b = 2
p = 0
while True :
if ( a >= p + b ) :
p += b
else :
break
print("나머지는 {0}이다.".format(a - p))
곱하기를 이용하면 위와 같다.
마지막으로, 전체 나눗셈 결과의 소수부분을 구할 방법에 대해 알아보자.
int(s1)
위 식으로 몫을 구할 수 있으니, 전체 나눗셈 결과에서 int값을 빼면,
s1 = 7 / 2
s3 = s1 - int(s1)
으로 구할 수 있다. 저 상황에서 int 연산자도 사용하지 못한다면 어떻게 할 수 있을까. 우리가 가진 것은 3.5의 몫이다. 이를 이용하여 아래처럼 쓸 수 있을 것이다.
s1 = 7 / 2
while True:
if ( s1 >= 1 ) :
s1 -= 1
else :
break
print("{0:f}가 나머지이다".format(s1))
우리가 알고 있는 몫에서, 1씩을 빼 가며 s1이 1보다 작아지는지 검사한다. 하지만 이 방법은, 몫이 매우 클 때 매우 비효율적인 연산을 할 것이다.
어떻게 효율적으로 구할 수 있을까 생각해보고 있지만, 아직 잘 감이 안 온다.
생각나면 글을 한 번 수정해 보겠다.
그냥 침대에 누워있다가, 갑자기 궁금해져서 한번 해봤다.