[파일명:  testSort.groovy]------------------------------------------------
List<String> list = Arrays.asList(args)
Collections.sort(list)
println(list)
------------------------------------------------


실행> groovy testSort.groovy 자전차 자전거 전동차 전차 전기자동차
["자전거", "자전차", "전기자동차", "전동차", "전차"]



[참고: 한글 문제]
Groovy 버전 1.5.8 이나 1.6.1을 윈도우용 인스톨러로 설치한 경우에는
명령행 옵션으로 넣어준 한글을 잘 처리하지 못한다.

Groovy 버전 1.5.8 이나 1.6.1을 zip 파일로 설치한 경우에는
명령행 옵션으로 넣어준 한글을 잘 처리한다.


 

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Scripter
,


정의
(소수와 합성수)
    1보다 큰 양의 정수 n에 대하여
    (i) n = a * b 를 만족하고 1보다 큰 두 양의 정수 a와 b가 존재하면,
        n을 합성수(合成數, composite number)라고 한다. 참고로 이 경우,
        a, b 중에 적어도 하나는 sqrt(n) 보다 작거나 같다.
        합성수의 예로는 4, 6, 9, 24, 143 등이 있다.
    (ii) n = a * b 를 만족하고 1보다 큰 두 양의 정수 a와 b가 존재하지 않으면,
         즉 n을 두 양의 정수의 곱으로 표현하는 방법이 1*n과 n*1 두 가지 뿐이면,
         n을 소수(素數, prime number)라고 한다.  소수의 예로는 2, 3, 5, 7, 11 등이 있다.
         n이 소수인지 아닌지 확인하려면, 
         n을 2 보다 크거나 같고 sqrt(n) 보다 작거나 같은 모든 정수로 나누어 본다.
         이 경우 언제나 나누어 떨어지지  않으면 n은 소수이고, 그렇지 않으면 n은 합성수이다.
    

우선 다음의 Groovy 소스 코드는 명령행 인자로 전달 받은 양의 정수 n을
2 및 3, 5, 7, ... , sqrt(n) 이하의 홀수들로 나누어 보아 n이 합성수인지 아닌지
확인하는 애플리케이션 소스이다. 확인하는데 걸린 경과 시간도 알려준다.


/*
 * Filename: divideEach.groovy
 *
 *  Purpose: Determine whether the given integer is a prime or not.
 *
 *  Execute: groovy divideEach.groovy [integer]
 *
 *     Date: 2009/03/23
 *   Author: PH Kim   [ pkim ((AT)) scripts.pe.kr ]
 */

/*
  Execution Examples (with Groovy 1.6.0):

      Prompt> groovy divideEach.groovy 1234567812343
      1234567812343 = 1 * 1234567812343
      1234567812343 is a prime
      Elapsed time: 4.953 sec
 
      Prompt> groovy divideEach.groovy 9999994200000841
      9999994200000841 = 99999971 * 99999971
      9999994200000841 is a not prime
      Elapsed time: 468.688 sec

      Prompt> groovy divideEach.groovy 18446744073709551617
      18446744073709551617 = 274177 * 67280421310721
      18446744073709551617 is a not prime
      Elapsed time: 1.594 sec

      Prompt> groovy divideEach.groovy 10023859281455311421
      10023859281455311421 = 1308520867 * 7660450463
      10023859281455311421 is a not prime
      Elapsed time: 3521.562000 sec
*/

BigInteger n = 10006099720301
if (args.length > 0) {
    n = new BigInteger(args[0])
}

BigInteger z = n / 2G    // z = n / 2
if (n == 2G*z) {
    print "${n} = 2 * ${z}\n"
}

def time1 = new GregorianCalendar().getTime().getTime()

BigInteger d = 1
BigInteger k = 3
while (k*k <= n) {
    z = n / k    // z = n / k
    if (n == k*z) {
        d = k
        break
    }
    k = k + 2G
}

def time2 = new GregorianCalendar().getTime().getTime()

print "$n = $d * ${n/d}\n"
if (d == 1)
    print "$n is a prime\n"
else
    print "$n is a not prime\n"

print "Elapsed time: ${(time2 - time1)/1000.0} sec\n"




이제 다음은 정수의 인수분해 능력이 뛰어난  Pollard의 rho 방법(일명 거북이와 토끼 알고리즘, tortoise-hair algorithm)을 구현한  Groovy 소스 코드이다. 이 알고리즘은 소수에 대해서는 시간이 많이 걸리지만, 합성수에 대해서는 시간이 매우 적게 걸린다는 것이 특징이다.


/*
 * Filename: pollardRho.groovy
 *
 *  Purpose: By using the pollard rho method,
 *           determine whether the given integer is a prime or not.
 *
 *      See: http://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
 *           http://en.wikipedia.org/wiki/Floyd%27s_cycle-finding_algorithm#Tortoise_and_hare#
 *
 *  Execute: groovy pollardRho.groovy [integer]
 *
 *     Date: 2009/03/24
 *   Author: PH Kim   [ pkim ((AT)) scripts.pe.kr ]
 */

