スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

どう書く?org F# 割り算の筆算

「どう書く?org」http://ja.doukaku.org/に挑戦5問目です。 
さて今回の問題は次のような内容。 
 
(問題) 
整数 n, m を与えれば、 n ÷ m の筆算を出力するような
プロシージャ(関数)を創ってください。  http://ja.doukaku.org/246/
 
例えば次のように表示するものを作ってみます。
 
> DivByHand 123456 77;;
     1603
   ------
77)123456
    77
   ------
    464
    462
   ------
      256
      231
   ------
       25
val it : unit = ()

 
結構愚直にコードに直してみました。
関数DivByHand内でbDigDispが含まれる行が表示担当部分です。
 
     1603
   ------
77)123456
    77        #2
   ------     #3
    464          #1
    462       #2
   ------     #3  
      256     #1
      231     #2
   ------     #3 
       25     #4
 
コード中で担当部分を#1#2#3#4でコメントしておきました。
最初の二つの関数は補助関数です。
 
//bDigDisp 3 "k" 2 で"   kk"を表示
let bDigDisp padCount str strCount  =
   let rec sub subStr count limit res =
        if count = limit then res
        else  sub subStr (count + 1) limit (res + subStr)
   printfn "%s" ((sub " " 0 padCount "") + (sub str 0 strCount ""))  
 
//numToList 1234 で[1;2;3;4]が返る
let numToList n  =
    let rec NtlSub m res =
        if m = 0 then 
            res
        else
            NtlSub (m/10) ((m - (m/10)*10)::res)
    NtlSub n []
 
let DivByHand num div =
    let numList = numToList num
    let divPadLen = (div.ToString()).Length + 1 //"割る数)"の文字数
    let numLen = (num.ToString()).Length
    bDigDisp (divPadLen + numLen - ((num/div).ToString()).Length) ((num/div).ToString()) 1 //商の表示
    bDigDisp divPadLen "-" numLen //商の下の"---------"
    printfn "%d)%d"div num        //割る数)割られる数
    //              繰越          未処理の数字のリスト  左の空白文字数 最初かどうか
    let rec dbhSub (carryIn:int) (remDigLst:int list)   (padLen :int)   (isFirst : bool)=
        match remDigLst with
        | [] -> bDigDisp  (padLen - (carryIn.ToString()).Length)   (carryIn.ToString()) 1//最後の余りの表示//#4
        | hd::tl -> let targetNum = 10*carryIn + hd
                    if targetNum < div then
                        dbhSub targetNum tl (padLen + 1) isFirst
                    else
                        let quoTemp = targetNum/div
                        let subNumStr = (div*quoTemp).ToString()
                        if(isFirst <> true) then //繰越の表示(一番最初は表示しない)
                            bDigDisp (padLen - (targetNum.ToString()).Length + 1 ) (targetNum.ToString()) 1 //#2
                        bDigDisp (padLen - subNumStr.Length + 1 ) subNumStr 1 //引く数の表示 //#3
                        bDigDisp divPadLen "-" numLen //仕切りの"----"の表示 //#3
                        dbhSub (targetNum % div) tl (padLen + 1)  false
    dbhSub 0 numList divPadLen true
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。