컴퓨터 프로그래밍에서 꼭 알아두어야 할 주요 진법은 당연히 10진법, 2진법, 8진법, 16진법이다.
다음은  0 에서 15 까지의 정수를 10진법, 2진법, 8진법, 16진법의 표로 만들어 보여주는 Groovy 소스 코드이다. 진법 변환에 필요한 메소드로는 자바에

         Integer.parseInt(String, int radix);
         Long.toString(long, int radix);

가 이미 있지만, 여기에 준하는 함수

        convertAtoI(String, radix)
        convertItoA(long, radix)

를 Groovy 코드로 자체 작성하여 사용하였다.



  1. /*
  2.  *  Filename: makeRadixTable.groovy
  3.  *            Show the radix table with 10-, 2-, 8-, 16-radices.
  4.  *
  5.  *  Execute: groovy makeRadixTable.groovy
  6.  *
  7.  *      Date:  2008/03/28
  8.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  9.  */
  10. def printUsage() {
  11.     println("Usage: groovy makeRadixTable.groovy")
  12.     println("Show the radix table with 10-, 2-, 8-, 16-radices.")
  13. }
  14. def convertItoA(long num, int radix) {
  15.     String BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  16.     long q, r
  17.     boolean isNegative = false
  18.     if (num < 0) {
  19.         isNegative = true
  20.         num = -num
  21.     }
  22.     def arr = ""
  23.     q = num
  24.     r = 0
  25.     while (q >= radix) {
  26.         r = q % radix
  27.         q = q / radix
  28.         arr += BASE36[(int) r]
  29.      }
  30.      arr += BASE36[(int) q]
  31.      if (isNegative) {
  32.          arr += "-"
  33.      }
  34.      int n = arr.length()
  35.      def ret = ""
  36.      for (i = 0; i < n; i++) {
  37.          ret += arr[n - i - 1]
  38.      }
  39.      return ret
  40. }
  41. def convertAtoI(String srcStr, int radix) {
  42.     String BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  43.     boolean isNegative = false
  44.     long ret = 0L
  45.     int len = srcStr.length()
  46.     String c
  47.     int i
  48.     long val = 0L
  49.     c = srcStr[0]
  50.     if (c == '-') {
  51.         isNegative = true
  52.     }
  53.     else if (c >= '0' && c <= '9') {
  54.         ret = (long) (c.charAt(0) - '0'.charAt(0))
  55.     }
  56.     else if (c >= 'A' && c <= 'Z') {
  57.         ret = (long) (c.charAt(0) - 'A'.charAt(0)) + 10L
  58.     }
  59.     else if (c >= 'a' && c <= 'z') {
  60.         ret = (long) (c.charAt(0) - 'a'.charAt(0)) + 10L
  61.     }
  62.     if (ret >= (long) radix) {
  63.         println("        Invalid character!")
  64.         return ret
  65.     }
  66.     for (i = 1; i < len; i++) {
  67.         c = srcStr[i]
  68.         ret *= radix
  69.         if (c >= '0' && c <= '9') {
  70.             val = (long) (c.charAt(0) - '0'.charAt(0))
  71.         }
  72.         else if (c >= 'A' && c <= 'Z') {
  73.             val = (long) (c.charAt(0) - 'A'.charAt(0)) + 10L
  74.         }
  75.         else if (c >= 'a' && c <= 'z') {
  76.             val = (long) (c.charAt(0) - 'a'.charAt(0)) + 10L
  77.         }
  78.         if (val >= (long) radix) {
  79.             println("        Invalid character!")
  80.             return ret
  81.         }
  82.         ret += val
  83.     }
  84.     return ret
  85. }
  86. def makeTable() {
  87.     String sbuf = ""
  88.     String abuf = ""
  89.     String tbuf = ""
  90.     int i, j
  91.     char c;
  92.     for (i = 0; i < 4; i++) {
  93.         print("+-------")
  94.     }
  95.     print("+")
  96.     println("")
  97.     print("|  Dec")
  98.     print("\t|   Bin")
  99.     print("\t|  Oct")
  100.     print("\t|  Hex  |")
  101.     println("")
  102.     for (i = 0; i < 4; i++) {
  103.         print("+-------")
  104.     }
  105.     print("+")
  106.     println("")
  107.     for (i = 0; i < 16; i++) {
  108.         sbuf = String.format("|   %2d", i)
  109.         abuf = convertItoA((long) i, 2)
  110.         tbuf = String.format("\t|  %4s", abuf)
  111.         sbuf += tbuf
  112.         abuf = convertItoA((long) i, 8)
  113.         tbuf = String.format("\t|   %2s", abuf)
  114.         sbuf += tbuf
  115.         abuf = convertItoA((long) i, 16)
  116.         tbuf = String.format("\t|    %-2s |", abuf)
  117.         sbuf += tbuf
  118.         println(sbuf)
  119.     }
  120.     for (i = 0; i < 4; i++) {
  121.         print("+-------")
  122.     }
  123.     print("+")
  124.     println("")
  125. }
  126. if (args.length > 0 && "-h".equals(args[0])) {
  127.     printUsage()
  128.     System.exit(1);
  129. }
  130. makeTable()



실행> groovy makeRadixTable.groovy

+-------+-------+-------+-------+
|  Dec  |   Bin |  Oct  |  Hex  |
+-------+-------+-------+-------+
|    0  |     0 |    0  |    0  |
|    1  |     1 |    1  |    1  |
|    2  |    10 |    2  |    2  |
|    3  |    11 |    3  |    3  |
|    4  |   100 |    4  |    4  |
|    5  |   101 |    5  |    5  |
|    6  |   110 |    6  |    6  |
|    7  |   111 |    7  |    7  |
|    8  |  1000 |   10  |    8  |
|    9  |  1001 |   11  |    9  |
|   10  |  1010 |   12  |    A  |
|   11  |  1011 |   13  |    B  |
|   12  |  1100 |   14  |    C  |
|   13  |  1101 |   15  |    D  |
|   14  |  1110 |   16  |    E  |
|   15  |  1111 |   17  |    F  |
+-------+-------+-------+-------+




Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Posted by Scripter
,

다음은  대화형 모드(interactive mode)에서 진법 변환(radix conversion)하는 Groovy 소스 코드이다.
메뉴는 주메뉴 Command: (S)et radix, (A)bout, (Q)uit or E(x)it
와 부메뉴 SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
로 구성되어 있으며, 진법 변환의 핵심은 Integer 클래스와 Long 클래스의 정적 메소드

         Integer.parseInt(String, int);
         Long.toString(long, int);