/*
  Execution Examples (with Groovy 1.6.0):

      Prompt> groovy pollardRho.groovy 1234567812343
      Try first the Pollard rho algorithm with c = 2
      d = 1234567812343, count = 466951
      Try second the Pollard rho algorithm with c = 3
      d = 1, count = 1111112
      Try third the Pollard rho algorithm with c = 1
      d = 1234567812343, count = 799441
      1234567812343 = 1234567812343 * 1
      Elapsed time: 33.937 sec

      Prompt> groovy pollardRho.groovy 9999994200000841
      Try first the Pollard rho algorithm with c = 2
      d = 99999971, count = 3593
      9999994200000841 = 99999971 * 99999971
      Elapsed time: 0.156 sec

      Prompt> groovy pollardRho.groovy 18446744073709551617
      Try first the Pollard rho algorithm with c = 2
      d = 274177, count = 1028
      18446744073709551617 = 274177 * 67280421310721
      Elapsed time: 0.11 sec

      Prompt> groovy pollardRho.groovy 10023859281455311421
      Try first the Pollard rho algorithm with c = 2
      d = 1308520867, count = 20350
      10023859281455311421 = 1308520867 * 7660450463
      Elapsed time: 0.579 sec
*/

BigInteger f(BigInteger x, BigInteger c, BigInteger n) {
    return (x*x + c) % n
}

BigInteger g(BigInteger x, BigInteger c, BigInteger n) {
    return f(f(x, c, n), c, n)
}

BigInteger gcd(BigInteger x, BigInteger y) {
    BigInteger a, b, t
    a = x.abs()
    b = y.abs()
    if (b == 0G) {
        return a
    }
    while (b != 0G) {
        t = a % b
        a = b
        b = t
    }
    return a
}

BigInteger pollardRho(BigInteger n) {
    BigInteger c = 2G
    BigInteger x = 1G
    BigInteger y = 1G
    BigInteger d = 1G
    BigInteger savedX = x
    BigInteger count = 0
    println("Try first the Pollard rho algorithm with c = $c")
    while (d == 1G && count*count <= n) {
        x = f(x, c, n)
        if (x == savedX) {
         println("It is cyclic.  x = $x")
         break
        }
        y = g(y, c, n)
        d = gcd((x - y).abs(), n)
        count = count + 1
        // if (count % 5000 == 0) {
        //  println("  count = $count")
        // }
    }

    println("d = $d, count = $count")
    if (d > 1 && d < n) {
        return d
    }

    c = 3
    x = 1
    y = 1
    d = 1
    savedX = x
    count = 0
    println("Try second the Pollard rho algorithm with c = $c")
    while (d == 1 && count*count <= n) {
        x = f(x, c, n)
        if (x == savedX) {
         println("It is cyclic.  x = $x")
         break
        }
        y = g(y, c, n)
        d = gcd(Math.abs(x - y), n)
        count = count + 1
        // if (count % 5000 == 0) {
        //  println("  count = $count")
        // }
    }

    println("d = $d, count = $count")
    if (d > 1 && d < n) {
        return d
    }

    c = 1
    x = 1
    y = 1
    d = 1
    savedX = x
    count = 0
    println("Try third the Pollard rho algorithm with c = $c")
    while (d == 1 && count*count <= n) {
        x = f(x, c, n)
        if (x == savedX) {
         println("It is cyclic.  x = $x")
         break
        }
        y = g(y, c, n)
        d = gcd(Math.abs(x - y), n)
        count = count + 1
        // if (count % 5000 == 0) {
        //  println("  count = $count")
        // }
    }

    println("d = $d, count = $count")

    return d
}

BigInteger n, k, z
n = 9991
if (args.length > 0) {
    n = new BigInteger(args[0])
}

def time1 = new GregorianCalendar().getTime().getTime()

k = pollardRho(n)
z = n/k
// if (n == k*z) {
    println("$n = $k * $z")
// }

def time2 = new GregorianCalendar().getTime().getTime()
print "Elapsed time: ${(time2 - time1)/1000.0} sec\n"


 

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

Posted by Scripter
,


초등학교 때 배우는 두 정수의 곱셈표를 만들어 주는 Groovy 소스이다.

/**
 * Filename: makeMultTable.groovy
 *
 *     Print a multiplication table.
 *
 *     Execute: groovy makeMultTable.groovy 230 5100
 *
 * Date: 2009/03/06
 * Author: pkim (AT) scripts.pe.kr
 */

import java.io.*;
import java.util.*;

def printUsing() {
    println "Using: groovy makeMultTable.groovy [number1] [number2]"
    println "Print a multiplication table for the given two integers."
}

