[Python] 코딩 도장 - Primary Arithmetic

Updated:

코딩 도장 사이트의 문제를 직접 풀어본 내용을 정리하여 올립니다.

코딩 도장에서 여러 문제를 확인할 수 있습니다.

난이도 순으로 차근차근 풀어보려 합니다.


[문제: Primary Arithmetic] - Lv.2

첫 번째 계산

아이들은 여러 자리 숫자들을 더하기 위해서 우에서 좌로 숫자를 하나씩 차례대로 더 하라고 배웠다. 1을 한 숫자 위치에서 다음 자리로 더하기위해 이동하는 “한자리올림”연산을 많이 발견하는 것은 중요한 도전이 된다. 당신의 일은 교육자가 그들의 어려움을 평가하기 위하여, 덧셈 문제들의 각 집합에 대해서 한자리올림 연산들의 수를 계산하는 것이다.

입력

입력의 각 라인은 10개의 숫자들보다 미만인 양의 정수들 두 개를 포함한다. 입력의 마지막 라인은 0 0 을 포한한다.

출력

마지막을 제외한 입력의 각 라인에 대해서 당신은 두 숫자들을 더한 결과에서 한자리올림 연산들의 수를 아래 처럼 보여지는 형식으로 계산하여 출력해야 한다.

입력 샘플

123 456
555 555
123 594
0 0

출력 샘플

No carry operation.
3 carry operations.
1 carry operation.

출처: https://codingdojang.com/scode/397?answer_mode=hide


[풀이]

def PrimaryArithmetic():
    x = input()
    a = []
    count = 0
    while x != "0 0":
        y = x.split()
        y0_len = len(y[0])
        y1_len = len(y[1])
        min_len = min(y0_len, y1_len)

        for i in range(0, min_len):
            if int(y[0][y0_len - i - 1]) + int(y[1][y1_len - i - 1]) >= 10:
                count += 1

        if count == 1:
            a.append(f"{count} carry operation")
        elif count > 1:
            a.append(f"{count} carry operations")
        else:
            a.append("No carry operations")

        count = 0

        x = input()

    print("-"*30)
    
    for i in a: print(i)
        
PrimaryArithmetic()
123 456
45 55
23 7
0 0
------------------------------
No carry operations
1 carry operation
1 carry operation

우선 while문으로 0 0 을 입력할 때 까지 반복하였고 각 자리별 숫자를 더하여 10이 넘으면 count하는 방식을 사용했다.

입력한 두 숫자의 자릿수가 다른 경우를 반영해두었다.

다만 현재 방법의 문제는 이전 자리에서 숫자가 올라왔을 때를 반영하지 못해 45 55를 입력하면 1이 반환된다.


[추천 풀이]

all((1,0))
False
from math import log10
a,b = map(int,input('? ').split())

while all((a,b)):
    print( sum( [(lambda x : int((a%x+b%x)/x))(10**(n+1)) for n in range(int(max(log10(a),log10(b)))+1)] ) )
    a,b = map(int,input('? ').split())
? 123 456
0
? 45 55
2
? 23 7
1
? 0 0

이 분은 아주 간결하게 푸셨는데 압축을 너무 해서 못 알아보겠어서 하나 하나 풀어 보려고 한다.

기존 풀이는 파이썬 2.x 버전이어서 3.x 버전에 맞게 조금 수정해두었다.

print(all((1,1)))
print(all((1,0)))
print(all((0,1)))
print(all((0,0)))
True
False
False
False

우선 all()은 모두 0이 아닐 때 True를 반환하므로 위 문제에서는 0 0을 입력할 때 까지 while이 반복된다.

단점은 굳이 100 0 이런식으로 입력하면 당연히 False가 반환되어 작동되지 않는다.

a = 100 ; b = 30
range(int(max(log10(a),log10(b)))+1)
range(0, 3)

상용로그를 사용해서 두 숫자의 자릿수 중 큰 값을 추출하고 있다.

이 부분은 그냥 len()으로 해둬도 될 것 같다.

a = 45 ; b = 55 ; n = 1
(lambda x : int((a%x+b%x)/x))(10**(n+1))
1

앞서 생성한 range()에 따라 10의 배수로 각 숫자를 나눠 나머지를 더한 후 다시 10의 배수로 나눠준다.

위의 경우 45 55를 10으로 나눠 (4.5 + 5.5) / 10으로 1이 나타난다.

이런 방식이기에 나와는 달리 이전 자리에서 숫자가 올라왔을 때까지 반영 된다.

또한 두 숫자의 자릿수 중 큰 값으로 추출하였기에 서로 자릿수가 달라도 잘 반영된다.

코드도 코드지만 아이디어도 좋아보이고 잘 만든 코드인 것 같다.

(lambda x: 2*x)(10)
20

참고로 위 lambda식이 복잡해 보여서 간단하게 만들어두었다.

Leave a comment