울 이용하였으며, 지원되는 진법은 2진법에서 36진법 까지이다.



  1. /*
  2.  *  Filename: convertRadix.groovy
  3.  *            Convert radix in a interactive mode.
  4.  *
  5.  *  Execute: groovy convertRadix.groovy
  6.  *
  7.  *      Date:  2008/03/25
  8.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  9.  */
  10. import java.io.*
  11. def printUsage() {
  12.     println("Usage: groovy convertRadix.groovy")
  13.     println("Convert radix in a interactive mode, where the maximum radix is 36.")
  14. }
  15. def printAbout() {
  16.     println("    About: Convert radix in a interactive mode.")
  17. }
  18. def printMainMenu() {
  19.     println("  Command: (S)et radix, (A)bout, (Q)uit or E(x)it")
  20. }
  21. def printMainPrompt() {
  22.     print("  Prompt> ")
  23. }
  24. def printSubMenu(int srcRadix, int destRadix) {
  25.     println("    Convert Radix_" + srcRadix + " to Radix_" + destRadix)
  26.     println("    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit")
  27. }
  28. def printSubPrompt() {
  29.     print("    Input Value>> ")
  30. }
  31. String convertRadix(String s,  int srcRdx, int destRdx) {
  32.     long val
  33.     String ret = ""
  34.     try {
  35.         val = Integer.parseInt(s, srcRdx)
  36.         ret = Long.toString(val, destRdx)
  37.         return ret.toUpperCase()
  38.     }
  39.     catch (NumberFormatException nfx) {
  40.         println("    Error: " + nfx.getMessage() + " cantains some invalid character.")
  41.         ret = "????"
  42.     }
  43.     finally {
  44.       return ret.toUpperCase()
  45.     }
  46. }
  47. def doConvert(BufferedReader r, int srcRadix, int destRadix) {
  48.     def line
  49.     def cmd
  50.     def srcStr = "", destStr = ""
  51.     println()
  52.     printSubMenu(srcRadix, destRadix)
  53.     try {
  54.         while (true) {
  55.             printSubPrompt()
  56.             while ((cmd = r.readLine()) == null) {
  57.             }
  58.             if ("main()".equals(cmd)) {
  59.                 return
  60.             }
  61.             else if ("exit()".equals(cmd) || "quit()".equals(cmd)) {
  62.                 System.exit(0)
  63.             }
  64.             try {
  65.                 Integer.parseInt(cmd, srcRadix)
  66.                 srcStr = cmd
  67.                 destStr = convertRadix(srcStr, srcRadix, destRadix)
  68.                 println("        ( " + srcStr + " )_" + srcRadix +  "   --->   ( " + destStr + " )_" + destRadix)
  69.                 println()
  70.             }
  71.             catch (NumberFormatException nfx) {
  72.             }
  73.         }
  74.     }
  75.     catch (IOException ex) {
  76.         ex.printStackTrace()
  77.     }
  78. }
  79. def doStart() {
  80.     def line
  81.     def cmd
  82.     def srcRadix = 10, destRadix = 10
  83.     def srcStr = "", destStr = ""
  84.     boolean onlyOnce = true
  85.     BufferedReader r = new BufferedReader(new InputStreamReader(System.in))
  86.     try {
  87.         while (true) {
  88.             println()
  89.             if (onlyOnce) {
  90.                 println("  The supported maximum radix is 36.")
  91.                 onlyOnce = false
  92.             }
  93.             printMainMenu()
  94.             printMainPrompt()
  95.             while ((cmd = r.readLine()) == null) {
  96.             }
  97.             if ("qQxX".contains(cmd) && cmd.length() == 1) {
  98.                 System.exit(0)
  99.             }
  100.             else if ("aA".contains(cmd) && cmd.length() == 1) {
  101.                 printAbout()
  102.             }
  103.             else if ("sS".contains(cmd) && cmd.length() == 1) {
  104.                 print("  Input the source and target radices (say, 16 2): ")
  105.                 line = r.readLine()
  106.                 StringTokenizer st = new StringTokenizer(line, " ,\t")
  107.                 while (st.countTokens() < 2) {
  108.                     print("  Input the source and target radices (say, 16 2): ")
  109.                     line = r.readLine()
  110.                     st = new StringTokenizer(line, " ,\t");
  111.                 }
  112.                 srcRadix = Integer.parseInt(st.nextToken())
  113.                 destRadix = Integer.parseInt(st.nextToken())
  114.                 doConvert(r, srcRadix, destRadix)
  115.             }
  116.         }
  117.     }
  118.     catch (IOException ex) {
  119.         ex.printStackTrace()
  120.     }
  121. }
  122. // Begin here
  123. if (args.length > 0 && "-h".equals(args[0])) {
  124.     printUsage()
  125.     System.exit(1)
  126. }
  127. doStart()



실행> groovy convertRadix.groovy

  The supported maximum radix is 36.
  Command: (S)et radix, (A)bout, (Q)uit or E(x)it
  Prompt> s
  Input the source and target radices (say, 16 2): 16 2

    Convert Radix_16 to Radix_2
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 1FF
        ( 1FF )_16   --->   ( 111111111 )_2

    Input Value>> main()

  Command: (S)et radix, (A)bout, (Q)uit or E(x)it
  Prompt> S
  Input the source and target radices (say, 16 2): 2 8

    Convert Radix_2 to Radix_8
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 1011001
        ( 1011001 )_2   --->   ( 131 )_8

    Input Value>> main()

  Command: (S)et radix, (A)bout, (Q)uit or E(x)it
  Prompt> x




Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

Posted by Scripter
,

다음은  이차방정식 x^2 - x - 1  = 0 의 양의 근 즉 황금비율(golden ratio)을 구하는 Groovy 애플리케이션 소스이다. 황금비율을 구하는 비례방정식은   1 : x = x : (x+1) 이며, 이를 이차방정식으로 표현한 것이 x^2 - x - 1  = 0 이다.

See:  http://en.wikipedia.org/wiki/Golden_ratio

  1. /*
  2.  *  Filename: testGoldenRatio.groovy
  3.  *    황금률(즉, 이차방정식 x^2 - x - 1  = 0 의 양의 근)을 계산한다.
  4.  *
  5.  *   Execute: groovy testGoldenRatio.groovy
  6.  *
  7.  *      Date:  2008/03/24
  8.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  9.  */
  10. import java.util.ArrayList
  11. def printUsing() {
  12.     println("Using: groovy testGoldenRatio.groovy [-h|-help]")
  13.     println("This calculates the value of the golden ratio.")
  14. }
  15. // 이차방정식 a x^2 + b x + c  = 0 의 근을 구한다.
  16. def findQuadraticRoot(double a, double b, double c) {
  17.     if (a == 0.0) {
  18.         throw new RuntimeException("Since the highest coefficient is zero, the given equation is not a quadratic equation.");
  19.     }
  20.     else if (b*b - 4*a*c < 0.0) {
  21.         throw new RuntimeException("Since the discriminant " + (b*b - 4*a*c) + " is negative, the given equation has no real root.")
  22.     }
  23.     double x1 = (-b + Math.sqrt(b*b - 4*a*c)) / (2.0 * a)
  24.     double x2 = (-b - Math.sqrt(b*b - 4*a*c)) / (2.0 * a)
  25.     def array = [x1, x2].asImmutable()
  26.     return array
  27. }
  28. // 실행 시작 지점
  29. if (args.length > 0 && (args[0].equals("-h") || args[0].equals("-help"))) {
  30.     printUsing()
  31.     System.exit(1)
  32. }
  33. def values = findQuadraticRoot(1.0, -1.0, -1.0)
  34. def x1 = values[0]
  35. def x2 = values[1]
  36. if (x1 >= x2) {
  37.     println("The bigger root is " + x1 + ", ")
  38.     println("and the less root is " + x2 + ".")
  39. }
  40. else {
  41.     println("The bigger root is " + x2 + ", ")
  42.     println("and the less root is " + x1 + ".")
  43. }



실행> groovy testGoldenRatio.groovy
The bigger root is 1.618033988749895,
and the less root is -0.6180339887498949.




Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