def printMultTable(x, y) {
    long nx = (x >= 0L) ? x : - x;
    long ny = (y >= 0L) ? y : - y;
    int ntail1 = 0;
    int ntail2 = 0;
    while (nx % 10 == 0) {
        nx = nx / 10;
        ntail1++;
    }
    while (ny % 10 == 0) {
        ny = ny / 10;
        ntail2++;
    }
    long z = nx * ny;
    def strZ = "" + z;
    def strX = "" + nx;
    def strY = "" + ny;
    def n = strY.length();
    def zeros  = "0000000000000000000000000000000000000000";
    def whites = "                                        ";
    def bars   = "----------------------------------------";
    def line1, line2, line3, line4;
    def loffset = "       ";
    line4 = loffset + strZ;
    line1 = loffset + whites.substring(0, strZ.length() - strX.length()) + strX;
    line2 = "   x ) " +  whites.substring(0, strZ.length() - strY.length()) + strY;
    line3 = "     --" +  bars.substring(0, strZ.length());
    println(line1 + zeros.substring(0, ntail1));
    println(line2 + zeros.substring(0, ntail2));
    println(line3);
    if (strY.length() > 1) {
        def y1;
        def strT;
        for (int i = 0; i < strY.length(); i++) {
            y1 = Integer.parseInt(strY.substring(strY.length() - i - 1, strY.length() - i));
            if (y1 != 0) {
                strT = "" + (nx * y1);
                    println(loffset + whites.substring(0, strZ.length() - strT.length() - i) + strT);
            }
        }
        println(line3);
    }
    println(line4 + zeros.substring(0, ntail1) + zeros.substring(0, ntail2));
}

long x, y;
if (args.length >= 2) {
    x = Integer.parseInt(args[0]);
    y = Integer.parseInt(args[1]);
    println("");
    printMultTable(x, y);
}
else {
    printUsing();
}




실행> groovy makeMultTable.groovy 230 5100
결과>

          230
   x )   5100
     ------
         23
       115
     ------
       1173000

 

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

 

Posted by Scripter
,
a = "Hello, world!";
b = "안녕하세요?";
println a.reverse()
println b.reverse()
/*
Expected result:
!dlrow ,olleH
?요세하녕안
*/





Creative Commons License

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

Posted by Scripter
,

다음은 초등학교에서 배우는 나눗셈 계산표를 만들어주는 Groovy 소스 코드이다.
나눗셈 계산표를 완성하고 나서 약수, 배수 관계를 알려준다.


  1. /*
  2.  *  Filename: makeDivisionTable.groovy
  3.  *
  4.  *  Purpose:  Make a division table in a handy written form.
  5.  *
  6.  *  Execute: groovy makeDivisionTable.groovy 12345 32
  7.  *           groovy makeDivisionTable.groovy 500210 61
  8.  *
  9.  *     Date:  2008/05/15
  10.  *   Author:  PH Kim   [ pkim ((AT)) scripts.pe.kr ]
  11.  */
  12. def printUsage() {
  13.     println("사용법: groovy makeDivisionTable.groovy [피제수] [제수]")
  14.     println("손으로 작성한 형태의 나눗셈 표를 만들어준다.")
  15. }
  16. def simplify(BigInteger v, int width) {
  17.     String t = "" + v
  18.     if (t.endsWith(".0"))
  19.         t = t.substring(0, t.length() - 2)
  20.         int len = t.length()
  21.         if (len < width)
  22.             t = "                                                                                             ".substring(0, width - len) + t;
  23.     return t
  24. }
  25. def getSuffix(BigInteger v) {
  26.     BigInteger t = v % 10G
  27.     String suffix = "은"
  28.     if ("2459".indexOf("" + t) >= 0) {
  29.         suffix = "는"
  30.     }
  31.     return suffix
  32. }
  33. BigInteger makeTable(BigInteger numer, BigInteger denom, BigInteger quotient) {
  34.     String strNumer = "" + numer
  35.     String strDenom = "" + denom
  36.     String strQuotient = "" + quotient
  37.     int lenN = strNumer.length()
  38.     int lenD = strDenom.length()
  39.     int lenQ = strQuotient .length()
  40.     int offsetLeft = 3 + lenD + 3
  41.     String spaces = "                                                                                 ";
  42.     String uline  = "_" * (lenN + 2)
  43.     String sline  = "-" * lenN
  44.     int bias = lenN - lenQ
  45.     println(spaces.substring(0, offsetLeft) + spaces.substring(0, bias) + quotient)
  46.     println(spaces.substring(0, offsetLeft - 2) + uline)
  47.     System.out.print("   " + strDenom + " ) " + strNumer)
  48.     String strTmpR = strNumer.substring(0, bias + 1)
  49.     BigInteger tmpR = new BigInteger(strTmpR)
  50.     BigInteger tmpSub = 0G
  51.     String oneDigit = null
  52.     for (int i = 0; i < lenQ; i++) {
  53.         if (strQuotient.substring(i, i + 1).equals("0")) {
  54.             if (i + 1 < lenQ) {
  55.                 oneDigit = strNumer.substring(bias + i + 1, bias + i + 2)
  56.                 print(oneDigit)
  57.                 strTmpR += oneDigit
  58.                 tmpR = new BigInteger(strTmpR)
  59.             }
  60.         }
  61.             else {
  62.             println()
  63.             tmpSub = new BigInteger(strQuotient.substring(i, i + 1)).multiply(denom)
  64.             println(spaces.substring(0, offsetLeft) + simplify(tmpSub, bias + i + 1))
  65.             println(spaces.substring(0, offsetLeft) + sline)
  66.             tmpR = tmpR.subtract(tmpSub)
  67.             if (tmpR == 0G && i + 1 < lenQ) {
  68.                 print(spaces.substring(0, offsetLeft) + spaces.substring(0, bias + i + 1))
  69.             }
  70.             else {
  71.                 print(spaces.substring(0, offsetLeft) + simplify(tmpR, bias + i + 1))
  72.             }
  73.             strTmpR = "" + tmpR;
  74.             if (i + 1 < lenQ) {
  75.                 oneDigit = strNumer.substring(bias + i + 1, bias + i + 2)
  76.                 print(oneDigit)
  77.                 strTmpR += oneDigit
  78.                 tmpR = new BigInteger(strTmpR)
  79.             }
  80.         }
  81.     }
  82.     println()
  83.     return tmpR
  84. }
  85. if (args.length < 2) {
  86.     printUsage()
  87.     System.exit(1)
  88. }
  89. BigInteger a = null
  90. BigInteger b = null
  91. try {
  92.     a = new BigInteger(args[0])
  93.     b = new BigInteger(args[1])
  94. }
  95. catch (NumberFormatException ex) {
  96.     println("피제수: " + args[0] + ", 제수: " + args[1])
  97.     println("숫자 입력에 오류가 있습니다.")
  98.     System.exit(1)
  99. }
  100. if (a.compareTo(BigInteger.ZERO) <= 0) {
  101.     println("피제수: " + a)
  102.     println("피제수는 양의 정수라야 합니다.")
  103.     System.exit(1)
  104. }
  105. else if (b.compareTo(BigInteger.ZERO) <=0) {
  106.     println("제수: " + b)
  107.     println("제수는 양의 정수라야 합니다.");
  108.     System.exit(1)
  109. }
  110. BigInteger q = a.divide(b)
  111. BigInteger r = a.mod(b)
  112. print("나눗셈 " + a + " ÷ " + b + " 의 결과: ")
  113. print("몫: " + q + ", ")
  114. println("나머지: " + r)
  115. println()
  116. BigInteger k = makeTable(a, b, q)
  117. if (k == r) {
  118.     println("\n나머지: " + k)
  119. }
  120. if (k == 0G) {
  121.     println(a + " = " + b + " x " + q)
  122.     println(a + getSuffix(a) + " " + b + "의 배수(mupltiple)이다.")
  123.     println(b + getSuffix(b) + " " + a + "의 약수(divisor)이다.")
  124. }
  125. else {
  126.     println(a + " = " + b + " x " + q + " + " + r)
  127.     println(a + getSuffix(a) + " " + b + "의 배수(mupltiple)가 아니다.")
  128. }




