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

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

예외상황 처리 부분 try ... with ... 부분이 아직 미완성이다.

  1. (*
  2.  *  Filename: makeDivisionTable.ml
  3.  *
  4.  *  Purpose:  Make a division table in a handy written form.
  5.  *
  6.  *  Execute: ocaml makeDivisionTable.ml
  7.  *
  8.  *   Or
  9.  *
  10.  *  Compile: ocamlc -o makeDivisionTable.exe makeDivisionTable.ml
  11.  *  Execute: makeDivisionTable 12345 32
  12.  *           makeDivisionTable 500210 61
  13.  *           makeDivisionTable 234 55
  14.  *
  15.  *     Date:  2013. 2. 2.
  16.  *   Author:  pkim __AT__ scripts.pe.kr
  17.  *)
  18. open Printf ;;
  19. exception RuntimeError of string
  20. exception ValueError of string
  21. let sBASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;;
  22. let sSPACE = "                                                          "  ;;
  23. let sULINE = "__________________________________________________________"  ;;
  24. let sHIPHEN = "----------------------------------------------------------"  ;;
  25. let println s = printf "%s\n" s ;;
  26. let print s = printf "%s" s ;;
  27. let printUsage() =
  28.     (* print("Using: makeDivisionTable [numerator] [denominator]")  *)
  29.     (* print("Make a division table in a handy written form.") *)
  30.     println "사용법: makeDivisionTable [피제수] [제수]" ;
  31.     println "손으로 작성한 형태의 나눗셈 표를 만들어준다." ;;
  32. let simplify v width =
  33.     let t = [| string_of_int v |] in
  34.     let slen = (String.length t.(0)) in
  35.     if slen < width then begin
  36.         t.(0) <- (String.sub sSPACE 0 (width - slen)) ^ t.(0)
  37.     end ;
  38.     t.(0) ;;
  39. let getSuffix v =
  40.     let t = v mod 10  in
  41.     let suffix = [| "은" |] in
  42.     if (String.contains "2459" (string_of_int  t).[0]) then begin
  43.         suffix.(0) <- "는" ;
  44.     end ;
  45.     suffix.(0) ;;
  46. let makeTable numer denom quotient =
  47.     let strNumer = sprintf "%d" numer in
  48.     let strDenom = sprintf "%d" denom  in
  49.     let strQuotient = sprintf "%d" quotient  in
  50.     let lenN = String.length strNumer  in
  51.     let lenD = String.length strDenom  in
  52.     let lenQ = String.length strQuotient  in
  53.     let offsetLeft = 3 + lenD + 3  in
  54.     let spaces = "                                                                                 "  in
  55.     let uline  = String.sub sULINE 0 (lenN + 2)  in
  56.     let sline  = String.sub sHIPHEN 0 lenN  in
  57.     let bias = lenN - lenQ  in
  58.     println ((String.sub spaces 0 offsetLeft) ^ (String.sub spaces 0 bias) ^ (sprintf "%d" quotient)) ;
  59.     println ((String.sub spaces 0 (offsetLeft - 2)) ^ uline) ;
  60.     print ("   " ^ strDenom ^ " ) " ^ strNumer) ;
  61.     let strTmpR = [| String.sub strNumer 0  (bias + 1) |] in
  62.     let tmpR = ref (int_of_string strTmpR.(0))  in
  63.     let tmpSub = ref 0  in
  64.     let oneDigit = [| "" |] in
  65.     for i = 0 to (lenQ - 1) do
  66.         if (String.sub strQuotient i 1) = "0" then begin
  67.             if i + 1 < lenQ then begin
  68.                 oneDigit.(0) <- (String.sub  strNumer (bias + i + 1) 1) ;
  69.                 printf "%s" oneDigit.(0)  ;
  70.                 strTmpR.(0) <- (strTmpR.(0) ^ oneDigit.(0)) ;
  71.                 tmpR := int_of_string strTmpR.(0)
  72.             end
  73.         end
  74.         else  begin
  75.             print_newline() ;
  76.             tmpSub := (int_of_string (String.sub strQuotient i 1)) * denom ;
  77.             printf "%s\n" ((String.sub spaces 0 offsetLeft) ^ (simplify !tmpSub  (bias + i + 1)))  ;
  78.             printf "%s\n" ((String.sub spaces 0 offsetLeft) ^ sline)  ;
  79.             tmpR := !tmpR - !tmpSub  ;
  80.             if !tmpR = 0 && i + 1 < lenQ then begin
  81.                 printf "%s" ((String.sub spaces 0 offsetLeft) ^ (String.sub spaces 0 (bias + i + 1)) ) ;
  82.             end
  83.             else begin
  84.                 printf "%s" ((String.sub spaces 0 offsetLeft) ^ (simplify !tmpR (bias + i + 1))) ;
  85.             end ;
  86.             strTmpR.(0) <- sprintf "%d" !tmpR ;
  87.             if i + 1 < lenQ then begin
  88.                 oneDigit.(0) <- (String.sub strNumer (bias + i + 1) 1) ;
  89.                 if  (String.length oneDigit.(0)) > 0 then
  90.                     print oneDigit.(0) ;
  91.                 strTmpR.(0) <- (strTmpR.(0) ^ oneDigit.(0))
  92.             end ;
  93.             tmpR := int_of_string strTmpR.(0)
  94.         end
  95.     done ;
  96.     printf "\n" ;
  97.     !tmpR ;;
  98. let main() =
  99.     let cmdArgs = Sys.argv in
  100.     if (Array.length cmdArgs < 3 || "-h" = cmdArgs.(1)) then begin
  101.         printUsage() ;
  102.         exit(1)
  103.     end ;
  104.     let a = [| 0 |] in
  105.     let b = [| 1 |] in
  106.     (*
  107.     try begin
  108.         a.(0) <- int_of_string (cmdArgs.(1)) ;
  109.         b.(0) <- int_of_string (cmdArgs.(2)) ;
  110.     end
  111.     with
  112.         | Failure e ->  ( begin
  113.                               printf "피제수: %s, 제수: %s\n" (cmdArgs.(1)) (cmdArgs.(2));
  114.                               printf "숫자 입력에 오류가 있습니다.\n";
  115.                               (* exit(1);  *)
  116.                         end; ) ;
  117.     *)
  118.    
  119.     a.(0) <- int_of_string (cmdArgs.(1)) ;
  120.     b.(0) <- int_of_string (cmdArgs.(2)) ;
  121.     if a.(0) <= 0 then begin
  122.         printf "피제수: %d\n" a.(0) ;
  123.         printf "피제수는 양의 정수라야 합니다.\n" ;
  124.         exit(1)
  125.     end
  126.     else if b.(0) <= 0 then begin
  127.         printf "제수: %d\n" b.(0) ;
  128.         printf "제수는 양의 정수라야 합니다.\n" ;
  129.         exit(1)
  130.     end ;
  131.     let q = a.(0) / b.(0) in
  132.     let r = a.(0) mod b.(0) in
  133.     printf "나눗셈 %d ÷ %d 의 결과: " a.(0) b.(0) ;
  134.     printf "몫: %d, " q ;
  135.     printf "나머지: %d\n" r ;
  136.     print_newline();
  137.     let k = makeTable a.(0) b.(0) q in
  138.     if k = r then
  139.         printf "\n나머지: %d\n" k ;
  140.     if k = 0 then begin
  141.         printf "%d = %d x %d\n" a.(0) b.(0) q  ;
  142.         printf "%d%s %d의 배수(mupltiple)이다.\n" a.(0) (getSuffix a.(0)) b.(0)  ;
  143.         printf "%d%s %d의 약수(divisor)이다.\n" b.(0) (getSuffix b.(0)) a.(0)
  144.     end
  145.     else begin
  146.         printf "%d = %d x %d + %d\n" a.(0) b.(0) q r  ;
  147.     printf "%d%s %d의 배수(mupltiple)가 아니다.\n" a.(0) (getSuffix a.(0)) b.(0)
  148.     end ;;
  149. main();;




컴파일> 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
,