Posted by Scripter
,
현재 시각을 컨솔에 보여주는 간단한 애플리케이션의 Groovy 언어 소스 코드이다.
UTC란 1970년 1월 1일 0시 0분 0초를 기준으로 하여 경과된 초 단위의 총 시간을 의미한다.
* UTC(Universal Time  Coordinated, 협정세계시, 協定世界時)


  1. /*
  2.  *  Filename: testCTime.groovy
  3.  *
  4.  *  Execute: groovy testCTime.groovy
  5.  */
  6. public class TestCTimeApp {
  7.    static def weekNames = [ "일", "월", "화", "수", "목", "금", "토" ].asImmutable()
  8.    public static void main(String[] args) {
  9.         Calendar now = new GregorianCalendar()
  10.         // 1970년 1월 1일 0시 0분 0초부터 시작하여 현재까지의 초
  11.         println("UTC: " + (now.getTime().getTime().intdiv(1000L)) + "초")
  12.         // 현재 시각 표시: 200x년 x월 xx일 (x요일) xx시 xx분 xx초
  13.         print(now.get(Calendar.YEAR) + "년 ")
  14.         print((1 + now.get(Calendar.MONTH)) + "월 ")
  15.         print(now.get(Calendar.DAY_OF_MONTH) +"일 ")
  16.         print("(" + weekNames[now.get(Calendar.DAY_OF_WEEK)] + "요일) ")
  17.         print(now.get(Calendar.HOUR_OF_DAY) + "시 ")
  18.         print(now.get(Calendar.MINUTE) + "분 ")
  19.         println(now.get(Calendar.SECOND) + "초")
  20.         // 1월 1일은 1, 1월 2일은 2
  21.         print("올해 몇 번째 날: " + now.get(Calendar.DAY_OF_YEAR) +", ")
  22.         // 0 이면 서머타임 없음
  23.         println("서머타임 적용 여부: " + (now.get(Calendar.DST_OFFSET) == 0 ? "안함" : "함"))
  24.     }
  25. }



실행> groovy testCTime.groovy
UTC: 1206324111초
2008년 3월 24일 (화요일) 11시 1분 51초
올해 몇 번째 날: 84, 서머타임 적용 여부: 안함




Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

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

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

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

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



  1. /*
  2.  *  Filename: testSyntheticDivision.groovy
  3.  *
  4.  *  Purpose:  Find the quotient and remainder when some polynomial is
  5.  *            divided by a monic polynomial of the first degree.
  6.  *     이 소스는 자바 소스 TestSyntheticMethod.java 와 내용이 거의 같은
  7.  *    그루비 소스 TestSyntheticMethod.groovy 를 더욱 그루비 소스 코드 답게 수정한 것이다.
  8.  *
  9.  *  Execute: groovy testSyntheticDivision.groovy -2 1 3 3 1
  10.  *
  11.  */
  12. // 사용법 표시
  13. def printUsage() {
  14.      println("사용법: groovy testSyntheticDivision.groovy [수] [피제식의 계수들]")
  15.      println("조립제법(synthetic method)에 의한 다항식 나눗셈 결과를 보여준다.")
  16. }
  17. // 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  18. String simplify(double v) {
  19.     String t = "" + v
  20.     if (t.endsWith(".0"))
  21.         t = t[0..<(t.length() - 2)]
  22.     return t
  23. }
  24. // 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  25. // 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
  26. String simplify(double v, int width) {
  27.     String t = "" + v
  28.     if (t.endsWith(".0"))
  29.         t = t[0..<(t.length() - 2)]
  30.     int len = t.length()
  31.     if (len < width)
  32.         t = "               ".substring(0, width - len) + t
  33.     return t;
  34. }
  35. // 다항식을 내림차순의 스트링 표현으로 반환
  36. String toPolyString(double[] c) {
  37.     String t = ""
  38.     def sc0 = simplify(c[0])
  39.     if (c.length > 2) {
  40.         if (sc0 == "1")
  41.             t += "x^" + (c.length-1)
  42.         else if (sc0 == "-1")
  43.             t += "-x^" + (c.length-1)
  44.         else
  45.             t += sc0 + " x^" + (c.length-1)
  46.     }
  47.     else if (c.length == 2) {
  48.         if (sc0 == "1")
  49.             t += "x"
  50.         else if (sc0 == "-1")
  51.             t += "-x"
  52.         else
  53.             t += sc0 + " x"
  54.     }
  55.     else if (c.length == 1) {
  56.         t += sc0
  57.     }
  58.     for (i in 1..< c.length) {
  59.         def k = c.length - 1 - i
  60.         def sc = simplify(c[i])
  61.         if (k > 1) {
  62.             if (c[i] > 0.0) {
  63.                 if (sc == "1")
  64.                     t += " + " + "x^" + k
  65.                 else
  66.                     t += " + " + sc + " x^" + k
  67.             }
  68.             else if (c[i] < 0.0) {
  69.                 if (sc == "-1")
  70.                     t += " - " + "x^" + k
  71.                 else
  72.                     t += " - " + simplify(Math.abs(c[i])) + " x^" + k
  73.             }
  74.         }
  75.         else if (k == 1) {
  76.             if (c[i] > 0.0) {
  77.                 if (sc == "1")
  78.                     t += " + " + "x"
  79.                 else
  80.                     t += " + " + sc + " x"
  81.             }
  82.             else if (c[i] < 0.0) {
  83.                 if (sc == "-1")
  84.                     t += " - " + "x"
  85.                 else
  86.                     t += " - " + simplify(Math.abs(c[i])) + " x"
  87.             }
  88.         }
  89.         else if (k == 0) {
  90.             if (c[i] > 0.0) {
  91.                 t += " + " + sc
  92.             }
  93.             else if (c[i] < 0.0)
  94.                 t += " - " + simplify(Math.abs(c[i]))
  95.         }
  96.     }
  97.     return t
  98. }
  99. // 다항식 나눗셈 결과를
  100. //     (피제식) = (제식)(몫) + (나마지)
  101. // 형태로 출력
  102. def printDivisionResult(double a, double[] c, double[] b) {
  103.     print("  " + toPolyString(c))
  104.     println()
  105.     print("    = ( " + toPolyString( [1.0, -a] as double[] ) + " )")
  106.     double[] tmp = new double[b.length - 1]
  107.     for (i in 0..<tmp.length) {
  108.         tmp[i] = b[i]
  109.     }
  110.     print("( " + toPolyString(tmp) + " )")
  111.     double r = b[b.length - 1]
  112.     if (r > 0.0)
  113.         print(" + " + simplify(r))
  114.     else if (r < 0.0)
  115.         print(" - " + simplify(Math.abs(r)))
  116.     println()
  117. }
  118. // 조립제법 계산표 출력 함수
  119. def printSyntheticTable(double a, double[] c, double[] s, double[] q) {
  120.     print("       | ")
  121.     print(simplify(c[0], 6))
  122.     for (i in 1..< c.length) {
  123.         print("  " + simplify(c[i], 6))
  124.     }
  125.     println()
  126.     print(simplify(a, 6) + " | ")
  127.     print("        ")
  128.     print(simplify(s[1], 6))
  129.     for (i in 2..< s.length) {
  130.         print("  " + simplify(s[i], 6))
  131.     }
  132.     println()
  133.     print("       |-")
  134.     for (i in 0..< q.length) {
  135.         print("--------")
  136.     }
  137.     println()
  138.     print("         ")
  139.     print(simplify(q[0], 6))
  140.     for (i in 1..< q.length) {
  141.         print("  " + simplify(q[i], 6))
  142.     }
  143.     println()
  144. }
  145. // 실행 시작 지점
  146. if (args.length < 3) {
  147.     printUsage()
  148.     System.exit(1);
  149. }
  150. double a = Double.parseDouble(args[0])
  151. double[] c = new double[args.length - 1]
  152. double[] s = new double[c.length]
  153. double[] b = new double[c.length]
  154. for (i in 0..<c.length) {
  155.     c[i] = Double.parseDouble(args[i + 1])
  156. }
  157. s[0] = 0.0;
  158. b[0] = c[0];
  159. for (i in 1..<c.length) {
  160.     s[i] = b[i-1]*a
  161.  b[i] = c[i] + s[i]
  162. }
  163. print("몫의 계수는 ");
  164. for (i in 0..<(b.length - 2)) {
  165.     print(simplify(b[i]) + ", " )
  166. }
  167. print(simplify(b[b.length - 2]))
  168. println(" 이고, 나머지는 " + simplify(b[b.length - 1]) + " 이다.")
  169. println()
  170. printSyntheticTable(a, c, s, b)
  171. println()
  172. printDivisionResult(a, c, b)



groovy 명령으로 아래와 같이 실행하여 보았다.