실행> groovy makeDivisionTable.groovy 500210 61

나눗셈 500210 ÷ 61 의 결과: 몫: 8200, 나머지: 10

          8200
      ________
   61 ) 500210
        488
        ------
         122
         122
        ------
            10

나머지: 10
500210 = 61 x 8200 + 10
500210은 61의 배수(mupltiple)가 아니다.




Creative Commons License

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

Posted by Scripter
,
Groovy 언어는 Java 언어와 달리 한 개의 소스 파일 내에 public 이든 아니든 여러 개의 클래스가 존재해도 된다. 또 클래스명과 다른 파일명으로 저장해도 된다. Groovy 언어도 Java, C 언어 처럼 대소문자 구별을 엄격히 하지만 public 클래스와 대소문자만 듵린 파일명으로 저장해도 아무 상관 없다.

다음은 두 개의 클래스로 구성되어 있다.
Parent는 부모 클래스이고 Child는 Parent에서 상속 받은 자식 클래스이다.



// Filename: testSubclassing.groovy
public class Parent {
    private String name
    public Parent(String name) {              // 생성자
        this.name =  name
    }
    public void sayName() {
        println("I am Parent, " + name)
    }
}

public class Child extends Parent {
    private String name
    public Child(String name) {                // 생성자
        super(name)                   // 클래스 상속시 부모 클래스 생성자 호출
        this.name =  name
    }
    public void sayName() {
        println("I am a child, named as " + name)
    }
}

def obj = new Child("Dooly")                   // 클래스 생성
obj.sayName()




실행> groovy testSubclassing.groovy
I am a child, named as Dooly




Creative Commons License

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

java.awt.Desktop 클래스는 JDK 1.6 부터 등장한 클래스이다.
이를 이용하면 시시템에 기본 웹 브라우저를 지정한 URL 주소로 직접 띄울 수 있다.

먼저, Java 소스 코드이다.  만일 파일 확장명을 groovy로 저장하면 실행 명령

        groovy TestAWTDesktop.groovy URL주소

으로 소스 코드를 직접 실행시킬 수 있다.



Java (또는 Groovy) 코드

import java.awt.Desktop;
import java.io.*;
import java.net.*;

class TestAwtDesktop {

