[파일명:  TestStringFindInList.fs]------------------------------------------------
#light

let find arr s = List.findIndex (fun x -> x = s) arr

let printList data =
    let rec loop l =
        match l with
        | x::[] -> printf "%O" x
        | x::xs -> printf "%O, " x; loop xs
        | [] -> printf ""
    printf "["
    loop data
    printf "]"

// Begin here
let cmdArgs = System.Environment.GetCommandLineArgs()

let words = ["하나"; "둘"; "셋"; "넷"; "다섯"; "여섯"]

printf "list: "
printList words
printfn ""
let where1 = find words "셋"
if where1 >= 0 then
    printf "발견!  "
    printf "Next word of 셋 in list: %O" (words.[where1+1])
printfn ""

printfn "Sorting..."
let otherwords = words |> List.sort |> List.sort

printf "list: "
printList otherwords
printfn ""
let where2 = find otherwords "셋"
if where2 >= 0 then
    printf "발견!  "
    printf "Next word of 셋 in list: %O" (otherwords.[where2+1])
printfn ""
------------------------------------------------


컴파일> fsc --codepage:949 TestStringFindInList.fs

실행> TestStringFindInList
list: [하나, 둘, 셋, 넷, 다섯, 여섯]
발견!  Next word of 셋 in list: 넷
Sorting...
list: [넷, 다섯, 둘, 셋, 여섯, 하나]
발견!  Next word of 셋 in list: 여섯


Posted by Scripter
,

printList 함수를 F#의 함수형 언어의 특징을 살려 (꼬리 재귀호출과 match 표현을 이용하여) 구현하였다.

[파일명:  TestSort.fs]------------------------------------------------
#light

let printList data =
    let rec loop l =
        match l with
        | x::[] -> printf "%O" x
        | x::xs -> printf "%O, " x; loop xs
        | [] -> printf ""
    printf "["
    loop data
    printf "]"

// Begin here
let cmdArgs = System.Environment.GetCommandLineArgs()
let b = cmdArgs.[1..] |> Array.toList |> List.sort
printList b
------------------------------------------------


컴파일> fsc TestSort.fs

실행> TestSort one two three four five
[five, four, one, three, two]

실행> TestSort 하나 둘 셋 넷 다섯
[넷, 다섯, 둘, 셋, 하나]

 

Posted by Scripter
,


초등학교 때 배우던 두 정수의 곱셈표를 만들어 주는 F# 소스이다.
이 소스는 Python 소스를 F# 소스로 변환한 것이라 F#의 명령형 언어 특징을 위주로 짜여져 있다.

(*
 * Filename: MakeMultTable.fs
 *
 *     Print a multiplication table.
 *
 *  Compile: fsc MakeMultTable.fs
 *  Execute: MakeMultTable 230 5100
 *
 *     Date: 2010/07/15
 *   Author:  PH Kim   [ pkim ((AT)) scripts.pe.kr ]
 *)

#light

exception RuntimeError of string
exception ValueError of string

let println s =
    printfn "%O" s

let print s =
    printf "%O" s

let printUsage dummy =
    println "Using: python makeMultTable.py [number1] [number2]"
    println "Print a multiplication table for the given two integers."

let printMultTable x y =
    let mutable nx = x
    if nx < 0 then
        nx <- -nx
    let mutable ny = y
    if ny < 0 then
        ny <- -ny
    let mutable ntail1 = 0
    let mutable ntail2 = 0
    while (nx % 10) = 0 do
        nx <- nx / 10
        ntail1 <- ntail1 + 1
    while ny % 10 = 0 do
        ny <- ny / 10
        ntail2 <- ntail2 + 1
    let z = nx * ny
    let strZ = sprintf "%d" z
    let strX = sprintf "%d" nx
    let strY = sprintf "%d" ny
    let n = strY.Length
    let zeros  = "0000000000000000000000000000000000000000"
    let whites = "                                        "
    let bars   = "----------------------------------------"
    let loffset = "       "
    let line4 = loffset + strZ
    let line1 = loffset + (whites.Substring(0, strZ.Length - strX.Length)) + strX
    let line2 = "   x ) " +  (whites.Substring(0, strZ.Length - strY.Length)) + strY
    let line3 = "     --" +  (bars.Substring(0, strZ.Length))
    println (line1 + (zeros.Substring(0, ntail1)))
    println (line2 + (zeros.Substring(0, ntail2)))
    println line3
    if strY.Length > 1 then
        for i in 0..(strY.Length - 1) do
            let y1 = int (strY.Substring(strY.Length - i - 1, 1))
            if not (y1 = 0) then
                let strT = sprintf "%d" (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)))