실행> groovy testSyntheticDivision.groovy 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
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Posted by Scripter
,


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

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

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


  1. /*
  2.  *  Filename: TestSyntheticMethod.groovy
  3.  *
  4.  *  Purpose:  Find the quotient and remainder when some polynomial is
  5.  *                 divided by a monic polynomial of the first degree.
  6.  *     이 소스는 자바소스 TestSyntheticMethod.java 에서 배열 생성 부분
  7.  *     new double[] {1.0, -a} 을 [1.0, -a] as double[] 로 변경한 것만 다르다.
  8.  *
  9.  *  Execute: groovy TestSyntheticMethod.groovy -2 1 3 3 1
  10.  */
  11. import java.lang.Math;
  12. public class TestSyntheticMethod {
  13.     // 사용법 표시
  14.     public static void printUsage() {
  15.          System.out.println("사용법: java TestSyntheticMethod [수] [피제식의 계수들]");
  16.          System.out.println("조립제법(synthetic method)에 의한 다항식 나눗셈 결과를 보여준다.");
  17.     }
  18.     // 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  19.     public static String simplify(double v) {
  20.         String t = "" + v;
  21.         if (t.endsWith(".0"))
  22.             t = t.substring(0, t.length() - 2);
  23.         return t;
  24.     }
  25.     // 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  26.     // 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
  27.     public static String simplify(double v, int width) {
  28.         String t = "" + v;
  29.         if (t.endsWith(".0"))
  30.             t = t.substring(0, t.length() - 2);
  31.         int len = t.length();
  32.         if (len < width)
  33.             t = "               ".substring(0, width - len) + t;
  34.         return t;
  35.     }
  36.     // 다항식을 내림차순의 스트링 표현으로 반환
  37.     public static String toPolyString(double[] c) {
  38.         String t = "";
  39.         if (c.length > 2) {
  40.             if (simplify(c[0]).equals("1"))
  41.                 t += "x^" + (c.length-1);
  42.             else if (simplify(c[0]).equals("-1"))
  43.                 t += "-x^" + (c.length-1);
  44.             else
  45.                 t += simplify(c[0]) + " x^" + (c.length-1);
  46.         }
  47.         else if (c.length == 2) {
  48.             if (simplify(c[0]).equals("1"))
  49.                 t += "x";
  50.             else if (simplify(c[0]).equals("-1"))
  51.                 t += "-x";
  52.             else
  53.                 t += simplify(c[0]) + " x";
  54.         }
  55.         else if (c.length == 1) {
  56.             t += simplify(c[0]);
  57.         }
  58.         for (int i = 1; i < c.length; i++) {
  59.             if (c.length - 1 - i > 1) {
  60.                 if (c[i] > 0.0) {
  61.                     if (simplify(c[i]).equals("1"))
  62.                         t += " + " + "x^" + (c.length - 1 - i);
  63.                     else
  64.                         t += " + " + simplify(c[i]) + " x^" + (c.length - 1 - i);
  65.                 }
  66.                 else if (c[i] < 0.0) {
  67.                     if (simplify(c[i]).equals("-1"))
  68.                         t += " - " + "x^" + (c.length - 1 - i);
  69.                     else
  70.                         t += " - " + simplify(Math.abs(c[i])) + " x^" + (c.length - 1 - i);
  71.                 }
  72.             }
  73.             else if (c.length - 1 - i == 1) {
  74.                 if (c[i] > 0.0) {
  75.                     if (simplify(c[i]).equals("1"))
  76.                         t += " + " + "x";
  77.                     else
  78.                         t += " + " + simplify(c[i]) + " x";
  79.             }
  80.             else if (c[i] < 0.0) {
  81.                 if (simplify(c[i]).equals("-1"))
  82.                     t += " - " + "x";
  83.                 else
  84.                     t += " - " + simplify(Math.abs(c[i])) + " x";
  85.             }
  86.         }
  87.         else if (c.length - 1 - i == 0) {
  88.             if (c[i] > 0.0) {
  89.                 t += " + " + simplify(c[i]);
  90.             }
  91.             else if (c[i] < 0.0)
  92.                 t += " - " + simplify(Math.abs(c[i]));
  93.             }
  94.         }
  95.         return t;
  96.     }
  97.     // 다항식 나눗셈 결과를
  98.     //     (피제식) = (제식)(몫) + (나마지)
  99.     // 형태로 출력
  100.     public static void printDivisionResult(double a, double[] c, double[] b) {
  101.         System.out.print("  " + toPolyString(c));
  102.         System.out.println();
  103.         System.out.print("    = ( " + toPolyString( [1.0, -a] as double[] ) + " )");
  104.         double[] tmp = new double[b.length - 1];
  105.         for (int i = 0; i < tmp.length; i++) {
  106.             tmp[i] = b[i];
  107.         }
  108.         System.out.print("( " + toPolyString(tmp) + " )");
  109.         double r = b[b.length - 1];
  110.         if (r > 0.0)
  111.             System.out.print(" + " + simplify(r));
  112.         else if (r < 0.0)
  113.             System.out.print(" - " + simplify(Math.abs(r)));
  114.         System.out.println();
  115.     }
  116.     // 조립제법 계산표 출력 메소드
  117.     public static void printSyntheticTable(double a, double[] c, double[] s, double[] q) {
  118.         System.out.print("       | ");
  119.         System.out.print(simplify(c[0], 6));
  120.         for (int i = 1; i < c.length; i++) {
  121.             System.out.print("  " + simplify(c[i], 6));
  122.         }
  123.         System.out.println();
  124.         System.out.print(simplify(a, 6) + " | ");
  125.         System.out.print("        ");
  126.         System.out.print(simplify(s[1], 6));
  127.         for (int i = 2; i < s.length; i++) {
  128.             System.out.print("  " + simplify(s[i], 6));
  129.         }
  130.         System.out.println();
  131.         System.out.print("       |-");
  132.         for (int i = 0; i < q.length; i++) {
  133.             System.out.print("--------");
  134.         }
  135.         System.out.println("");
  136.         System.out.print("         ");
  137.         System.out.print(simplify(q[0], 6));
  138.         for (int i = 1; i < q.length; i++) {
  139.             System.out.print("  " + simplify(q[i], 6));
  140.         }
  141.         System.out.println();
  142.     }
  143.     // Java 애플리케이션의 실행 시작 시점 main 메소드
  144.     // (C 언어의 main 함수에 해당)
  145.     public static void main(String[] args) {
  146.         if (args.length < 3) {
  147.             printUsage();
  148.             System.exit(1);
  149.         }
  150.         //////////////////////////////////////////////////////
  151.         // 피제식은 c_0 x^n +  c_1 x^(n -1) + ... + c_n
  152.         // 제식은 x -  a
  153.         double a = Double.parseDouble(args[0]);
  154.         double[] c = new double[args.length - 1];
  155.         double[] s = new double[c.length];
  156.         double[] b = new double[c.length];
  157.         for (int i = 0; i < c.length; i++) {
  158.             c[i] = Double.parseDouble(args[i + 1]);
  159.         }
  160.         //////////////////////////////////////////////////////
  161.         // 조립제법의 주요 부분
  162.         s[0] = 0.0;
  163.         b[0] = c[0];
  164.         for (int i = 1; i < c.length; i++) {
  165.            s[i] = b[i-1]*a;
  166.             b[i] = c[i] + s[i];
  167.         }
  168.         //////////////////////////////////////////////////////
  169.         // 몫의 계수와 나머지를 출력한다.
  170.         System.out.print("몫의 계수는 ");
  171.         for (int i = 0; i < b.length - 2; i++) {
  172.             System.out.print(simplify(b[i]) + ", " );
  173.         }
  174.         System.out.print(simplify(b[b.length - 2]));
  175.         System.out.println(" 이고, 나머지는 " + simplify(b[b.length - 1]) + " 이다.");
  176.         System.out.println();
  177.         //////////////////////////////////////////////////////
  178.         // 조립제법 표를 출력한다.
  179.         printSyntheticTable(a, c, s, b);
  180.         System.out.println();
  181.         //////////////////////////////////////////////////////
  182.         // (피제식) = (제식) x (몫) + (나머지)
  183.         printDivisionResult(a, c, b);
  184.     }
  185. }



