* 아래는 낮은 버전(1.8.6 이하)의 Ruby를 사용할 때 적용된다.

영문 문자열을 거꾸로 하기는 잘되지만,
한글 문자열을 거꾸로 하기는 잘 안된다.
그 이유는 Ruby가 모든 문자열을 바이트로 처리하기 때문이다.

예제 1.  한글 문자열을 잘 처리하지 못하는 예제

a = "Hello, world!"
b = "안녕하세요?"
puts "%s --> %s" % [a, a.reverse()]
puts "%s --> %s" % [b, b.reverse()]
####################
# Expected:
#   Hello, world! --> !dlrow ,olleH
#   안녕하세요? --> ?요세하녕안
# Result:
#   Hello, world! --> !dlrow ,olleH
#   안녕하세요? --> ?岳세逑楹횡
####################



Ruby 언어(버전 1.8.6 이하)는 유니코드를 거의 지원하지 않는다.
그러나 iconv 를 이용하여 문자열 인코딩 변환하기는 가능하다.
다음은 EUC-KR 문자열을 UTF8 문자열로 변환하는 예이다.
'UTF8' 대신 'UTF8//IGNORE'로 한 것은 확장완성형 한글(예: 똠방, 아햏핼)을
변환하는 경우 발생하는 에러 Iconv::IllegalSequence를 예방하기 위함이다.

        require iconv

        #  양식 conv =  Iconv.new(encTarget, encSource)
        # EUC-KR 인코딩을 UTF-8 인코딩으로 변환하기
        conv =  Iconv.new('UTF-8//IGNORE', 'EUC-KR')

        s = "한글"
        t = conv.iconv(s)   # t는 변환된 문자열


예제 2. EUC-KR 한글 문자열을 잘 처리하지만, 확장완성형 한글을 잘 처리하지 못하는 예제

require 'iconv'

conv = Iconv.new('UTF-8//IGNORE', 'EUC-KR')
conv2 = Iconv.new('EUC-KR', 'UTF-8//IGNORE')

s = "안녕하세요? 아햏햏"
arrS = conv.iconv(s).unpack('U*')
arrT = arrS.reverse
t = conv2.iconv(arrT.pack("U*"))   # "U" -> 1글자만 변환, "U*"  -> 모두 변환
puts "%s --> %s" % [s, t]
####################
# Expected:
#   안녕하세요? 아햏햏 --> 햏햏아 ?요세하녕안
# Result:
#   안녕하세요? 아햏햏 --> dd아 ?요세하녕안
####################




예제 3 (최종). 확장완성형 한글도 잘 처리하는 예제 (문자셋 'EUC-KR' 대신 'CP949' 사용)

require 'iconv'

conv = Iconv.new('UTF-8//IGNORE', 'CP949')
conv2 = Iconv.new('CP949', 'UTF-8//IGNORE')

s = "안녕하세요? 아햏햏"
arrS = conv.iconv(s).unpack('U*')
arrT = arrS.reverse
t = conv2.iconv(arrT.pack("U*"))   # "U" -> 1글자만 변환, "U*"  -> 모두 변환
puts "%s --> %s" % [s, t]
####################
# Expected:
#   안녕하세요? 아햏햏 --> 햏햏아 ?요세하녕안
# Result:
#   안녕하세요? 아햏햏 --> 햏햏아 ?요세하녕안
####################





Creative Commons License

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

 

Posted by Scripter
,

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


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




실행> ruby makeDivisionTable.rb 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
,

Ruby도 한 개의 소스 파일에 여러 개의 클래스가 존재해도 된다. 또 클래스명과 다른 파일명으로 저장해도 된다. Ruby 언어도 Java 언어 처럼 대소문자 구별을 엄격히 하므로 클래스를 선언하고 그 클래스로 객체 생성할 때 대소문자 구별을 꼭 지켜야 한다.

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


# Filename: testSubclassing.rb
class Parent
    @name
    def initialize(name)
        @name =  name
    end

    def sayName()
        print("I am Parent, " + @name + "\n")
    end
end

class Child < Parent
    @name
    def initialize(name)
        @name =  name
    end

    def sayName()
        print("I am a child, named as " + @name + "\n")
    end
end

obj = Child.new("Dooly")
obj.sayName()




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



JRuby로 실행해도 된다.

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





Creative Commons License

Posted by Scripter
,

콘솔에 삼각형

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


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

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

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


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

