프로그래밍/OCaml

손으로 계산하는 긴자리 곱셈표 만들기 with OCaml

Scripter 2013. 2. 2. 20:32

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

(*
 * Filename: makeMultTable.ml
 *
 *     Print a multiplication table.
 *
 *  Execute: ocaml makeMultTable.ml 123 450
 *
 *   Or
 *
 *  Compile: ocamlc -o makeMultTable.exe makeMultTable.ml
 *  Execute: makeMultTable 230 5100
 *
 *     Date: 2013. 2. 2).
 *   Author:  pkim __AT__ scripts.pe.kr
 *)
open Printf;;
exception RuntimeError of string
exception ValueError of string
let println s = printf "%s\n" s ;;
let print s = printf "%s" s ;;
let printUsage() =
    println "Using: ocaml makeMultTable.ml [number1] [number2]" ;
    println "Print a multiplication table for the given two integers." ;;
let printMultTable x y =
    let nx = ref x in
    if !nx < 0 then
        nx := - !nx ;
    let ny = ref y in
    if !ny < 0 then
        ny := - !ny ;
    let ntail1 = ref 0 in
    let ntail2 = ref 0 in
    while (!nx mod 10) = 0 do
        nx := !nx / 10 ;
        ntail1 := !ntail1 + 1
    done ;
    while !ny mod 10 = 0 do
        ny := !ny / 10 ;
        ntail2 := !ntail2 + 1
    done ;
    let z = !nx * !ny in
    let strZ = sprintf "%d" z in
    let strX = sprintf "%d" !nx in
    let strY = sprintf "%d" !ny in
    (* let n = String.length strY in *)
    let zeros  = "0000000000000000000000000000000000000000" in
    let whites = "                                        " in
    let bars   = "----------------------------------------" in
    let loffset = "       " in
    let line4 = loffset ^ strZ in
    let line1 = loffset ^ (String.sub whites 0 ((String.length strZ) - (String.length strX))) ^ strX in
    let line2 = "   x ) " ^  (String.sub whites 0 ((String.length strZ) - (String.length strY))) ^ strY in
    let line3 = "     --" ^  (String.sub bars 0 (String.length strZ)) in
    println (line1 ^ (String.sub zeros 0 !ntail1)) ;
    println (line2 ^ (String.sub zeros 0 !ntail2)) ;
    println line3 ;
    if (String.length strY) > 1 then begin
        for i = 0 to ((String.length strY) - 1) do
            let y1 = int_of_string (String.sub strY ((String.length strY) - i - 1)  1) in
            if not (y1 = 0) then begin
                let strT = sprintf "%d" (!nx * y1) in
                println (loffset ^ (String.sub whites 0 ((String.length strZ) - (String.length strT) - i)) ^ strT)
            end
        done ;
        println line3 ;
    end ;
    println (line4 ^ (String.sub zeros 0 !ntail1) ^ (String.sub zeros 0 !ntail2)) ;;
(* Begin here *)
let cmdArgs = Sys.argv in
if (Array.length cmdArgs >= 3) then begin
    let x = int_of_string (cmdArgs.(1)) in
    let y = int_of_string (cmdArgs.(2)) in
    println "" ;
    printMultTable x y
end
else begin
    printUsage() ;
    exit(1)
end




컴파일> ocamlc -o makeMultTable.exe makeMultTable.ml

실행> makeMultTable 230 5100
결과>

          1030
   x )   10020
     --------
          206
       103
     --------
       10320600