Groovy 언어로 작성된 소스파일은 groovyc 명형으로 컴파일한 후 , 컴파일된 .class 파일을 java 명령으로 실행해도 되지만, groovy 명령을 사용하여 (아래에서 처험) 컴파일 과정 없이 직접 소스파일을 실행시킬 수 있다.


실행> groovy TestSyntheticMethod.groovy 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
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Posted by Scripter
,

다음 소스 코드는 80컬럼 컨솔에 19단표 출력하기 예제 (1) for Groovy 에 올려진 Groovy 소스 코드를 더 Groovy 소스 코드 답게 고친 것이다.
Java 문법은 모든 구문에서 문장의 끝은 세미콜론(;)을 붙이게 되어 있다.
그러나 Groovy 문법은 문장의 끝을 알리는 세미콜론(;)을 붙여도 되고 안븉여도 된다.
(단, 동일한 줄에 여러 개의 문장이 들어갈 때는 문장과 문장을 구별하는 세미콜론(;)을 사이사이에 넣어야 한다.)
즉, 문장의 끝을 알리는 세미콜론(;) 붙이기는 사용자의 개별 취향에 맡기는 옵션이다.(신택스 슈가, syntax sugar)

함수나 변수의 선언시에 Java 구문처럼 타입을 지정해도 되지만, 타입 대신 단지 def를 함수명이나 변수명 앞에 붙여도 된다. 이렇게 하는 이유는 함수의 라턴 값이나 변수가 참조하는 값에 대하여 타입의 융통성을 주기 위함이다. 바로 이 이유 때문에 언어를 소개할 때 Java 언어는 타입이 엄격한 언어(strictly typed language)라고 하고, Groovy 언어는 타입이 동적인 언어(dynamic language)라고 한다.

Groovy 언어에서는 args가 특별하게 쓰이는 예약어로 되어 있다.
main 메소드가 아닌 곳이라도 변수 선언 없이 쓸 수 있는 args는 명령행 실행시 옵션으로 붙인 스트링 값들을 갖고 있는 String[] 타입의 객체의 참조자로 예약되어 있다.

아래의 소스 코드에서 사용된 for 구문은 Java 언어의 for 구문과 완전히 똑 같다.
이는 Groovy 1.0 에서는 없던 구문이지만 Groovy 1.5 부터는 지원되는 구문이다.
그러므로 아래의 Groovy 소스 코드를 실행시키려면 반드시 Groovy 1.5 이상을 써야 한다.
이 글을 쓰는 현재 Groovy의  최신 버전을 1.5.4.이다.

 

  1. /*
  2.  *  Filename: testForFor.groovy
  3.  *
  4.  *  Execute:  groovy testForFor.groovy
  5.  *
  6.  *  Date:  2008. 3. 3.
  7.  */
  8. String[] getDan(int dan) {
  9.     def t = new String[19]
  10.     def sa, sb, sval
  11.     for (int j = 0; j < 19; j++) {
  12.         sa = "" + dan
  13.         if (sa.length() < 2)
  14.             sa = " " + sa
  15.         sb = "" + (j + 1)
  16.         if (sb.length() < 2)
  17.             sb = " " + sb
  18.         sval = "" + (dan*(j + 1))
  19.         if (sval.length() < 2)
  20.             sval = "  " + sval
  21.         else if (sval.length() < 3)
  22.             sval = " " + sval
  23.         t[j] = sa + " x " + sb + " = " + sval
  24.     }
  25.     return t
  26. }
  27. // 19단표를 모두 80컬럼 컨솔에 출력한다.
  28. def printAllNineteenDan() {
  29.     def arr = new String[18][19]
  30.     for (int i = 2; i < 20; i++) {
  31.         arr[i - 2] = getDan(i)
  32.     }
  33.     // 아래는 배열 대신 수정불가(immutable) 리스트를 사용하는 Groovy 코드이다.
  34.     def d = [ 2, 7, 11, 16 ].asImmutable()      // 각 줄단위 블럭의 첫단
  35.     def counter = [ 5, 4, 5, 4 ].asImmutable()  // 각 줄단위 블럭에 속한 단의 개수
  36.     def lines = new String[19]
  37.     for (int k = 0; k < d.size(); k++) {
  38.         // 80 바이트 길이의 한 줄씩 완성
  39.         for (int i = 0; i < 19; i++) {
  40.             lines[i] = arr[d[k]-2][i]
  41.             for (int j = 1; j < counter[k]; j++) {
  42.                 lines[i] += "   " +  arr[d[k]-2+j][i]
  43.             }
  44.         }
  45.         // 8-바이트 길이의 한 줄씩 출력
  46.         for (int i = 0; i < 19; i++) {
  47.             println(lines[i])
  48.         }
  49.         println()
  50.     }
  51. }
  52. printAllNineteenDan()




실행> groovy testForFor.groovy

 2 x  1 =   2    3 x  1 =   3    4 x  1 =   4    5 x  1 =   5    6 x  1 =   6
 2 x  2 =   4    3 x  2 =   6    4 x  2 =   8    5 x  2 =  10    6 x  2 =  12
 2 x  3 =   6    3 x  3 =   9    4 x  3 =  12    5 x  3 =  15    6 x  3 =  18
 2 x  4 =   8    3 x  4 =  12    4 x  4 =  16    5 x  4 =  20    6 x  4 =  24
 2 x  5 =  10    3 x  5 =  15    4 x  5 =  20    5 x  5 =  25    6 x  5 =  30
 2 x  6 =  12    3 x  6 =  18    4 x  6 =  24    5 x  6 =  30    6 x  6 =  36
 2 x  7 =  14    3 x  7 =  21    4 x  7 =  28    5 x  7 =  35    6 x  7 =  42
 2 x  8 =  16    3 x  8 =  24    4 x  8 =  32    5 x  8 =  40    6 x  8 =  48
 2 x  9 =  18    3 x  9 =  27    4 x  9 =  36    5 x  9 =  45    6 x  9 =  54
 2 x 10 =  20    3 x 10 =  30    4 x 10 =  40    5 x 10 =  50    6 x 10 =  60
 2 x 11 =  22    3 x 11 =  33    4 x 11 =  44    5 x 11 =  55    6 x 11 =  66
 2 x 12 =  24    3 x 12 =  36    4 x 12 =  48    5 x 12 =  60    6 x 12 =  72
 2 x 13 =  26    3 x 13 =  39    4 x 13 =  52    5 x 13 =  65    6 x 13 =  78
 2 x 14 =  28    3 x 14 =  42    4 x 14 =  56    5 x 14 =  70    6 x 14 =  84
 2 x 15 =  30    3 x 15 =  45    4 x 15 =  60    5 x 15 =  75    6 x 15 =  90
 2 x 16 =  32    3 x 16 =  48    4 x 16 =  64    5 x 16 =  80    6 x 16 =  96
 2 x 17 =  34    3 x 17 =  51    4 x 17 =  68    5 x 17 =  85    6 x 17 = 102
 2 x 18 =  36    3 x 18 =  54    4 x 18 =  72    5 x 18 =  90    6 x 18 = 108
 2 x 19 =  38    3 x 19 =  57    4 x 19 =  76    5 x 19 =  95    6 x 19 = 114

 7 x  1 =   7    8 x  1 =   8    9 x  1 =   9   10 x  1 =  10
 7 x  2 =  14    8 x  2 =  16    9 x  2 =  18   10 x  2 =  20
 7 x  3 =  21    8 x  3 =  24    9 x  3 =  27   10 x  3 =  30
 7 x  4 =  28    8 x  4 =  32    9 x  4 =  36   10 x  4 =  40
 7 x  5 =  35    8 x  5 =  40    9 x  5 =  45   10 x  5 =  50
 7 x  6 =  42    8 x  6 =  48    9 x  6 =  54   10 x  6 =  60
 7 x  7 =  49    8 x  7 =  56    9 x  7 =  63   10 x  7 =  70
 7 x  8 =  56    8 x  8 =  64    9 x  8 =  72   10 x  8 =  80
 7 x  9 =  63    8 x  9 =  72    9 x  9 =  81   10 x  9 =  90
 7 x 10 =  70    8 x 10 =  80    9 x 10 =  90   10 x 10 = 100
 7 x 11 =  77    8 x 11 =  88    9 x 11 =  99   10 x 11 = 110
 7 x 12 =  84    8 x 12 =  96    9 x 12 = 108   10 x 12 = 120
 7 x 13 =  91    8 x 13 = 104    9 x 13 = 117   10 x 13 = 130
 7 x 14 =  98    8 x 14 = 112    9 x 14 = 126   10 x 14 = 140
 7 x 15 = 105    8 x 15 = 120    9 x 15 = 135   10 x 15 = 150
 7 x 16 = 112    8 x 16 = 128    9 x 16 = 144   10 x 16 = 160
 7 x 17 = 119    8 x 17 = 136    9 x 17 = 153   10 x 17 = 170
 7 x 18 = 126    8 x 18 = 144    9 x 18 = 162   10 x 18 = 180
 7 x 19 = 133    8 x 19 = 152    9 x 19 = 171   10 x 19 = 190