def printTriange()
    print "        *        " + "\n"
    print "       * *       " + "\n"
    print "      *   *      " + "\n"
    print "     *     *     " + "\n"
    print "    *       *    " + "\n"
    print "   *         *   " + "\n"
    print "  *           *  " + "\n"
    print " *             * " + "\n"
    print "*****************" + "\n"
end

printTriange()




위의 소스 코드는 아무 알고리즘도 없는 너무 단순한 코드이다. 이런 코드를 작성했다간 출력 모양이나 크기를 변경해야 하는 상황을 맞이하면 워드프로세서로 문서 만드는 것 이상으로 많은 수작업을 하거나 아니면 포기하는 지경에 이를 수도 있다. 그래서 다음처럼 좀 더 나은 소스 코드를 작성하였다. Ruby 언어의 출력 함수 print() 는 Python 언어의 print 와는 달리 새 줄 문자(newline, '\n')를 추가하지 않는다. Ruby 언어의 출력 함수 print() 는 Groovy 언어의 print() 함수, 그리고 Java 언어의 System.out.print() 함수와 유사하다. 그 대신 println() 함수를 어래의 소스 코드에서 구현하여 Groovy 언어의 println() 처럼 사용할 수 있게 하였다.




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

def println(s=nil)
    if s == nil
        print "\n"
    else
        print "%s\n" % s
    end
end

def printTriange()
    for i in 0...8
        for k in 0...8-i
            print " "
        end
        for k in 0...2*i+1
            if k == 0 or k == 2*i
                print "*"
     else
                print " "
            end
        end
        for k in 0...8-i
            print " "
        end
        println()
    end

    for i in 0...17
        print "*"
    end
    println()
end

printTriange()



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

        line2 = [" "]*17

이다. (string*number 또는 list*number 의 구문은 Groovy, Python 언어에서도 지원된다.)



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

def println(s=nil)
    if s == nil
        print "\n"
    else
        print "%s\n" % s
    end
end

def printTriange()
    line2 = [" "]*17
    for i in 0...8
        line2 = [" "]*17
        line2[8-i] =  '*'
        line2[8+i] =  '*'
        line2.each { |x| print x }
        println()
    end

    line2 = [" "]*17
    for i in 0...17
        line2[i] =  '*'
    end
    line2.each { |x| print x }
    println()
end

printTriange()





별(*) 문자를 이용하여 삼각형을 출력하는 일은 빈칸 문자와 별 문자를 적당한 좌표(위치)에 촐력하는 일이다. 출력될 한 줄의 스트링을 완성한 후 하나의 print 구문으로 출력하는 기법으로 소스 코드를 작성해 보았다. 소스 코드 중에

        whites = " "*17
        stars = "*"*17

은 지정된 개수(여기서는 17) 만큼 string을 중복 연결하는 구문이다.




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

def println(s=nil)
    if s == nil
        print "\n"
    else
        print "%s\n" % s
    end
end

def printTriange()
    whites = " "*17
    stars  = "*"*17
    line2 = "%s%s%s" % [whites[0...8], "*", whites[0...7]]
    println line2
    for i in 1...8
        line2 = "%s%s%s%s%s" % [whites[0...8-i], "*", whites[8-i...7+i], "*", whites[7+i..-1]]
        println line2
    end
    println stars
end

printTriange()





string은 immutable이라 그 내용을 변경할 수 없지만, 리스트는 그 요소(item)를 아무 때 나 변경할 수 있다. 한줄에 출력될 각 문자를 리스트 타입의 변수 line2에 저장한 후, 클로저를 이용한 구문

        line2.each { |x| print x }

으로 그 리스트의 모든 요소item)가 모두 이어서 출력되게 하였다.



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

def println(s=nil)
    if s == nil
        print "\n"
    else
        print "%s\n" % s
    end
end

def printTriange()
    whites = " "*17
    stars  = "*"*17
    start = 8
    line2 = [" "]*17
    line2[start] = "*"
    line2.each { |x| print x }
    println
    for i in 1...8
        line2 = [" "]*17
        line2[start - i] = stars[start - i..start - i]
        line2[start + i] = stars[start + i..start + i]
        line2.each { |x| print x }
        println
    end
    println stars
end

printTriange()





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



삼각형 출력 예제 6
#  Filename: printTriangle6.rb
#            Print a triangle on console.
#
#  Execute: ruby printTriangle6.rb
#
#      Date:  2008/04/03
#    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
def println(s=nil)
    if s == nil
        print "\n"
    else
        print "%s\n" % s
    end
end