// Begin here
let cmdArgs = System.Environment.GetCommandLineArgs()
if (Array.length cmdArgs >= 3) then
    let x = int (cmdArgs.[1])
    let y = int (cmdArgs.[2])
    println ""
    printMultTable x y
else
    printUsage 0
    exit(1)





컴파일> fsc MakeMultTable.fs

실행> MakeMultTable 230 5100
결과>

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

 

 

 

Posted by Scripter
,
▒ F#  소스:  TestStringReverse.fs

#light

let a = "Hello, world!"
let b = "안녕하세요?"
let mutable arr = a.ToCharArray()
arr <- Array.rev arr
System.Console.WriteLine(new System.String(arr))
arr <- b.ToCharArray()
arr <- Array.rev arr
System.Console.WriteLine(new System.String(arr))

(*
Expected result:
!dlrow ,olleH
?요세하녕안
*)




주: 한글이 출력되어야 하므로 fsc 명령으로 컴파일시 옵션 --codepage:949 를 추가한다.




 

Posted by Scripter
,

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

아래의 소스는 Python 용 소스를 F# 용 소스로 거의 일대일 변환한 것이라서, F# 언어의 명령형 언어의 특징을 위주로 짜여져 있다.

  1. (*
  2.  *  Filename: MakeDivisionTable.fs
  3.  *
  4.  *  Purpose:  Make a division table in a handy written form.
  5.  *
  6.  *  Compile: fsc --codepage:949 MakeDivisionTable.fs
  7.  *
  8.  *  Execute: MakeDivisionTable 12345 32
  9.  *           MakeDivisionTable 500210 61
  10.  *           MakeDivisionTable 234 55
  11.  *
  12.  *     Date:  2010/07/15
  13.  *   Author:  PH Kim   [ pkim ((AT)) scripts.pe.kr ]
  14.  *)
  15. #light
  16. exception RuntimeError of string
  17. exception ValueError of string
  18. let BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  19. let SPACE = "                                                          "
  20. let ULINE = "__________________________________________________________"
  21. let HIPHEN = "----------------------------------------------------------"
  22. let println s =
  23.     printfn "%O" s
  24. let print s =
  25.     printf "%O" s
  26. let printUsage dummy =
  27.     // print("Using: MakeDivisionTable [numerator] [denominator]")
  28.     // print("Make a division table in a handy written form.")
  29.     println "사용법: MakeDivisionTable [피제수] [제수]"
  30.     println "손으로 작성한 형태의 나눗셈 표를 만들어준다."
  31. let simplify v width =
        let mutable t = sprintf "%d" v
  32.     if (t.EndsWith ".0") then
  33.         t <- t.Substring(0, t.Length - 2)
  34.     let slen = t.Length
  35.     if slen < width then
  36.         t <- SPACE.Substring(0, width - slen) + t
  37.     t
  38. let getSuffix v =
  39.     let mutable t = v % 10
  40.     let mutable suffix = "은"
  41.     if "2459".IndexOf(sprintf "%d"  t) >= 0 then
  42.         suffix <- "는"
  43.     suffix
  44. let makeTable numer denom quotient =
  45.     let strNumer = sprintf "%d" numer
  46.     let strDenom = sprintf "%d" denom
  47.     let strQuotient = sprintf "%d" quotient
  48.     let lenN = strNumer.Length
  49.     let lenD = strDenom.Length
  50.     let lenQ = strQuotient.Length
  51.     let offsetLeft = 3 + lenD + 3
  52.     let spaces = "                                                                                 "
  53.     let mutable uline  = ULINE.Substring(0, lenN + 2)
  54.     let mutable sline  = HIPHEN.Substring(0, lenN)
  55.     let bias = lenN - lenQ
  56.     println(spaces.Substring(0, offsetLeft) + spaces.Substring(0, bias) + sprintf "%d" quotient)
  57.     println(spaces.Substring(0, offsetLeft - 2) + uline)
  58.     print("   " + strDenom + " ) " + strNumer)
  59.     let mutable strTmpR = strNumer.Substring(0, bias + 1)
  60.     let mutable tmpR = int strTmpR
  61.     let mutable tmpSub = 0
  62.     let mutable oneDigit = ""
  63.     for i in 0..(lenQ - 1) do
  64.         if (strQuotient.Substring(i, 1)) = "0" then
  65.             if i + 1 < lenQ then
  66.                 oneDigit <- (strNumer.Substring(bias + i + 1, 1))
  67.                 print(oneDigit)
  68.                 strTmpR <- strTmpR + oneDigit
  69.                 tmpR <- int strTmpR
  70.         else
  71.             println ""
  72.             tmpSub <- (int (strQuotient.Substring(i, 1))) * denom
  73.             println(spaces.Substring(0, offsetLeft) + simplify tmpSub  (bias + i + 1))
  74.             println(spaces.Substring(0, offsetLeft) + sline)
  75.             tmpR <- tmpR - tmpSub
  76.             if tmpR = 0 && i + 1 < lenQ then
  77.                 print(spaces.Substring(0, offsetLeft) + spaces.Substring(0, bias + i + 1))
  78.             else 
  79.                 print(spaces.Substring(0, offsetLeft) + (simplify tmpR (bias + i + 1))) 
  80.             strTmpR <- sprintf "%d" tmpR
  81.             if i + 1 < lenQ then
  82.                 oneDigit <- (strNumer.Substring(bias + i + 1, 1))
  83.                 if  (oneDigit.Length) > 0 then
  84.                     print(oneDigit)
  85.                 strTmpR <- strTmpR + oneDigit
  86.             tmpR <- int strTmpR
  87.     println ""
  88.     tmpR
  89. // Begin here
  90. let cmdArgs = System.Environment.GetCommandLineArgs()
  91. if (Array.length cmdArgs < 3 || "-h" = cmdArgs.[1]) then
  92.     printUsage 0
  93.     exit(1)
  94. let mutable a = 0
  95. let mutable b = 1
  96. try
  97.     a <- int (cmdArgs.[1])
  98.     b <- int (cmdArgs.[2])
  99. with
  100.     | ValueError e -> printfn "피제수: %s, 제수: %s" (cmdArgs.[1]) (cmdArgs.[2]);
  101.                       printfn "숫자 입력에 오류가 있습니다.";
  102.                       exit(1)
  103. if a <= 0 then
  104.     printf "피제수: %d" a
  105.     printf "피제수는 양의 정수라야 합니다."
  106.     exit(1)
  107. elif b <= 0 then
  108.     printf "제수: %d" b
  109.     printf "제수는 양의 정수라야 합니다."
  110.     exit(1)
  111. let q = a / b
  112. let r = a % b
  113. printf "나눗셈 %d ÷ %d 의 결과: " a b
  114. printf "몫: %d, " q
  115. printfn "나머지: %d" r
  116. printfn ""
  117. let k = makeTable a b q
  118. if k = r then
  119.     printfn "\n나머지: %d" k
  120. if k = 0 then
  121.     printfn "%d = %d x %d" a b q
  122.     printfn "%d%s %d의 배수(mupltiple)이다." a (getSuffix a) b
  123.     printfn "%d%s %d의 약수(divisor)이다." b (getSuffix b) a
  124. else
  125.     printfn "%d = %d x %d + %d" a b q r
  126.     printfn "%d%s %d의 배수(mupltiple)가 아니다." a (getSuffix a) b