11 x  1 =  11   12 x  1 =  12   13 x  1 =  13   14 x  1 =  14   15 x  1 =  15
11 x  2 =  22   12 x  2 =  24   13 x  2 =  26   14 x  2 =  28   15 x  2 =  30
11 x  3 =  33   12 x  3 =  36   13 x  3 =  39   14 x  3 =  42   15 x  3 =  45
11 x  4 =  44   12 x  4 =  48   13 x  4 =  52   14 x  4 =  56   15 x  4 =  60
11 x  5 =  55   12 x  5 =  60   13 x  5 =  65   14 x  5 =  70   15 x  5 =  75
11 x  6 =  66   12 x  6 =  72   13 x  6 =  78   14 x  6 =  84   15 x  6 =  90
11 x  7 =  77   12 x  7 =  84   13 x  7 =  91   14 x  7 =  98   15 x  7 = 105
11 x  8 =  88   12 x  8 =  96   13 x  8 = 104   14 x  8 = 112   15 x  8 = 120
11 x  9 =  99   12 x  9 = 108   13 x  9 = 117   14 x  9 = 126   15 x  9 = 135
11 x 10 = 110   12 x 10 = 120   13 x 10 = 130   14 x 10 = 140   15 x 10 = 150
11 x 11 = 121   12 x 11 = 132   13 x 11 = 143   14 x 11 = 154   15 x 11 = 165
11 x 12 = 132   12 x 12 = 144   13 x 12 = 156   14 x 12 = 168   15 x 12 = 180
11 x 13 = 143   12 x 13 = 156   13 x 13 = 169   14 x 13 = 182   15 x 13 = 195
11 x 14 = 154   12 x 14 = 168   13 x 14 = 182   14 x 14 = 196   15 x 14 = 210
11 x 15 = 165   12 x 15 = 180   13 x 15 = 195   14 x 15 = 210   15 x 15 = 225
11 x 16 = 176   12 x 16 = 192   13 x 16 = 208   14 x 16 = 224   15 x 16 = 240
11 x 17 = 187   12 x 17 = 204   13 x 17 = 221   14 x 17 = 238   15 x 17 = 255
11 x 18 = 198   12 x 18 = 216   13 x 18 = 234   14 x 18 = 252   15 x 18 = 270
11 x 19 = 209   12 x 19 = 228   13 x 19 = 247   14 x 19 = 266   15 x 19 = 285

16 x  1 =  16   17 x  1 =  17   18 x  1 =  18   19 x  1 =  19
16 x  2 =  32   17 x  2 =  34   18 x  2 =  36   19 x  2 =  38
16 x  3 =  48   17 x  3 =  51   18 x  3 =  54   19 x  3 =  57
16 x  4 =  64   17 x  4 =  68   18 x  4 =  72   19 x  4 =  76
16 x  5 =  80   17 x  5 =  85   18 x  5 =  90   19 x  5 =  95
16 x  6 =  96   17 x  6 = 102   18 x  6 = 108   19 x  6 = 114
16 x  7 = 112   17 x  7 = 119   18 x  7 = 126   19 x  7 = 133
16 x  8 = 128   17 x  8 = 136   18 x  8 = 144   19 x  8 = 152
16 x  9 = 144   17 x  9 = 153   18 x  9 = 162   19 x  9 = 171
16 x 10 = 160   17 x 10 = 170   18 x 10 = 180   19 x 10 = 190
16 x 11 = 176   17 x 11 = 187   18 x 11 = 198   19 x 11 = 209
16 x 12 = 192   17 x 12 = 204   18 x 12 = 216   19 x 12 = 228
16 x 13 = 208   17 x 13 = 221   18 x 13 = 234   19 x 13 = 247
16 x 14 = 224   17 x 14 = 238   18 x 14 = 252   19 x 14 = 266
16 x 15 = 240   17 x 15 = 255   18 x 15 = 270   19 x 15 = 285
16 x 16 = 256   17 x 16 = 272   18 x 16 = 288   19 x 16 = 304
16 x 17 = 272   17 x 17 = 289   18 x 17 = 306   19 x 17 = 323
16 x 18 = 288   17 x 18 = 306   18 x 18 = 324   19 x 18 = 342
16 x 19 = 304   17 x 19 = 323   18 x 19 = 342   19 x 19 = 361




Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Posted by Scripter
,

아래는 Java용 소스파일 TestForForApp.java 를 (최소한의 수정으로) Groovy용으로 고친 것이다. 배열(array)을 생성하는 문법에 있어 Java 코드와 Groovy 코드가 서로 다르기 때문이다.

예를 들어, 정수 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 을 갖고 있는 int[] 타입의 배열을 생성하여
변수 arr에 저장하는(참조자 arr이 이를 참조하게 하는) Java 문법은

        int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

이다. 하지만 이에 대응하는 Groovy 문법은

        int[] arr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] as int[];

이다. 즉. Groovy 문법은 리스트를 생성시켜서 as int[] 라는 구문으로 타입변환한 다음 참조자 arr이 생성된 이 배열을 참조하도록 한다.

그러나 Groovy 언어에서는 배열(array)의 사용을 권하지 않는다. 배열 보다는 리스트를 사용 하는 것이 훨씬 효율적이다. 때로는 수정가능(mutable) 리스트 보다 수정불가(immutable) 리스트가 필요할 때가 있다. 이때는 Groovy 에서 지원하는 리스트의 asImmuable() 이라는 객체 메소드를 써서 리스트의 속성을 바꾸면 된다. 그래서 위의 Groovy 코드 보다는

        def arr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ].asImmutable();

로 하는 것이 더 Groovy 다운 Groovy 코드이다. 이와 유사한 Groovy 코드가 아래의 소스 코드 중에 두 줄 있을 것이다. 바로 그 두 줄만 자바소스파일 TestForForApp.java로 부터 수정되었다.