def printTriange()
    whites = " "*8
    stars  = "*"*8
    start = 8
    line = whites + '*' + whites
    println line
    for i in 1...8
        line = whites[0...-i] + '*' + whites[-i...-1]
        println line + ' ' + line.reverse
    end
    line = stars + '*' + stars
    println line
end

printTriange()





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



삼각형 출력 예제 7
#  Filename: printTriangle5.rb
#            Print a triangle on console.
#
#  Execute: ruby printTriangle5.rb
#
#      Date:  2008/04/03
#    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]

def println(s=nil)
    if s == nil
        print "\n"
    else
        print "%s\n" % s
    end
end

def printTriange()
    start = 0x100
    total = 0
    val = start
    data = ""
    for k in 0...8
        val = (start << k) | (start >> k)
        data = val.to_s 2
        for i in 0...17-data.length
            print " "
        end
        for i in 0...data.length
     if data[i..i] == "0"
                print " "
     else
                print "*"
            end
        end
        println
        total += val
    end

    val = (start << 8) | (start >> 8)
    total += val
    data = total.to_s 2
    for i in 0...17-data.length
        print " "
    end
    for i in 0...data.length
        if data[i..i] == '0'
            print " "
        else
            print "*"
        end
    end
    println
end

printTriange()





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

            total |= val

이 하는 일이 무엇인지 이해할 수 있으면 좋다. 또한 Ruby 언어는 간편 표기법(syntex sugar)를 지원허므로

        anotherString = string.gsub(원본, 타겟)

은 괄호를 생략하여

        anotherString = string.gsub 원본, 타겟

로 해도 되고,

        printlln()

도 괄호를 생략하여

        printlln

로 해도 된다.






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

def println(s=nil)
    if s == nil
        print "\n"
    else
        print "%s\n" % s
    end
end

def printTriange()
    zeros  = "00000000"
    start = 0x100
    total = 0
    val = start
    line = ""
    data = ""
    for k in 0...8
        val = (start << k) | (start >> k)
        data = val.to_s 2
        line = zeros[0...17-data.length] + data
        line = line.gsub "0", " "
        line = line.gsub "1", "*"
        println line
        total |= val
    end

    val = (start << 8) | (start >> 8)
    total |= val
    line = total.to_s 2
    line = line.gsub "0", " "
    line = line.gsub "1", "*"
    println line
end

printTriange()





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

        println data.join

도 Python 코드와 비교하여 음미해볼 만한 부분이다.



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

def println(s=nil)
    if s == nil
        print "\n"
    else
        print "%s\n" % s
    end
end

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

    data[start] = "*"
    last[start] = "*"
    println data.join
    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] = " "
    end

    last[start - 8] = "*"
    last[start + 8] = "*"
    println last.join
end

printTriange()





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

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

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




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

def println(s=nil)
    if s == nil
        print "\n"
    else
        print "%s\n" % s
    end
end

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

printTriange()





Creative Commons License

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

Posted by Scripter
,

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

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

        convertAtoI(string, radix)
        convertItoA(number, radix)