    public static void main(String[] args) {
        if (Desktop.isDesktopSupported()) {
            Desktop desktop = Desktop.getDesktop();
            if (desktop.isSupported(Desktop.Action.BROWSE)) {
                String uri = args[0];
                try {
                    desktop.browse(new URI(uri));
                }
                catch (URISyntaxException ex) {
                    ex.printStackTrace();
                }
                catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}



아래는 위의 소스 코드를 Groovy의 간편 문법에 맞게 고친 것이다.

실행 명령:  groovy testAwtDesktopSimple.groovy URL주소


Groovy 코드

import java.awt.Desktop

if (Desktop.isDesktopSupported()) {
    def desktop = Desktop.desktop
    if (desktop.isSupported(Desktop.Action.BROWSE)) {
        desktop.browse(new URI(args[0]))
    }
}





Creative Commons Licence This work is licensed under the Creative Commons Attribution 2.0 License


Posted by Scripter
,

콘솔에 삼각형

         *
       * *
      *   *
     *     *
    *       *
   *         *
  *           *
 *             *
*****************


을 출력하는 Groovy 소스 코드를 작성해 보자. 이런 소스 코드의 작성은 학원이나 학교에서 프로그래밍 입문자에게 과제로 많이 주어지는 것 중의 하나이다. 코끼리를 보거나 만진 사람들이 저마다 그 생김새를 말할 때 제각기 다르게 표현할 수 있듯이 이런 소스 코드의 작성도 알고 보면 얼마든지 많은 방법이 있을 것이다. 여기서는 쉬운 코드 부터 작성해 보고 차츰차츰 소스를 바꾸어 가면서 Groovy 프로그래밍의 기초부분을 터득해 보기로 한다.

모든 소스 코드에서는 삼각형 출력 부분 담당 함수 printTriange()를 별도로 구현하였다.

우선 첫번 째 예제는 Groovy의 컨솔 출력 함수 println()의 사용법 만 알면 누구나 코딩할 수 있는 매우 단순한 소스 코드이다.


삼각형 출력 예제 1
/*
 *  Filename: printTriangle1.groovy
 *            Print a triangle on console.
 *
 *  Execute: groovy printTriangle1.groovy
 *
 *      Date:  2008/04/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

def printTriange() {
     println("        *        ")
     println("       * *       ")
     println("      *   *      ")
     println("     *     *     ")
     println("    *       *    ")
     println("   *         *   ")
     println("  *           *  ")
     println(" *             * ")
     println("*****************")
}

printTriange()




위의 소스 코드는 아무 알고리즘도 없는 너무 단순한 코드이다. 이런 코드를 작성했다간 출력 모양이나 크기를 변경해야 하는 상황을 맞이하면 워드프로세서로 문서 만드는 것 이상으로 많은 수작업을 하거나 아니면 포기하는 지경에 이를 수도 있다. 그래서 다음 처럼 좀 더 나은 소스 코드를 작성하였다.



삼각형 출력 예제 2
/*
 *  Filename: printTriangle2.groovy
 *            Print a triangle on console.
 *
 *  Execute: groovy printTriangle2.groovy
 *
 *      Date:  2008/04/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

def printTriange() {
    for (i in 0..<8) {
        for (k in 0..<8-i) {
            print(" ")
        }
        for (k in 0..<2*i+1) {
            if (k == 0 || k == 2*i)
                print("*")
            else
                print(" ")
        }
        for (k in 0..<8-i) {
            print(" ")
        }
        println()
    }

    for (i in 0..<17) {
        print("*")
    }
    println()
}

printTriange()



위의 소스 코드는 Groovy의 컨솔 출력 함수 println()와 print() 그리고 for 반복 구문을 적절히 사용하여 구현되었다. 숫자 몇 곳만 수정하면 출력되는 삼각형의 크기를 바꿀 수 있다. 한 줄에 출력될 문자를 구성하는 알고리즘은 위의 예제와 근본적으로 같지만 print()를 사용하지 않고, 그대신 char[] 타입의 배열을 만들어 한 즐씩 출력하는 소스 코드를 다음 예제와 같이 작성해 보았다.
또 빈칸 17개의 문자로 구성된 스트링을 생성하기 위한 구문

    def whites = " "*17

도 음미해볼 만하다. (string*number 또는 list*number의 구문은 Python, Ruby 언어에서도 지원된다.)



삼각형 출력 예제 3
/*
 *  Filename: printTriangle3.groovy
 *            Print a triangle on console.
 *
 *  Execute: groovy printTriangle3.groovy
 *
 *      Date:  2008/04/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

def printTriange() {
    def line = " "*17
    def line2 = " "*17 as char[]

    for (int i in 0..<8) {
        ine2 = " "*17 as char[]
        line2[8-i] =  '*'
        line2[8+i] =  '*'
        println(new String(line2))
    }

    line2 = " "*17 as char[]
    for (i in 0..<17) {
        line2[i] =  '*'
    }
    println(new String(line2))
}

printTriange()



별(*) 문자를 이용하여 삼각형을 출력하는 일은 빈칸 문자와 별 문자를 적당한 좌표(위치)에 촐력하는 일이다. StringBuffer를 사용하더라도 한 줄의 출력을 빈칸 만으로로 구성된 string(소스 코드에서 변수 whites가 참조하는 string 값)을 기본으로 하고, 이 string에 한 두 개의 빈칸을 바꾸어 출력하는 기법으로 작성한 것이 다음 소스 코드이다. 단, 마지막 줄에 츨력될 string은 stars라는 별도의 변수로 처리하였다.


삼각형 출력 예제 4
/*
 *  Filename: printTriangle4.groovy
 *            Print a triangle on console.
 *
 *  Execute: groovy printTriangle4.groovy
 *
 *      Date:  2008/04/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

def printTriange() {
    def whites = " "*17
    def stars  = "*"*17
    def line2 = new StringBuffer(whites)
    line2 = line2.replace(8, 9, "*")
    println(line2)
    for (int i in 1..<8) {
        line2 = new StringBuffer(whites)
        line2 = line2.replace(8-i, 8+i, stars.substring(8-i, 8+i))
        line2 = line2.replace(8-i+1, 8+i-1, whites.substring(8-i, 8+i-1))
        println(line2)
    }
    println(stars)
}

printTriange()




빈칸 문자를 별(*) 문자로 바꾸기 위해, 위의 소스 코드에서는 StringBuffer.replace() 메소드를 이용하였지만, 다음 소스 코드에서는 StringBuffer.setCharAt() 메소드를 이용하였다.



삼각형 출력 예제 5
/*
 *  Filename: printTriangle5.groovy
 *            Print a triangle on console.
 *
 *  Execute: groovy printTriangle5.groovy
 *
 *      Date:  2008/04/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

def printTriange() {
    def whites = " "*17
    def stars  = "*"*17
    def line = new StringBuffer(whites)
    def start = 8
    line = line.replace(start, start, "*")
    println(line)
    for (int i in 1..<8) {
        line = new StringBuffer(whites)
        line.setCharAt(start - i, stars.charAt(start - i))
        line.setCharAt(start + i, stars.charAt(start + i))
        println(line)
    }
    println(stars)
}

printTriange()




출력되는 삼각형이 좌우 대칭이라는 사실에 착안하여, 다음 소스 코드에서는  각 줄을 처음 8자, 중앙 한 문자, 끝 8자(처음 8자의 역순)로 string을 만들어 출력하였다.



삼각형 출력 예제 6
/*
 *  Filename: printTriangle6.groovy
 *            Print a triangle on console.
 *
 *  Execute: groovy printTriangle6.groovy
 *
 *      Date:  2008/04/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

def printTriange() {
    def whites = " "*8
    def stars  = "*"*8
    def start = 8
    def line = new StringBuffer(whites)
    line.append('*')
    line.append(whites)
    println(line)

    for (int i in 1..<8) {
        line = new StringBuffer(whites)
        line.setCharAt(start - i, stars.charAt(start - i))
        print(line)
        print(" ")
        line.reverse()
        println(line)
    }

    line = new StringBuffer(stars)
    line.append('*')
    line.append(stars)
    println(line)
}

printTriange()




다음 소스 코드는 한 줄에 출력될 문자열의 데이터를 17비트 이진법 수로 구성하고, 이 이진법수의 비트가 0인 곳에는 빈칸을, 1인 곳에는 별(*)을 출력하는 기법으로 작성되었다.



삼각형 출력 예제 7
/*
 *  Filename: printTriangle7.groovy
 *            Print a triangle on console.
 *
 *  Execute: groovy printTriangle7.groovy
 *
 *      Date:  2008/04/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

def printTriange() {
    def start = 0x100
    def total = 0
    def val = start
    def data = ""

    for (k in 0..<8) {
        val = (start << k) | (start >> k)
        data = Integer.toString(val, 2)
        for (i in 0..<17 - data.length()) {
            print(' ')
        }
        for (i in 0..<data.length()) {
            if (data[i] == '0')
                print(' ')
            else
                print('*')
        }
        println()
        total += val
    }

    val = (start << 8) | (start >> 8)
    total += val
    data = Integer.toString(total, 2)
    for (i in 0..<17 - data.length()) {
        print(' ')
    }
    for (i in 0..<data.length()) {
        if (data[i] == '0')
            print(' ')
        else
            print('*')
    }
    println()
}

printTriange()




기본적인 원리는 위의 소스 코드와 같지만 이진법수의 한 비트 마다 한 문자씩 츨력하는 대신에 출력된 한 줄의 string을 완성하여 이를 println() 으로 출력하는 기법으로 재작성한 것이 다음의 소스 코드이다. String.replaceAll() 메소드를 이용하여 모든 0을 빈칸으로, 모든 1을 별(*) 문자로 바꾸었으며, 별(*) 문자만으로 이루어진 마지막 줄 출력을 위해 변수 total을 준비하였다. for 반복 구문의 블럭 내에서 구문

            total |= val

이 하는 일이 무엇인지 이해할 수 있으면 좋겠다.




삼각형 출력 예제 8
/*
 *  Filename: printTriangle8.groovy
 *            Print a triangle on console.
 *
 *  Execute: groovy printTriangle8.groovy
 *
 *      Date:  2008/04/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

def printTriange() {
    def zeros  = "00000000"
    def start = 0x100
    def total = 0
    def val = start
    def line = ""
    def data = ""

    for (k in 0..<8) {
        val = (start << k) | (start >> k)
        data = Integer.toString(val, 2)
        line = zeros[0..<17-data.length()] + data
        line = line.replaceAll("0", " ")
        line = line.replaceAll("1", "*")
        println(line)
        total |= val
    }

    val = (start << 8) | (start >> 8)
    total |= val
    line = Integer.toString(total, 2)
    line = line.replaceAll("0", " ")
    line = line.replaceAll("1", "*")
    println(line)
}

printTriange()




소스 코드가 처음 것 보다 매우 복잡해졌지만, Groovy의 리스트를 이용해서 구현해 보았다. Groovy 언어 외에 Python, Ruby 언어 같은 스크립팅 언어에서도 리스트와 맵은 매우 중요하게 취급되며, 구문에서도 이를 위한 문법을 제공하고 있다. 별(*) 문자만으로 이루어진 마지막 줄 출력을 위해 리스트 타입의 변수 last를 준비하였다. 또 리스트에 속한 모든 item을 출력하는 부분

        data.each { print it }
        println

은 Groovy 언어에서 많이 사용되는 클로저(closure)를 이용한 구문이다. 이 두 줄은 리스트의 join 메소드를 이용하여

        println( data.join() )

로 해도 같은 출력을 얻는다.




삼각형 출력 예제 9
/*
 *  Filename: printTriangle9.groovy
 *            Print a triangle on console.
 *
 *  Execute: groovy printTriangle9.groovy
 *
 *      Date:  2008/04/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

def printTriange() {
    def start = 8
    def data = [" "]*17
    def last = [" "]*17

    data[start] = "*"
    last[start] = "*"
    data.each { print it }
    println()
    data[start] = " "

    for (k in 1..<8) {
        data[start - k] = "*"
        last[start - k] = "*"
        data[start + k] = "*"
        last[start + k] = "*"
        println( data.join() )
        data[start - k] = " "
        data[start + k] = " "
    }

    last[start - 8] = "*"
    last[start + 8] = "*"
    println(  last.join() )
}

printTriange()





다음 예제는 수학에서 xy-좌표평면에 점을 찍듯이 논리 구문

             (x + y - 8 == 0) || (y - x + 8 == 0) || (y - 8 == 0)

가 참이 되는 위치에 별(*) 문자를 표시하는 기법으로 작성된 소스 코드이다.




삼각형 출력 예제 10
/*
 *  Filename: printTriangle10.groovy
 *            Print a triangle on console.
 *
 *  Execute: groovy printTriangle10.groovy
 *
 *      Date:  2008/04/03
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

def printTriange() {
    def a
    for (y in 0..8) {
        for (x in 0..16) {
            if ((x + y - 8 == 0) || (y - x + 8 == 0) || (y - 8 == 0))
                a = '*'
            else
                a = ' '
            print a
        }
        println()
    }
}

printTriange()






Creative Commons License

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

Posted by Scripter
,

다음은 JDK 1.5 부터 등장한 java.util.Scanner 클래스를 이용하여 웹문서를 통째로 읽어들이는 Groovy 예제 소스 코드이다. 실행 예는

        groovy readWebText.groovy http://groovy.codehaus.org

이다.
(침고 자료: http://kr.sun.com/developers/techtips/c2004_1201.html#1 )


/*
 *  Filename: readWebText.groovy
 */

def readFile(String filename) {
    def connection = new URL(filename).openConnection()
    def scanner = new Scanner(connection.getInputStream()).useDelimiter("\\Z")
    String text = scanner.next()
    println text
    scanner.close()
}


if (args.length != 1) {
    println("Usage: groovy readWebText.groovy [url address]")
    System.exit(0)
}
readFile(args[0])

Posted by Scripter
,

ASCII(애스키)란 American Standard Cpde for Information Interchange의 줄임글로서, 영문자에 기초한 문자 인코딩이다.  이 문자 인코딩에는  C0 제어문자(C0 control character)도 포함되어 있다.  ( 참고:  ASCII - Wikipedia, the free encyclopedia )

다음은  7bit ASCII 코드표를 만들어 보여주는 Groovy 소스 코드이다.
소스 코드 중에 진법변환에 필요한 함수

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

의 구현도 포함되어 있다.


  1. /*
  2.  *  Filename: makeAsciiTable.groovy
  3.  *            Make a table of ascii codes.
  4.  *
  5.  *  Execute: groovy makeAsciiTable.groovy
  6.  *
  7.  *      Date:  2008/03/28
  8.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  9.  */
  10. def printUsage() {
  11.     println("Usage: groovy makeAsciiTable.groovy")
  12.     println("Make a table of ascii codes.")
  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.     def asc  = [
  88.      "NUL", "SOH", "STX", "ETX", "EOT",
  89.      "ENQ", "ACK", "BEL", "BS", "HT",
  90.      "LF", "VT", "FF", "CR", "SO",
  91.      "SI", "DLE", "DC1", "DC2", "DC3",
  92.      "DC4", "NAK", "SYN", "ETB", "CAN",
  93.      "EM", "SUB", "ESC", "FS", "GS",
  94.      "RS", "US", "Spc"
  95.     ] as String[]
  96.     def control  = [
  97.         "NUL (null)",
  98.         "SOH (start of heading)",
  99.         "STX (start of text)",
  100.         "ETX (end of text)",
  101.         "EOT (end of transmission)",
  102.         "ENQ (enquiry)",
  103.         "ACK (acknowledge)",
  104.         "BEL (bell)",
  105.         "BS  (backspace)",
  106.         "TAB (horizontal tab)",
  107.         "LF  (line feed, NL new line)",
  108.         "VT  (vertical tab)",
  109.         "FF  (form feed, NP new page)",
  110.         "CR  (carriage return)",
  111.         "SO  (shift out)",
  112.         "SI  (shift in)",
  113.         "DLE (data link escape)",
  114.         "DC1 (device control 1)",
  115.         "DC2 (device control 2)",
  116.         "DC3 (device control 3)",
  117.         "DC4 (device control 4)",
  118.         "NAK (negative acknowledge)",
  119.         "SYN (synchronous idle)",
  120.         "ETB (end of trans. block)",
  121.         "CAN (cancel)",
  122.         "EM  (end of medium)",
  123.         "SUB (substitute, EOF end of file)",
  124.         "ESC (escape)",
  125.         "FS  (file separator)",
  126.         "GS  (group separator)",
  127.         "RS  (record separator)",
  128.         "US  (unit separator)",
  129.     ] as String[]
  130.     String sbuf = ""
  131.     String abuf = ""
  132.     String tbuf = ""
  133.     int i, j
  134.     char c
  135.     print("    ");
  136.     for (i = 0; i < 8; i++) {
  137.         print("+----")
  138.     }
  139.     print("+")
  140.     println("")
  141.     print("    ")
  142.     print("| 0- ")
  143.     print("| 1- ")
  144.     print("| 2- ")
  145.     print("| 3- ")
  146.     print("| 4- ")
  147.     print("| 5- ")
  148.     print("| 6- ")
  149.     print("| 7- ")
  150.     print("|")
  151.     println("")
  152.     print("+---")
  153.     for (i = 0; i < 8; i++) {
  154.         print("+----")
  155.     }
  156.     print("+")
  157.     println("")
  158.     for (i = 0; i < 16; i++) {
  159.         tbuf = ""
  160.         sbuf = convertItoA((long) i, 16)
  161.         tbuf += "| " + sbuf + " "
  162.         for (j = 0; j < 8; j++) {
  163.             if (j*16 + i <= 32) {
  164.                 abuf = String.format("| %-3s", asc[j*16 + i])
  165.             }
  166.             else if (j*16 + i == 127) {
  167.                 abuf = String.format("| %-3s", "DEL")
  168.             }
  169.             else {
  170.                 c = (char) (j*16 + i)
  171.                 abuf = String.format("| %2c ", c);
  172.             }
  173.             tbuf += abuf
  174.         }
  175.         tbuf += "|"
  176.         println(tbuf)
  177.     }
  178.     print("+---")
  179.     for (i = 0; i < 8; i++) {
  180.         print("+----")
  181.     }
  182.     print("+")
  183.     println("")
  184.     println("")
  185.     for (i = 0; i < 16; i++) {
  186.         sbuf = String.format("%-30s",  control[i])
  187.         tbuf = String.format("  %-34s",  control[i+16])
  188.         print(sbuf)
  189.         println(tbuf)
  190.     }
  191. }
  192. if (args.length > 0 && "-h".equals(args[0])) {
  193.     printUsage()
  194.     System.exit(1)
  195. }
  196. makeTable()




실행> groovy makeAsciiTable.groovy

    +----+----+----+----+----+----+----+----+
    | 0- | 1- | 2- | 3- | 4- | 5- | 6- | 7- |
+---+----+----+----+----+----+----+----+----+
| 0 | NUL| DLE| Spc|  0 |  @ |  P |  ` |  p |
| 1 | SOH| DC1|  ! |  1 |  A |  Q |  a |  q |
| 2 | STX| DC2|  " |  2 |  B |  R |  b |  r |
| 3 | ETX| DC3|  # |  3 |  C |  S |  c |  s |
| 4 | EOT| DC4|  $ |  4 |  D |  T |  d |  t |
| 5 | ENQ| NAK|  % |  5 |  E |  U |  e |  u |
| 6 | ACK| SYN|  & |  6 |  F |  V |  f |  v |
| 7 | BEL| ETB|  ' |  7 |  G |  W |  g |  w |
| 8 | BS | CAN|  ( |  8 |  H |  X |  h |  x |
| 9 | HT | EM |  ) |  9 |  I |  Y |  i |  y |
| A | LF | SUB|  * |  : |  J |  Z |  j |  z |
| B | VT | ESC|  + |  ; |  K |  [ |  k |  { |
| C | FF | FS |  , |  < |  L |  \ |  l |  | |
| D | CR | GS |  - |  = |  M |  ] |  m |  } |
| E | SO | RS |  . |  > |  N |  ^ |  n |  ~ |
| F | SI | US |  / |  ? |  O |  _ |  o | DEL|
+---+----+----+----+----+----+----+----+----+

NUL (null)                      DLE (data link escape)
SOH (start of heading)          DC1 (device control 1)
STX (start of text)             DC2 (device control 2)
ETX (end of text)               DC3 (device control 3)
EOT (end of transmission)       DC4 (device control 4)
ENQ (enquiry)                   NAK (negative acknowledge)
ACK (acknowledge)               SYN (synchronous idle)
BEL (bell)                      ETB (end of trans. block)
BS  (backspace)                 CAN (cancel)
TAB (horizontal tab)            EM  (end of medium)
LF  (line feed, NL new line)    SUB (substitute, EOF end of file)
VT  (vertical tab)              ESC (escape)
FF  (form feed, NP new page)    FS  (file separator)
CR  (carriage return)           GS  (group separator)
SO  (shift out)                 RS  (record separator)
SI  (shift in)                  US  (unit separator)



Creative Commons License

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