하지만 이 두 줄의 수정 만으로는 아직 소스 전체가 Groovy 소스 코드 답지 않고 Java 소스 코드의 모습을 그대로 간직하고 있다. 구문을 Groovy 소스 코드 답게 더 고치는 일은 다음
에 (   80컬럼 컨솔에 19단표 출력하기 예제 (2) for Groovy )에서 하기로 한다.



  1. /*
  2.  *  Filename: testForForApp.groovy
  3.  *
  4.  *  Execute:  groovy testForForApp.groovy
  5.  *
  6.  *  Date:  2008. 3. 3.
  7.  */
  8. public class TestForForApp {
  9.     // static 선언자가 없으므로 이 메소드는 인스턴스 메소드이다.
  10.     // 인스턴스 메소드는 static 메소드에서는 직접 호출되지 않는다.
  11.     // 반드시 생성된 객체를 거쳐서 호출되어 진다.
  12.     public String[] getDan(int dan) {
  13.         String[] t = new String[19];
  14.         String sa, sb, sval;
  15.         for (int j = 0; j < 19; j++) {
  16.             sa = "" + dan;
  17.             if (sa.length() < 2)
  18.                 sa = " " + sa;
  19.             sb = "" + (j + 1);
  20.             if (sb.length() < 2)
  21.                 sb = " " + sb;
  22.             sval = "" + (dan*(j + 1));
  23.             if (sval.length() < 2)
  24.                 sval = "  " + sval;
  25.             else if (sval.length() < 3)
  26.                 sval = " " + sval;
  27.             t[j] = sa + " x " + sb + " = " + sval;
  28.         }
  29.         return t;
  30.     }
  31.     // 19단표를 모두 80컬럼 컨솔에 출력한다.
  32.     //
  33.     // (static 선언자가 없는) 인스턴스 메소드이므로,
  34.     // 반드시 생성된 객체를 거쳐서 호출되어 진다.
  35.     public void printAllNineteenDan() {
  36.         String[][] arr = new String[18][19];
  37.         for (int i = 2; i < 20; i++) {
  38.             arr[i - 2] = getDan(i);
  39.         }
  40.         // 아래 처럼 두 줄만 바꾸면 Groovy 애플리케이션이 된다.
  41.         def d = [ 2, 7, 11, 16 ].asImmutable();      // 각 줄단위 블럭의 첫단
  42.         def counter = [ 5, 4, 5, 4 ].asImmutable();  // 각 줄단위 블럭에 속한 단의 개수
  43.         String[] lines = new String[19];
  44.         for (int k = 0; k < d.size(); k++) {
  45.             // 8-바이트 길이의 한 줄씩 완성
  46.             for (int i = 0; i < 19; i++) {
  47.                 lines[i] = arr[d[k]-2][i];
  48.                 for (int j = 1; j < counter[k]; j++) {
  49.                     lines[i] += "   " +  arr[d[k]-2+j][i];
  50.                 }
  51.             }
  52.             // 80 바이트 길이의 한 줄씩 출력
  53.             for (int i = 0; i < 19; i++) {
  54.                 System.out.println(lines[i]);
  55.             }
  56.             System.out.println();
  57.         }
  58.     }
  59.     // C 언어의 main 함수에 준하는 Java 언어의 스테틱 main 메소드
  60.     public static void main(String[] args) {
  61.         TestForForApp app = new TestForForApp();  // 객체를 생성한다.
  62.         app.printAllNineteenDan();    // 객체에 속하는 메소드 printDan()을 호출한다.
  63.     }
  64. }



실행> groovy testForForApp.groovy

 2 x  1 =   2    3 x  1 =   3    4 x  1 =   4    5 x  1 =   5    6 x  1 =   6
 2 x  2 =   4    3 x  2 =   6    4 x  2 =   8    5 x  2 =  10    6 x  2 =  12
 2 x  3 =   6    3 x  3 =   9    4 x  3 =  12    5 x  3 =  15    6 x  3 =  18
 2 x  4 =   8    3 x  4 =  12    4 x  4 =  16    5 x  4 =  20    6 x  4 =  24
 2 x  5 =  10    3 x  5 =  15    4 x  5 =  20    5 x  5 =  25    6 x  5 =  30
 2 x  6 =  12    3 x  6 =  18    4 x  6 =  24    5 x  6 =  30    6 x  6 =  36
 2 x  7 =  14    3 x  7 =  21    4 x  7 =  28    5 x  7 =  35    6 x  7 =  42
 2 x  8 =  16    3 x  8 =  24    4 x  8 =  32    5 x  8 =  40    6 x  8 =  48
 2 x  9 =  18    3 x  9 =  27    4 x  9 =  36    5 x  9 =  45    6 x  9 =  54
 2 x 10 =  20    3 x 10 =  30    4 x 10 =  40    5 x 10 =  50    6 x 10 =  60
 2 x 11 =  22    3 x 11 =  33    4 x 11 =  44    5 x 11 =  55    6 x 11 =  66
 2 x 12 =  24    3 x 12 =  36    4 x 12 =  48    5 x 12 =  60    6 x 12 =  72
 2 x 13 =  26    3 x 13 =  39    4 x 13 =  52    5 x 13 =  65    6 x 13 =  78
 2 x 14 =  28    3 x 14 =  42    4 x 14 =  56    5 x 14 =  70    6 x 14 =  84
 2 x 15 =  30    3 x 15 =  45    4 x 15 =  60    5 x 15 =  75    6 x 15 =  90
 2 x 16 =  32    3 x 16 =  48    4 x 16 =  64    5 x 16 =  80    6 x 16 =  96
 2 x 17 =  34    3 x 17 =  51    4 x 17 =  68    5 x 17 =  85    6 x 17 = 102
 2 x 18 =  36    3 x 18 =  54    4 x 18 =  72    5 x 18 =  90    6 x 18 = 108
 2 x 19 =  38    3 x 19 =  57    4 x 19 =  76    5 x 19 =  95    6 x 19 = 114

 7 x  1 =   7    8 x  1 =   8    9 x  1 =   9   10 x  1 =  10
 7 x  2 =  14    8 x  2 =  16    9 x  2 =  18   10 x  2 =  20
 7 x  3 =  21    8 x  3 =  24    9 x  3 =  27   10 x  3 =  30
 7 x  4 =  28    8 x  4 =  32    9 x  4 =  36   10 x  4 =  40
 7 x  5 =  35    8 x  5 =  40    9 x  5 =  45   10 x  5 =  50
 7 x  6 =  42    8 x  6 =  48    9 x  6 =  54   10 x  6 =  60
 7 x  7 =  49    8 x  7 =  56    9 x  7 =  63   10 x  7 =  70
 7 x  8 =  56    8 x  8 =  64    9 x  8 =  72   10 x  8 =  80
 7 x  9 =  63    8 x  9 =  72    9 x  9 =  81   10 x  9 =  90
 7 x 10 =  70    8 x 10 =  80    9 x 10 =  90   10 x 10 = 100
 7 x 11 =  77    8 x 11 =  88    9 x 11 =  99   10 x 11 = 110
 7 x 12 =  84    8 x 12 =  96    9 x 12 = 108   10 x 12 = 120
 7 x 13 =  91    8 x 13 = 104    9 x 13 = 117   10 x 13 = 130
 7 x 14 =  98    8 x 14 = 112    9 x 14 = 126   10 x 14 = 140
 7 x 15 = 105    8 x 15 = 120    9 x 15 = 135   10 x 15 = 150
 7 x 16 = 112    8 x 16 = 128    9 x 16 = 144   10 x 16 = 160
 7 x 17 = 119    8 x 17 = 136    9 x 17 = 153   10 x 17 = 170
 7 x 18 = 126    8 x 18 = 144    9 x 18 = 162   10 x 18 = 180
 7 x 19 = 133    8 x 19 = 152    9 x 19 = 171   10 x 19 = 190