의 구현도 포함되어 있다.



  1. #  Filename: makeAsciiTable.rb
  2. #            Make a table of ascii codes.
  3. #
  4. #  Execute: ruby makeAsciiTable.rb
  5. #
  6. #      Date:  2008/03/28
  7. #    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  8. BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  9. def println(s)
  10.     print("%s\n" % s)
  11. end
  12. def printUsage()
  13.     println("Usage: ruby makeAsciiTable.rb")
  14.     println("Make a table of ascii codes.")
  15. end
  16. def convertItoA(num, radix)
  17.     isNegative = false
  18.     if num < 0
  19.         isNegative = true
  20.         num = -num
  21.     end
  22.     arr = ""
  23.     q = num
  24.     r = 0
  25.     while q >= radix
  26.         r = q % radix
  27.         q = q / radix
  28.         arr = arr + BASE36[r..r]
  29.     end
  30.     arr = arr + BASE36[q..q]
  31.     if isNegative
  32.         arr = arr + "-"
  33.     end
  34.     n = arr.length
  35.     ret = ""
  36.     for i in 0...n
  37.         ret = ret + arr[(n - i - 1)..(n - i - 1)]
  38.     end
  39.     return ret
  40. end
  41. def convertAtoI(srcStr, radix)
  42.     isNegative = false
  43.     ret = 0
  44.     len = srcStr.length
  45.     val = 0
  46.     c = srcStr[0..0]
  47.     if c == '-'
  48.         isNegative = true
  49.     elsif c >= '0' and c <= '9'
  50.         ret = c[0] - '0'[0]
  51.     elsif c >= 'A' and c <= 'Z'
  52.         ret = (c[0] - 'A'[0]) + 10
  53.     elsif c >= 'a' and c <= 'z'
  54.         ret = (c[0] - 'a'[0]) + 10
  55.     end
  56.     if ret >= radix
  57.         println("        Invalid character!")
  58.         return ret
  59.     end
  60.     for i in 1...len
            c = srcStr[i..i]
  61.         ret = ret * radix
  62.         if c >= '0' and c <= '9'
  63.             val = c[0] - '0'[0]
  64.         elsif c >= 'A' and c <= 'Z'
  65.             val = (c[0] - 'A'[0]) + 10
  66.         elsif c >= 'a' and c <= 'z'
  67.             val = (c[0] - 'a'[0]) + 10
  68.         end
  69.         if val >= radix
  70.             println("        Invalid character!")
  71.             return ret
  72.         end
  73.         ret = ret + val
  74.     end
  75.     return ret
  76. end
  77. def makeTable()
  78.   asc = [
  79.     "NUL", "SOH", "STX", "ETX", "EOT",
  80.     "ENQ", "ACK", "BEL", "BS", "HT",
  81.     "LF", "VT", "FF", "CR", "SO",
  82.     "SI", "DLE", "DC1", "DC2", "DC3",
  83.     "DC4", "NAK", "SYN", "ETB", "CAN",
  84.     "EM", "SUB", "ESC", "FS", "GS",
  85.     "RS", "US", "Spc"
  86.   ]
  87.   control  = [
  88.     "NUL (null)",
  89.     "SOH (start of heading)",
  90.     "STX (start of text)",
  91.     "ETX (end of text)",
  92.     "EOT (end of transmission)",
  93.     "ENQ (enquiry)",
  94.     "ACK (acknowledge)",
  95.     "BEL (bell)",
  96.     "BS  (backspace)",
  97.     "TAB (horizontal tab)",
  98.     "LF  (line feed, NL new line)",
  99.     "VT  (vertical tab)",
  100.     "FF  (form feed, NP new page)",
  101.     "CR  (carriage return)",
  102.     "SO  (shift out)",
  103.     "SI  (shift in)",
  104.     "DLE (data link escape)",
  105.     "DC1 (device control 1)",
  106.     "DC2 (device control 2)",
  107.     "DC3 (device control 3)",
  108.     "DC4 (device control 4)",
  109.     "NAK (negative acknowledge)",
  110.     "SYN (synchronous idle)",
  111.     "ETB (end of trans. block)",
  112.     "CAN (cancel)",
  113.     "EM  (end of medium)",
  114.     "SUB (substitute, EOF end of file)",
  115.     "ESC (escape)",
  116.     "FS  (file separator)",
  117.     "GS  (group separator)",
  118.     "RS  (record separator)",
  119.     "US  (unit separator)",
  120.   ]
  121.     sbuf = ""
  122.     abuf = ""
  123.     tbuf = ""
  124.     sbuf = "    "
  125.     for i in 0...8
  126.         sbuf += "+----"
  127.     end
  128.     sbuf += "+"
  129.     println(sbuf)
  130.     sbuf = "    "
  131.     sbuf += "| 0- "
  132.     sbuf += "| 1- "
  133.     sbuf += "| 2- "
  134.     sbuf += "| 3- "
  135.     sbuf += "| 4- "
  136.     sbuf += "| 5- "
  137.     sbuf += "| 6- "
  138.     sbuf += "| 7- "
  139.     sbuf += "|"
  140.     println(sbuf)
  141.     sbuf = "+---"
  142.     for i in 0...8
  143.         sbuf += "+----"
  144.     end
  145.     sbuf += "+"
  146.     println(sbuf)
  147.     for i in 0...16
  148.         tbuf = ""
  149.         sbuf = convertItoA(i, 16)
  150.         tbuf = tbuf + "| " + sbuf + " "
  151.         for j in 0...8
  152.             if j*16 + i <= 32
  153.                 abuf = "| %-3s" % asc[j*16 + i]
  154.             elsif j*16 + i == 127
  155.                 abuf = "| %-3s" % "DEL"
  156.             else
  157.                 c = j*16 + i
  158.                 abuf = "| %2c " % c
  159.             end
  160.             tbuf = tbuf + abuf
  161.         end
  162.         tbuf = tbuf + "|"
  163.         println(tbuf)
  164.     end
  165.     sbuf = "+---"
  166.     for i in 0...8
  167.         sbuf += "+----"
  168.     end
  169.     sbuf += "+"
  170.     println(sbuf)
  171.     println("")
  172.     for i in 0...16
  173.         tbuf = "%-30s  %-34s" % [control[i], control[i+16]]
  174.         println(tbuf)
  175.     end
  176. end
  177. if ARGV.length > 0 and "-h" == ARGV[0]
  178.     printUsage()
  179.     exit(1)
  180. end
  181. makeTable()




