다항식 p(x) 를 1차 다항식 x - a 로 나눌 때의 몫과 나머지를 구하는 조립제법을
Boo 언어로 구현해 보았다. 조립제법은 일명 Horner의 방법이라고도 불리우는데, 이는
x = a 에서 다항식 p(x)의 값 p(a)을 계산하는 가장 빠른 알고리즘이기도 하다.

         p(x) = (x - a)q(x) + r

여기서 r은 나머지이며 r = p(a) 이다. 또 q(x)는 몫이다.

[참고]
    * 온라인으로 조립제법 표 만들기 손으로 계산하는 조립제법 표 
    * 온라인으로 구하는 다항식의 도함수: 조립제법을 이용한 다항식의 도함수


아래의 소스파일은 Python용 소스파일 testSyntheticDivision.py를 Boo용으로 수정한 것이다.
소스파일을 저장할 때는 UTF-8 인코딩으로 저장해야 한다.

Boo  언어는 그 구문의 바탕을 Python 언어의 것에서 빌렸다.
그러나 Python 언어는 변수의 타입이 런타임시에 결정되는 동적 타입(dynamically typed) 언어이지만, Boo 언어는 변수의 타입이 컴파일시에 결정되는 정적 타입(statically typed) 언어라는 점에서 차이점이 있다.

      (1) 함수를 구현할 때 매개변수의 타입을 지정해야 한다.
      (2) 변수 선언시에 타입을 지정해야 하는 경우가 많다.
      (3) 리스트에서 가져온 데이터의 타입을 다시 지정해야 한다.



  1. #  Filename: testSyntheticDivision.boo
  2. #
  3. #  Purpose:  Find the quotient and remainder when some polynomial is
  4. #            divided by a monic polynomial of the first degree.
  5. #
  6. #  Execute:  booi testSyntheticDivision.boo -2 1 3 3 1
  7. import System
  8. # 사용법 표시
  9. def printUsage():
  10.     print("사용법: booi testSyntheticDivision.boo [수] [피제식의 계수들]")
  11.     print("조립제법(synthetic method)에 의한 다항식 나눗셈 결과를 보여준다.")
  12. # 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  13. # 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
  14. def simplify(v as double, width as int):
  15.     t = "${v}"
  16.     tlen = len(t)
  17.     if t[tlen-2:tlen-1] == ".0":
  18.         t = t[0:-2]
  19.     if width > 0:
  20.         if tlen < width:
  21.             t = "              "[0: width - tlen] + t
  22.     return t
  23. # 다항식을 내림차순의 스트링 표현으로 반환
  24. def toPolyString(c as List):
  25.     t = ""
  26.     sc0 = simplify(Convert.ToDouble(c[0]), -1)
  27.     if len(c) > 2:
  28.         if sc0 == "1":
  29.             t += "x^${len(c)-1}"
  30.         elif sc0 == "-1":
  31.             t += "-x^${len(c)-1}"
  32.         else:
  33.             t += sc0 + " x^${len(c)-1}"
  34.     elif len(c) == 2:
  35.         if sc0 == "1":
  36.             t += "x"
  37.         elif sc0 == "-1":
  38.             t += "-x"
  39.         else:
  40.             t += sc0 + " x"
  41.     elif len(c) == 1:
  42.         t += sc0
  43.     for i in range(1, len(c)):
  44.         k = len(c) - 1 - i
  45.         sc = simplify(Convert.ToDouble(c[i]), -1)
  46.         if k > 1:
  47.             if Convert.ToDouble(c[i]) > 0.0:
  48.                 if sc == "1":
  49.                     t += " + " + "x^${k}"
  50.                 else:
  51.                     t += " + " + sc + " x^${k}"
  52.             elif Convert.ToDouble(c[i]) < 0.0:
  53.                 if sc == "-1":
  54.                     t += " - " + "x^${k}"
  55.                 else:
  56.                     t += " - " + simplify(Math.Abs(Convert.ToDouble(c[i])), -1) + " x^${k}"
  57.         elif k == 1:
  58.             if Convert.ToDouble(c[i]) > 0.0:
  59.                 if sc == "1":
  60.                     t += " + " + "x"
  61.                 else:
  62.                     t += " + " + sc + " x"
  63.             elif Convert.ToDouble(c[i]) < 0.0:
  64.                 if sc == "-1":
  65.                     t += " - " + "x"
  66.                 else:
  67.                     t += " - " + simplify(Math.Abs(Convert.ToDouble(c[i])), -1) + " x"
  68.         elif k == 0:
  69.             if Convert.ToDouble(c[i]) > 0.0:
  70.                 t += " + " + sc
  71.             elif Convert.ToDouble(c[i]) < 0.0:
  72.                 t += " - " + simplify(Math.Abs(Convert.ToDouble(c[i])), -1)
  73.     return t
  74. # 다향식 나눗셈 결과를
  75. #     (피제식) = (제식)(몫) + (나마지)
  76. # 형태로 출력
  77. def printDivisionResult(a as double, c as List, b as List):
  78.     strLine = "  " + toPolyString(c)
  79.     print( strLine )
  80.     strLine = "    = ( " + toPolyString( [1.0, -a] ) + " )"
  81.     tmp = [0.0] * (len(b) - 1)
  82.     for i in range(0, len(tmp)):
  83.         tmp[i] = b[i]
  84.     strLine += "( " + toPolyString(tmp) + " )"
  85.     r as double = b[len(b) - 1]
  86.     if r > 0.0:
  87.         strLine += " + " + simplify(r, -1)
  88.     elif r < 0.0:
  89.         strLine += " - " + simplify(Math.Abs(r), -1)
  90.     print( strLine )
  91. # 조립제법 계산표 출력 함수
  92. def printSyntheticTable(a, c as List, s as List, q as List):
  93.     strLine = "       | "
  94.     strLine += simplify(c[0], 6)
  95.     for i in range(1, len(c)):
  96.         strLine += "  " + simplify(c[i], 6)
  97.     print( strLine )
  98.     strLine = simplify(a, 6) + " |"
  99.     strLine += "         "
  100.     strLine += simplify(s[1], 6)
  101.     for i in range(2, len(s)):
  102.         strLine += "  " + simplify(s[i], 6)
  103.     print( strLine )
  104.     strLine = "       |"
  105.     for i in range(0, len(q)):
  106.         strLine += "--------"
  107.     print( strLine )
  108.     strLine = "         "
  109.     strLine += simplify(Convert.ToDouble(q[0]), 6)
  110.     for i in range(1, len(q)):
  111.         strLine += "  " + simplify(Convert.ToDouble(q[i]), 6)
  112.     print( strLine )
  113. def write(s):
  114.     Console.Write(s)
  115. # 실행 시작 지점
  116. if len(argv) < 2:
  117.     printUsage()
  118.     Environment.Exit(1)
  119. ######################################################
  120. # 피제식은 c_0 x^n +  c_1 x^(n -1) + ... + c_n
  121. # 제식은 x -  a 
  122.  as double = Convert.ToDouble(argv[0])
  123. c as List = [0.0]*(len(argv) - 1)
  124. s as List = [0.0]*(len(argv) - 1)
  125. b as List = [0.0]*(len(argv) - 1)
  126. for i in range(0, len(c)):
  127.     c[i] = Convert.ToDouble(argv[i + 1])
  128. ######################################################
  129. # 조립제법의 주요 부분
  130. s[0] = 0.0
  131. b[0] = c[0]
  132. for i in range(1, len(c)):
  133.     s[i] = Convert.ToInt32(b[i-1])*a
  134.     b[i] = Convert.ToInt32(c[i]) + Convert.ToInt32(s[i])
  135. ######################################################
  136. # 몫의 계수와 나머지를 출력한다.
  137. write("몫의 계수는 ")
  138. for i in range(0, len(b) - 2):
  139.     write(simplify(b[i], -1) + ", ")
  140. write(simplify(b[len(b) - 2], -1))
  141. write(" 이고, 나머지는 " + simplify(b[len(b) - 1], -1) + " 이다.")
  142. print
  143. print
  144. ######################################################
  145. # 조립제법 표를 출력한다.
  146. printSyntheticTable(a, c, s, b)
  147. print
  148. ######################################################
  149. # (피제식) = (제식) x (몫) + (나머지)
  150. printDivisionResult(a, c, b)




실행> booi testSyntheticDivision.boo 1 2 3 4 5
몫의 계수는 2, 5, 9 이고, 나머지는 14 이다.

       |      2       3       4       5
     1 |              2       5       9
       |---------------------------------
              2       5       9      14

  2 x^3 + 3 x^2 + 4 x + 5
    = ( x - 1 )( 2 x^2 + 5 x + 9 ) + 14



크리에이티브 커먼즈 라이선스
Creative Commons License

Posted by Scripter
,