컴파일> fsc --codepage:949   MakeDivisionTable.fs

실행> MakeDivisionTable.py 500210 61
나눗셈 500210 ÷ 61 의 결과: 몫: 8200, 나머지: 10

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

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



 

Posted by Scripter
,

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

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

                atoi(string, radix)
                itoa(number, radix)

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

(아래의 소스는 Python 소스를 F# 소스로 일대일 변환 수정한 것이라서, F# 언어의 명령형 언어 특징을 위주로 작성되어 있다.)

  1. (*
  2.  *  Filename: MakeAsciiTable.fs
  3.  *            Make a table of ascii codes.
  4.  *
  5.  *  Compile: fsc MakeAsciiTable.fs
  6.  *  Execute: MakeAsciiTable
  7.  *
  8.  *      Date:  20010/07/15
  9.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  10.  *)
  11. #light
  12. exception RuntimeError of string
  13. exception ValueError of string
  14. let BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  15. let println s =
  16.     printfn "%O" s
  17. let print s =
  18.     printf "%O" s
  19. let printUsage dummy =
  20.     println "Usage: MakeAsciiTable"
  21.     println "Make a table of ascii codes."
  22. let itoa (num : int, radix : int) =
  23.    let mutable isNegative = false
  24.    let mutable numx = num
  25.    if num < 0 then
  26.       isNegative <- true
  27.       numx <- (-num)
  28.    let mutable arr = [  ]
  29.    let mutable q = numx
  30.    let mutable r = 0
  31.    while (q >= radix) do
  32.        r <- int (q % radix)
  33.        q <- int (q / radix)
  34.        arr <- List.append arr [ sprintf "%O" (BASE36.[r]) ]
  35.    arr <- List.append arr [ sprintf "%O" (BASE36.[q]) ]
  36.    if isNegative then
  37.       arr <- List.append arr [ "-" ]
  38.    arr <- List.rev arr
  39.    System.String.Join("", List.toArray arr)
  40. let atoi (s : string, radix : int) : int =
  41.     let mutable ret = 0
  42.     let mutable isNegative = false
  43.     let len = s.Length
  44.     let mutable valx = 0
  45.     let mutable c = s.[0]
  46.     if c = '-' then
  47.         isNegative <- true
  48.     elif (c >= '0' && c <= '9') then
  49.         ret <- (int c) - (int '0')
  50.     elif (c >= 'A' && c <= 'Z') then
  51.         ret <- int c - int 'A' + 10
  52.     elif (c >= 'a' && c <= 'z') then
  53.         ret <- int c - int 'a' + 10
  54.     if (ret >= radix) then
  55.         printfn "    Error: Can not read \"%s\" (as radix %d): %O is an invalid character!" s radix ret
  56.     for i = 1 to len - 1 do
  57.         c <- s.[i]
  58.         ret <- ret*radix
  59.         if (c >= '0' && c <= '9') then
  60.             valx <- int c - int '0'
  61.         elif (c >= 'A' && c <= 'Z') then
  62.             valx <- int c - int 'A' + 10
  63.         elif (c >= 'a' && c <= 'z') then
  64.             valx <- int c - int 'a' + 10
  65.         if (valx >= radix) then
  66.             printfn "    Error: Can not read \"%s\" (as radix %d): %O is an invalid character!" s radix c

  67.         ret <- ret + valx
  68.     if (isNegative) then
  69.         ret <- (-ret )
  70.     ret
  71. let asc = [
  72.     "NUL"; "SOH"; "STX"; "ETX"; "EOT";
  73.     "ENQ"; "ACK"; "BEL"; "BS"; "HT";
  74.     "LF"; "VT"; "FF"; "CR"; "SO";
  75.     "SI"; "DLE"; "DC1"; "DC2"; "DC3";
  76.     "DC4"; "NAK"; "SYN"; "ETB"; "CAN";
  77.     "EM"; "SUB"; "ESC"; "FS"; "GS";
  78.     "RS"; "US"; "Spc"
  79. ]
  80. let control = [
  81.     "NUL (null)";
  82.     "SOH (start of heading)";
  83.     "STX (start of text)";
  84.     "ETX (end of text)";
  85.     "EOT (end of transmission)";
  86.     "ENQ (enquiry)";
  87.     "ACK (acknowledge)";
  88.     "BEL (bell)";
  89.     "BS  (backspace)";
  90.     "TAB (horizontal tab)";
  91.     "LF  (line feed, NL new line)";
  92.     "VT  (vertical tab)";
  93.     "FF  (form feed, NP new page)";
  94.     "CR  (carriage return)";
  95.     "SO  (shift out)";
  96.     "SI  (shift in)";
  97.     "DLE (data link escape)";
  98.     "DC1 (device control 1)";
  99.     "DC2 (device control 2)";
  100.     "DC3 (device control 3)";
  101.     "DC4 (device control 4)";
  102.     "NAK (negative acknowledge)";
  103.     "SYN (synchronous idle)";
  104.     "ETB (end of trans. block)";
  105.     "CAN (cancel)";
  106.     "EM  (end of medium)";
  107.     "SUB (substitute, EOF end of file)";
  108.     "ESC (escape)";
  109.     "FS  (file separator)";
  110.     "GS  (group separator)";
  111.     "RS  (record separator)";
  112.     "US  (unit separator)";
  113. ]
  114. let makeTable dummy =
  115.     let mutable sbuf = ""
  116.     let mutable abuf = ""
  117.     let mutable tbuf = ""
  118.     let mutable c = 'a'
  119.     sbuf <- "    "
  120.     for i in 0..(8-1) do
  121.         sbuf <- sbuf +  "+----"
  122.     sbuf <- sbuf +  "+"
  123.     println(sbuf)
  124.     sbuf <- "    "
  125.     sbuf <- sbuf +  "| 0- "
  126.     sbuf <- sbuf +  "| 1- "
  127.     sbuf <- sbuf +  "| 2- "
  128.     sbuf <- sbuf +  "| 3- "
  129.     sbuf <- sbuf +  "| 4- "
  130.     sbuf <- sbuf +  "| 5- "
  131.     sbuf <- sbuf +  "| 6- "
  132.     sbuf <- sbuf +  "| 7- "
  133.     sbuf <- sbuf +  "|"
  134.     println(sbuf)
  135.     sbuf <- "+---"
  136.     for i in 0..(8-1) do
  137.         sbuf <- sbuf +  "+----"
  138.     sbuf <- sbuf +  "+"
  139.     println(sbuf)
  140.     for i in 0..(16-1) do
  141.         tbuf <- ""
  142.         sbuf <- itoa(i, 16)
  143.         tbuf <- tbuf +  "| " + sbuf + " "
  144.         for j in 0..(8-1) do
  145.             if j*16 + i <= 32 then
  146.                 abuf <- sprintf "| %-3s" (asc.[j*16 + i])
  147.             elif j*16 + i = 127 then
  148.                 abuf <- sprintf  "| %-3s" "DEL"
  149.             else
  150.                 c <- char (j*16 + i)
  151.                 abuf <- sprintf "|  %1c " c
  152.             tbuf <- tbuf + abuf
  153.         tbuf <- tbuf + "|"
  154.         println(tbuf)
  155.     sbuf <- "+---"
  156.     for i in 0..(8-1) do
  157.         sbuf <- sbuf + "+----"
  158.     sbuf <- sbuf + "+"
  159.     println(sbuf)
  160.     println("")
  161.     for i in 0..(16-1) do
  162.         tbuf <- sprintf "%-30s  %-34s" (control.[i]) (control.[i+16])
  163.         println(tbuf)
  164. // Begin here
  165. let cmdArgs = System.Environment.GetCommandLineArgs()
  166. if (Array.length cmdArgs > 1 && "-h" = cmdArgs.[1]) then
  167.     printUsage 0
  168.     exit(1)
  169. makeTable 0




컴파일> fsc MakeAsciiTable.fs

실행> MakeAsciiTable

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




 

Posted by Scripter
,

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

        atoi(string, radix)
        itoa(number, radix)

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

(아래의 소스는 Python 소스를 F# 소스로 일대일 변환 수정한 것이라서, F# 언어의 명령형 언어 특징을 위주로 작성되어 있다.)

  1. (*
  2.  *  Filename: MakeRadixTable.fs
  3.  *            Show the radix table with 10-, 2-, 8-, 16-radices.
  4.  *
  5.  *  Compile: fsc MakeRadixTable.fs
  6.  *  Execute: MakeRadixTable
  7.  *
  8.  *      Date:  2010/07/15
  9.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  10.  *)
  11. #light
  12. exception RuntimeError of string
  13. exception ValueError of string
  14. let BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  15. let println s =
  16.     printfn "%O" s
  17. let print s =
  18.     printf "%O" s
  19. let printUsage dummy =
  20.     println "Usage: MakeRadixTable"
  21.     println "Show the radix table with 10-, 2-, 8-, 16-radices."
  22. let itoa (num : int, radix : int) =
  23.    let mutable isNegative = false
  24.    let mutable numx = num
  25.    if num < 0 then
  26.       isNegative <- true
  27.       numx <- (-num)
  28.    let mutable arr = [  ]
  29.    let mutable q = numx
  30.    let mutable r = 0
  31.    while (q >= radix) do
  32.        r <- int (q % radix)
  33.        q <- int (q / radix)
  34.        arr <- List.append arr [ sprintf "%O" (BASE36.[r]) ]
  35.    arr <- List.append arr [ sprintf "%O" (BASE36.[q]) ]
  36.    if isNegative then
  37.       arr <- List.append arr [ "-" ]
  38.    arr <- List.rev arr
  39.    System.String.Join("", List.toArray arr)
  40. let atoi (s : string, radix : int) : int =
  41.     let mutable ret = 0
  42.     let mutable isNegative = false
  43.     let len = s.Length
  44.     let mutable valx = 0
  45.     let mutable c = s.[0]
  46.     if c = '-' then
  47.         isNegative <- true
  48.     elif (c >= '0' && c <= '9') then
  49.         ret <- (int c) - (int '0')
  50.     elif (c >= 'A' && c <= 'Z') then
  51.         ret <- int c - int 'A' + 10
  52.     elif (c >= 'a' && c <= 'z') then
  53.         ret <- int c - int 'a' + 10
  54.     if (ret >= radix) then
  55.         printfn "    Error: Can not read \"%s\" (as radix %d): %O is an invalid character!" s radix ret
  56.     for i = 1 to len - 1 do
  57.         c <- s.[i]
  58.         ret <- ret*radix
  59.         if (c >= '0' && c <= '9') then
  60.             valx <- int c - int '0'
  61.         elif (c >= 'A' && c <= 'Z') then
  62.             valx <- int c - int 'A' + 10
  63.         elif (c >= 'a' && c <= 'z') then
  64.             valx <- int c - int 'a' + 10
  65.         if (valx >= radix) then
  66.             printfn "    Error: Can not read \"%s\" (as radix %d): %O is an invalid character!" s radix c
  67.         ret <- ret + valx
  68.     if (isNegative) then
  69.         ret <- (-ret )
  70.     ret
  71. let makeTable dummy =
  72.     let mutable sbuf = ""
  73.     let mutable abuf = ""
  74.     let mutable tbuf = ""
  75.     for i in 0..(4-1) do
  76.         sbuf <- sbuf + "+-------"
  77.     sbuf <- sbuf + "+"
  78.     println(sbuf)
  79.     sbuf <- "|  Dec"
  80.     sbuf <- sbuf +  "\t|   Bin"
  81.     sbuf <- sbuf +  "\t|  Oct"
  82.     sbuf <- sbuf +  "\t|  Hex  |"
  83.     println(sbuf)
  84.     sbuf <- ""
  85.     for i in 0..(4-1) do
  86.         sbuf <- sbuf +  "+-------"
  87.     sbuf <- sbuf +  "+"
  88.     println(sbuf)
  89.     for i in 0..(16-1) do
  90.         sbuf <- sprintf "|   %2d" i
  91.         abuf <- itoa(i, 2)
  92.         tbuf <- sprintf "\t|  %4s" abuf
  93.         sbuf <- sbuf +  tbuf
  94.         abuf <- itoa(i, 8)
  95.         tbuf <- sprintf "\t|   %2s" abuf
  96.         sbuf <- sbuf + tbuf
  97.         abuf <- itoa(i, 16)
  98.         tbuf <- sprintf "\t|    %-2s |"  abuf
  99.         sbuf <- sbuf +  tbuf
  100.         println(sbuf)
  101.     sbuf <- ""
  102.     for i in 0..(4-1) do
  103.         sbuf <- sbuf +  "+-------"
  104.     sbuf <- sbuf +  "+"
  105.     println(sbuf)
  106. // Begin here
  107. let cmdArgs = System.Environment.GetCommandLineArgs()
  108. if (Array.length cmdArgs > 1 && "-h" = cmdArgs.[1]) then
  109.     printUsage 0
  110.     exit(1)
  111. makeTable 0


컴파일> fsc MakeRadixTable.fs

실행> MakeRadixTable

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




 

Posted by Scripter
,

다음은  대화형 모드(interactive mode)에서 진법 변환(radix conversion)하는 F# 소스 코드이다.

   주: 이 소스는 Python 용으로 만들어 둔 소스를 F# 언어로 바꾼 것이라서
        F# 언어의 명령형 언어 특징을 위주로 짜여져 있다.

메뉴는 주메뉴 Command: (S)et radix, (A)bout, (Q)uit or E(x)it
와 부메뉴 SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
로 구성되어 있으며, 진법 변환의 핵심은 소스 코드에 자체 작성된 함수 atoi(string, radix)와  itoa(number, radix)의 사용이다.

         let value = atoi(str, srcRdx)
         let str = itoa(value, destRdx)

지원되는 진법은 2진법에서 36진법까지이다.

  1. (*
  2.  *  Filename: ConvertRadix.fs
  3.  *            Convert radix in an interactive mode.
  4.  *
  5.  *  Compile: fsc convertRadix.fs
  6.  *  Execute: ConvertRadix
  7.  *
  8.  *      Date:  2010/07/14
  9.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  10.  *)
  11. #light
  12. exception RuntimeError of string
  13. exception ValueError of string
  14. let println s =
  15.     printfn "%O" s
  16. let print s =
  17.     printf "%O" s
  18. let printUsage dummy =
  19.     println "Usage: python convertRadix.py"
  20.     println "Convert radix in a interactive mode, where the maximum radix is 36."
  21. let printAbout dummy =
  22.     println "    About: Convert radix in a interactive mode."
  23. let printMainMenu dummy =
  24.     println "  Command: (S)et radix, (A)bout, (Q)uit or E(x)it"
  25. let printMainPrompt dummy =
  26.     print "  Prompt> "
  27. let printSubMenu srcRadix destRadix =
  28.     println ("    Convert Radix_" + (sprintf "%O" srcRadix) + " to Radix_" + (sprintf "%O" DestRadix) )
  29.     println ("    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit" )
  30. let printSubPrompt dummy =
  31.     print "    Input Value>> "
  32. let BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  33. let itoa (num : int, radix : int) =
  34.    let mutable isNegative = false
  35.    let mutable numx = num
  36.    if num < 0 then
  37.       isNegative <- true
  38.       numx <- (-num)
  39.    let mutable arr = [  ]
  40.    let mutable q = numx
  41.    let mutable r = 0
  42.    while (q >= radix) do
  43.        r <- int (q % radix)
  44.        q <- int (q / radix)
  45.        arr <- List.append arr [ sprintf "%O" (BASE36.[r]) ]
  46.    arr <- List.append arr [ sprintf "%O" (BASE36.[q]) ]
  47.    if isNegative then
  48.       arr <- List.append arr [ "-" ]
  49.    arr <- List.rev arr
  50.    System.String.Join("", List.toArray arr)
  51. let atoi (s : string, radix : int) : int =
  52.     let mutable ret = 0
  53.     let mutable isNegative = false
  54.     let len = s.Length
  55.     let mutable valx = 0
  56.     let mutable c = s.[0]
  57.     if c = '-' then
  58.         isNegative <- true
  59.     elif (c >= '0' && c <= '9') then
  60.         ret <- (int c) - (int '0')
  61.     elif (c >= 'A' && c <= 'Z') then
  62.         ret <- int c - int 'A' + 10
  63.     elif (c >= 'a' && c <= 'z') then
  64.         ret <- int c - int 'a' + 10
  65.     if (ret >= radix) then
  66.         printfn "    Error: Can not read \"%s\" (as radix %d): %O is an invalid character!" s radix ret
  67.     for i = 1 to len - 1 do
  68.         c <- s.[i]
  69.         ret <- ret*radix
  70.         if (c >= '0' && c <= '9') then
  71.             valx <- int c - int '0'
  72.         elif (c >= 'A' && c <= 'Z') then
  73.             valx <- int c - int 'A' + 10
  74.         elif (c >= 'a' && c <= 'z') then
  75.             valx <- int c - int 'a' + 10
  76.         if (valx >= radix) then
  77.             printfn "    Error: Can not read \"%s\" (as radix %d): %O is an invalid character!" s radix c
  78.         ret <- ret + valx
  79.     if (isNegative) then
  80.         ret <- (-ret )
  81.     ret
  82. let convertRadix s srcRdx destRdx =
  83.     let mutable ret = ""
  84.     try
  85.         try
  86.             let valx = atoi (s, srcRdx)
  87.             ret <- itoa (valx, destRdx)
  88.             ret <- ret.ToUpper()
  89.             ret
  90.         with
  91.             | ValueError e -> printfn "    Error: Cannot convert radix %O" srcRdx
  92.                               ret <- "????"
  93.                               ret
  94.     finally
  95.         ret.ToUpper() |> ignore
  96. let doConvert srcRadix destRadix =
  97.     let mutable line = ""
  98.     let mutable cmd = ""
  99.     let mutable srcStr = ""
  100.     let mutable destStr = ""
  101.     printfn ""
  102.     printSubMenu srcRadix  destRadix
  103.     let mutable stop_flag = false
  104.     try
  105.         while not stop_flag do
  106.             printSubPrompt()
  107.             let mutable cmd = System.Console.ReadLine()
  108.             while (String.length cmd) = 0 do
  109.                 cmd <- System.Console.ReadLine()
  110.             if "main()" = cmd then
  111.                 stop_flag <- false
  112.                 raise (RuntimeError ("return to main menu"))
  113.             elif "exit()" = cmd || "quit()" = cmd then
  114.                 exit(0)
  115.             try
  116.                 let dum = atoi(cmd, srcRadix) |> ignore
  117.                 srcStr <- cmd
  118.                 destStr <- (convertRadix srcStr srcRadix destRadix)
  119.                 printfn "        ( %s )_%d   --->   ( %s )_%d" srcStr srcRadix destStr destRadix
  120.                 printfn ""
  121.             with
  122.                 | ValueError e -> println ""
  123.     with
  124.         | RuntimeError e -> printfn "      %O" e
  125. let doStart dummy =
  126.     let mutable line = ""
  127.     let mutable cmd = ""
  128.     let mutable srcRadix = 10
  129.     let mutable destRadix = 10
  130.     let mutable srcStr = ""
  131.     let mutable destStr = ""
  132.     let mutable onlyOnce = true
  133.     let mutable st = [| |]
  134.     try
  135.         while true do
  136.             printfn ""
  137.             if onlyOnce then
  138.                 println "  The supported maximum radix is 36."
  139.                 onlyOnce <- false
  140.             printMainMenu 0
  141.             printMainPrompt 0
  142.             cmd <- System.Console.ReadLine()
  143.             while (String.length cmd) = 0 do
  144.                 cmd <- System.Console.ReadLine()
  145.             if "qQxX".IndexOf(cmd) >= 0 && (String.length cmd) = 1 then
  146.                 exit(0)
  147.             elif "aA".IndexOf(cmd) >= 0 && cmd.Length = 1 then
  148.                 printAbout 0
  149.             elif "sS".IndexOf(cmd) >= 0 && cmd.Length = 1 then
  150.                 print "  Input the source and target radices (say, 16 2): "
  151.                 line <- System.Console.ReadLine()
  152.                 st <- line.Split [| ' ' |]
  153.                 while (Array.length st) < 2 do
  154.                     print ("  Input the source and target radices (say, 16 2): ")
  155.                     line <- System.Console.ReadLine()
  156.                     st <- line.Split [| ' ' |]
  157.                 srcRadix <- int (st.[0])
  158.                 destRadix <- int (st.[1])
  159.                 doConvert srcRadix destRadix
  160.     with
  161.         | RuntimeError e ->  printfn "  Error foune!!"
  162. // Begin here
  163. let cmdArgs = System.Environment.GetCommandLineArgs()
  164. if (Array.length cmdArgs > 1 && "-h" = cmdArgs.[1]) then
  165.     printUsage 0
  166.     exit(1)
  167. doStart 0 |> ignore



컴파일> fsc ConvertRadix.fs

실행> ConvertRadix

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

    Convert Radix_10 to Radix_8
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 200
        ( 200 )_10   --->   ( 310 )_8

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

    Convert Radix_8 to Radix_10
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 2666
        ( 2666 )_8   --->   ( 1462 )_10

    Input Value>> main()

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




Posted by Scripter
,

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

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


  1. (*
  2.  *  Filename: TestGoldenRatio.fs
  3.  *    황금률(즉, 이차방정식 x^2 - x - 1  = 0 의 양의 근)을 계산한다.
  4.  *
  5.  *   Compile: fsc testGoldenRatio.fs
  6.  *   Execute: testGoldenRatio
  7.  *
  8.  *      Date:  2010/07/13
  9.  *    Author: PH Kim   [ pkim (AT) scripts.pe.kr ]
  10.  *)
  11. #light
  12. exception RuntimeError of string
  13. let printUsing =
  14.     printfn "Using: TestGoldenRatio [-h|-help]"
  15.     printfn "This calculates the value of the golden ratio."
  16. // 이차방정식 a x^2 + b x + c  = 0 의 근을 구한다.
  17. let findQuadraticRoot (a : float,  b : float, c : float) =
  18.     if a = 0.0 then
  19.         raise (RuntimeError "Since the highest coefficient is zero, the given equation is not a quadratic equation.")
  20.     elif (b*b - 4.0*a*c < 0.0) then
  21.         raise (RuntimeError ("Since the discriminant " + (sprintf "%O" (b*b - 4.0*a*c)) + " is negative, the given equation has no real root."))
  22.     let x1 = (-b + (sqrt (b*b - 4.0*a*c))) / (2.0 * a)
  23.     let x2 = (-b - (sqrt (b*b - 4.0*a*c))) / (2.0 * a)
  24.     x1, x2
  25. // 실행 시작 지점
  26. let cmdArgs = System.Environment.GetCommandLineArgs()
  27. if (Array.length cmdArgs > 1) && (cmdArgs.[1] = "-h" || cmdArgs.[1] = "-help") then
  28.     printUsing; exit(1)
  29. let x1, x2 = findQuadraticRoot (1.0 , -1.0 , -1.0)
  30. if x1 >= x2 then
  31.     printfn "The bigger root is %O, " x1
  32.     printfn "and the less root is %O." x2
  33. else
  34.     printfn "The bigger root is %O, " x2
  35.     printfn "and the less root is %O." x1



컴파일> fsc TestGoldenRatio.fs

실행>TestGoldenRatio
The bigger root is 1.61803398874989,
and the less root is -0.618033988749895.



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


  1. (*
  2.  *  Filename: TestCTimeApp.fs
  3.  *
  4.  *  Compile: fsc --codepage:949 TestCTimeApp.fs
  5.  * 
  6.  *  Execute: TestCTimeApp 
  7.  *)
  8. // namespace MyTestApp1
  9. open System
  10. let weekNames = [| "일"; "월"; "화"; "수"; "목"; "금"; "토" |]
  11. let now = System.DateTime.Now
  12. let startOfEpoch = new DateTime ( 1970, 1, 1 )
  13. // 1970년 1월 1일 0시 0분 0초부터 시작하여 현재까지의 초
  14. printfn "UTC: %O" ((int64 (DateTime.UtcNow - startOfEpoch).TotalMilliseconds) / 1000L)
  15. // 현재 시각 표시: 20xx년 xx월 xx일 (x요일) xx시 xx분 xx초
  16. printf "%O년 " (now.Year)
  17. printf "%O월 " (now.Month)     // Not 1 + now.Month !!
  18. printf "%O일 " (now.Day)
  19. printf "(%O요일) " (weekNames.[int (now.DayOfWeek)])
  20. printf "%O시 " (now.Hour)
  21. printf "%O분 " (now.Minute)
  22. printfn "%O초" (now.Second)
  23. // 1월 1일은 1, 1월 2일은 2
  24. printf "올해 몇 번째 날: %O, " (now.DayOfYear)
  25. // True 이면 서머타임 있음
  26. let str = if not (now.IsDaylightSavingTime()) then "안함" else "함"
  27. printfn "서머타임 적용 여부: %O"  str



컴파일> fsc TestCTimeApp.fs

실행> TestCTimeApp
UTC: 1279016975
2010년 7월 13일 (화요일) 19시 29분 35초
올해 몇 번째 날: 194, 서머타임 적용 여부: 안함



Posted by Scripter
,