실행> ruby makeAsciiTable.rb

    +----+----+----+----+----+----+----+----+
    | 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
,

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

        convertAtoI(string, radix)
        convertItoA(number, radix)

를 Ruby 코드로 자체 작성하여 사용하였다.
(아래의 소스는 JRuby로 실행시켜도 된다.)




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



실행> ruby makeRadixTable.rb

+-------+-------+-------+-------+
|  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)하는 Ruby 소스 코드이다.
메뉴는 주메뉴 Command: (S)et radix, (A)bout, (Q)uit or E(x)it
와 부메뉴 SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
로 구성되어 있으며, 진법 변환의 핵심은 Ruby의 string 클래스의 빌트인(build-in) 함수 string.to_i(radix)와 소스 코드에 자체 작성된 함수 itoa(number, radix)의 사용이다.

         val = s.to_i(srcRdx)
         ret = itoa(val, destRdx)

지원되는 진법은 2진법에서 36진법 까지이다.
(JRuby로는 gets 때문에 실행되지 않는다.)



  1. #  Filename: convertRadix.rb
  2. #            Convert radix in a interactive mode.
  3. #
  4. #  Execute: ruby convertRadix.rb
  5. #
  6. #      Date:  2008/03/26
  7. #    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  8. def println(s=nil)
  9.     if s != nil
  10.         print("%s\n" % s)
  11.     else
  12.         print("\n")
  13.     end
  14. end
  15. def printUsage()
  16.     println("Usage: ruby convertRadix.rb")
  17.     println("Convert radix in a interactive mode, where the maximum radix is 36.")
  18. end
  19. def printAbout()
  20.     println("    About: Convert radix in a interactive mode.")
  21. end
  22. def printMainMenu()
  23.     println("  Command: (S)et radix, (A)bout, (Q)uit or E(x)it")
  24. end
  25. def printMainPrompt()
  26.     print("  Prompt> ")
  27. end
  28. def printSubMenu(srcRadix, destRadix)
  29.     println("    Convert Radix_" + srcRadix.to_s + " to Radix_" + destRadix.to_s)
  30.     println("    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit")
  31. end
  32. def printSubPrompt()
  33.     print("    Input Value>> ")
  34. end
  35. BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  36. def itoa(num, radix=10)
  37.    isNegative = false
  38.    if num < 0
  39.       isNegative = true
  40.       num = -num
  41.    end
  42.    arr = []
  43.    q, r = num, 0
  44.    while q >= radix
  45.       val = q.divmod(radix)
  46.       q, r = val[0], val[1]
  47.       arr.push(BASE36.slice(r..r))
  48.    end
  49.    arr.push(BASE36.slice(q..q))
  50.    if isNegative
  51.       arr.push("-")
  52.    end
  53.    b = arr.reverse()
  54.    return b.join
  55. end
  56. def convertRadix(s, srcRdx, destRdx)
  57.     ret = ""
  58.     begin
  59.         val = s.to_i(srcRdx)
  60.         ret = itoa(val, destRdx)
  61. return ret.upcase
  62.     rescue
  63.         println("    Error: Cannot convert radix " + str(srcRdx))
  64.         ret = "????"
  65.     end
  66. end
  67. def doConvert(srcRadix, destRadix)
  68.     line = ""
  69.     cmd = ""
  70.     srcStr = ""
  71.     destStr = ""
  72.     println("")
  73.     printSubMenu(srcRadix, destRadix)
  74.     begin
  75.         while true
  76.             printSubPrompt()
  77.             cmd = gets
  78.             while cmd.length < 2
  79.                 cmd = gets
  80.             end
  81.             cmd = cmd[0...cmd.length-1]
  82.             if "main()" == cmd
  83.                 return
  84.             elsif "exit()" == cmd or "quit()" == cmd
  85.                 exit(0)
  86.             end
  87.             begin
  88.                 cmd.to_i(srcRadix)
  89.                 srcStr = cmd
  90.                 destStr = convertRadix(srcStr, srcRadix, destRadix)
  91.                 println("        ( " + srcStr + " )_" + srcRadix.to_s +  "   --->   ( " + destStr + " )_" + destRadix.to_s)
  92.                 println("")
  93.             rescue
  94.                  nil
  95.             end
  96.         end
  97.     rescue
  98.         puts "    An error occurred: #{$!}"
  99.         retry
  100.     end
  101. end
  102. def doStart()
  103.     line = ""
  104.     cmd = ""
  105.     srcRadix = 10
  106.     destRadix = 10
  107.     srcStr = ""
  108.     destStr = ""
  109.     onlyOnce = true
  110.     begin
  111.         while true
  112.             println()
  113.             if onlyOnce
  114.                 println("  The supported maximum radix is 36.")
  115.                 onlyOnce = false
  116.             end
  117.             printMainMenu()
  118.             printMainPrompt()
  119.             cmd = gets
  120.             while cmd.length < 1
  121.                 cmd = gets
  122.             end
  123.             cmd = cmd[0...cmd.length-1]
  124.             if "qQxX".include?(cmd) and cmd.length == 1
  125.                 exit(0)
  126.             elsif "aA".include?(cmd) and cmd.length == 1
  127.                 printAbout()
  128.             elsif "sS".include?(cmd) and cmd.length == 1
  129.                 print("  Input the source and target radices (say, 16 2): ")
  130.                 line = gets
  131.                 line = line[0...line.length-1]
  132.                 st = line.split(" ")
  133.                 while st.length < 2
  134.                     print("  Input the source and target radices (say, 16 2): ")
  135.                     line = gets
  136.                     line = line[0...line.length-1]
  137.                     st = line.split(" ")
  138.                 end
  139.                 srcRadix = st[0].to_i
  140.                 destRadix = st[1].to_i
  141.                 doConvert(srcRadix, destRadix)
  142.             end
  143.         end
  144.     rescue
  145.         puts "  An error occurred: #{$!}"
  146.         retry
  147.     end
  148. end
  149. # Begin here
  150. if ARGV.length > 0 and "-h" == ARGV[0]
  151.     printUsage()
  152.     exit(1)
  153. end
  154. doStart()