11 x  1 =  11   12 x  1 =  12   13 x  1 =  13   14 x  1 =  14   15 x  1 =  15
11 x  2 =  22   12 x  2 =  24   13 x  2 =  26   14 x  2 =  28   15 x  2 =  30
11 x  3 =  33   12 x  3 =  36   13 x  3 =  39   14 x  3 =  42   15 x  3 =  45
11 x  4 =  44   12 x  4 =  48   13 x  4 =  52   14 x  4 =  56   15 x  4 =  60
11 x  5 =  55   12 x  5 =  60   13 x  5 =  65   14 x  5 =  70   15 x  5 =  75
11 x  6 =  66   12 x  6 =  72   13 x  6 =  78   14 x  6 =  84   15 x  6 =  90
11 x  7 =  77   12 x  7 =  84   13 x  7 =  91   14 x  7 =  98   15 x  7 = 105
11 x  8 =  88   12 x  8 =  96   13 x  8 = 104   14 x  8 = 112   15 x  8 = 120
11 x  9 =  99   12 x  9 = 108   13 x  9 = 117   14 x  9 = 126   15 x  9 = 135
11 x 10 = 110   12 x 10 = 120   13 x 10 = 130   14 x 10 = 140   15 x 10 = 150
11 x 11 = 121   12 x 11 = 132   13 x 11 = 143   14 x 11 = 154   15 x 11 = 165
11 x 12 = 132   12 x 12 = 144   13 x 12 = 156   14 x 12 = 168   15 x 12 = 180
11 x 13 = 143   12 x 13 = 156   13 x 13 = 169   14 x 13 = 182   15 x 13 = 195
11 x 14 = 154   12 x 14 = 168   13 x 14 = 182   14 x 14 = 196   15 x 14 = 210
11 x 15 = 165   12 x 15 = 180   13 x 15 = 195   14 x 15 = 210   15 x 15 = 225
11 x 16 = 176   12 x 16 = 192   13 x 16 = 208   14 x 16 = 224   15 x 16 = 240
11 x 17 = 187   12 x 17 = 204   13 x 17 = 221   14 x 17 = 238   15 x 17 = 255
11 x 18 = 198   12 x 18 = 216   13 x 18 = 234   14 x 18 = 252   15 x 18 = 270
11 x 19 = 209   12 x 19 = 228   13 x 19 = 247   14 x 19 = 266   15 x 19 = 285

16 x  1 =  16   17 x  1 =  17   18 x  1 =  18   19 x  1 =  19
16 x  2 =  32   17 x  2 =  34   18 x  2 =  36   19 x  2 =  38
16 x  3 =  48   17 x  3 =  51   18 x  3 =  54   19 x  3 =  57
16 x  4 =  64   17 x  4 =  68   18 x  4 =  72   19 x  4 =  76
16 x  5 =  80   17 x  5 =  85   18 x  5 =  90   19 x  5 =  95
16 x  6 =  96   17 x  6 = 102   18 x  6 = 108   19 x  6 = 114
16 x  7 = 112   17 x  7 = 119   18 x  7 = 126   19 x  7 = 133
16 x  8 = 128   17 x  8 = 136   18 x  8 = 144   19 x  8 = 152
16 x  9 = 144   17 x  9 = 153   18 x  9 = 162   19 x  9 = 171
16 x 10 = 160   17 x 10 = 170   18 x 10 = 180   19 x 10 = 190
16 x 11 = 176   17 x 11 = 187   18 x 11 = 198   19 x 11 = 209
16 x 12 = 192   17 x 12 = 204   18 x 12 = 216   19 x 12 = 228
16 x 13 = 208   17 x 13 = 221   18 x 13 = 234   19 x 13 = 247
16 x 14 = 224   17 x 14 = 238   18 x 14 = 252   19 x 14 = 266
16 x 15 = 240   17 x 15 = 255   18 x 15 = 270   19 x 15 = 285
16 x 16 = 256   17 x 16 = 272   18 x 16 = 288   19 x 16 = 304
16 x 17 = 272   17 x 17 = 289   18 x 17 = 306   19 x 17 = 323
16 x 18 = 288   17 x 18 = 306   18 x 18 = 324   19 x 18 = 342
16 x 19 = 304   17 x 19 = 323   18 x 19 = 342   19 x 19 = 361




Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Posted by Scripter
,

간단한 Groovy 스크립트:

def name='World'; println "Hello $name!"

다소 복잡한 Groovy 스크립트:

class Greet {
  def name
  Greet(who) { name = who[0].toUpperCase() + who[1..-1] }
  def salute() { println "Hello $name!" }
}

g = new Greet('world')  // 객체 생성
g.salute()              // "Hello World!"를 출력




Apache의 commons.lang 라이브러리를 이용한 스크립트
(한 개의 소스 파일로 저장한다.):

class Greet {
  def name
  Greet() {  }
  Greet(who) { name = who[0].toUpperCase() + who[1..-1] }
  def salute() { println "Hello, $name!" }
}
g = new Greet('world')  // 객체 생성
g.salute()              // "Hello, World!"를 출력

import static org.apache.commons.lang.WordUtils.*

















명령행 스크립트로 실행한 경우:
groovy -e "println 'Hello ' + args[0] + '!'" World
Posted by Scripter
,

아래의 소스 코드는 Groovy로도 실행되는 Java 용 소스파일 TestWhileLoop.java를 Groovy 용으로 Groovy 언어 답게 고친 것이다.

소스 파일명: testWhile.groovy

  1. /*
  2.  *  Filename: testWhile.groovy
  3.  *
  4.  *  Purpose:  Example using the while loop syntax
  5.  *                while ....
  6.  *
  7.  *  Execute: groovy testWhile.groovy -200 300
  8.  *
  9.  */
  10. // java.lang.Math 클래스를 명시적으로 import하는 구문이 없어도
  11. // Groovy는 이 클래스를 자동으로 import한다.
  12. // 사용법 표시
  13. def printUsage() {
  14.     println 'Using: groovy testWhile.groovy [integer1] [integer2]'
  15.     println 'This finds the greatest common divisor of the given two integers.'
  16. }
  17. if (args.length != 2) {
  18.     printUsage()
  19.     System.exit(1)
  20. }
  21. def val1 = args[0].toLong()
  22. def val2 = args[1].toLong()
  23. def a, b, q, r, gcd
  24. ////////////////////////////////////////////////
  25. // 명령행 인자의 두 스트링을 가져와서
  26. // 긴정수(long) 타입으로 변환하여
  27. // 변수 val1과 val2에 저장한다.
  28. a = val1.abs()
  29. b = val2.abs()
  30. // a는 |val1|, |val2| 중 큰 값
  31. if (a < b) {
  32.     a = val2.abs()
  33.     b = val1.abs()
  34. }
  35. if (b == 0L) {
  36.     println "GCD($val1, $val2) = $a"
  37.     System.exit(0)
  38. }
  39. ////////////////////////////////////////
  40. // Euclidean 알고리즘의 시작
  41. //
  42. // a를 b로 나누어 몫은 q에, 나머지는 r에 저장
  43. q = a / b
  44. r = a % b
  45. ////////////////////////////////////////
  46. // Euclidean 알고리즘의 반복 (나머지 r이 0이 될 때 까지)
  47. while (r != 0L) {
  48.     a = b
  49.     b = r
  50.     q = a / b
  51.     r = a % b
  52. }
  53. // 나머지가 0이면 그 때 나눈 수(제수) b가 최대공약수(GCD)이다.
  54. gcd = b
  55. // 최대공약수(GCD)를 출력한다.
  56. println "GCD($val1, $val2) = $gcd"


실행> groovy testWhile.groovy
Using: groovy testWhile.groovy [integer1] [integer2]
This finds the greatest common divisor of the given two integers.

실행> groovy testWhile.groovy -50, 200
GCD(-50, 200) = 50

실행> groovy testWhile.groovy 50, -30
GCD(50, -30) = 10

실행> groovy testWhile.groovy 0. 30
GCD(0, 30) = 30




Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

Posted by Scripter
,