실행> ruby convertRadix.rb

  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): 8 2

    Convert Radix_8 to Radix_2
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 123
        ( 123 )_8   --->   ( 1010011 )_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>> 1010011
        ( 1010011 )_2   --->   ( 123 )_8

    Input Value>> quit()




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

Posted by Scripter
,

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

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


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



실행> ruby testGoldenRatio.rb
The bigger root is 1.61803398874989,
and the less root is -0.618033988749895.


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




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

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


  1. =begin
  2.    Filename: testCTime.rb
  3.    Execute: ruby testCTime.rb
  4. =end
  5. def println(s)
  6.     print("#{s}\n")
  7. end
  8. weekNames = [ "일", "월", "화", "수", "목", "금", "토" ]
  9. cNow = Time.now
  10. # 1970년 1월 1일 0시 0분 0초부터 시작하여 현재까지의 초
  11. println("UTC: %d초" % cNow.to_i)
  12. # 현재 시각 표시: 200x년 x월 xx일 (x요일) xx시 xx분 xx초
  13. println("%d년 %d월 %d일 (%s요일) %d시 %d분 %d초" % [cNow.year, cNow.mon, cNow.day, weekNames[cNow.wday], cNow.hour, cNow.min, cNow.sec] )
  14. # 1월 1일은 1, 1월 2일은 2
  15. # Time.now.isdat == false 이면, 서머타임 없음
  16. println("올해 몇 번째 날: %d, 서머타임 적용 여부: %s" % [cNow.yday, cNow.isdst ? "함" : "안함"])



실행> ruby testCTime.rb
UTC: 1206325100초
2008년 3월 24일 (월요일) 11시 18분 20초
올해 몇 번째 날: 84, 서머타임 적용 여부: 안함


실행> jruby testCTime.rb
UTC: 1206325102초
2008년 3월 24일 (월요일) 11시 18분 22초
올해 몇 번째 날: 84, 서머타임 적용 여부: 안함




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

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

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

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

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


아래의 소스파일은 Python용 소스파일 testSyntheticDivision.py 를 Ruby용으로 수정한 것이다.

ruby 대신 jruby 로도 수정 없이 그대로 실행된다.


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




실행> ruby testSyntheticDivision.rb 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
,