スポンサーサイト

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

F#雑記 与えられた文字列を#等で囲むプログラム

みずぴーさんの記事や、BLUEPIXYさんの記事で取り上げていたプログラムをdiscriminated unionを使用してやってみました。(中心の文字は一つだけという点と、周りの囲みが複数可という点がオリジナルの問題と異なります)  
  
晴晴晴晴晴晴
晴こんちわ晴
晴晴晴晴晴晴
  
や  
光光光光光光光光光光
光晴晴晴晴晴晴晴晴光
光晴         晴光
光晴 こんちわ   晴光
光晴         晴光
光晴晴晴晴晴晴晴晴光
光光光光光光光光光光
を表示するプログラムです。 (なんかブラウザではゆがんでしまい、うまく表示されませんが。)
 
type BorderWithStr = 
  | Core of string 
  | Deco of char * BorderWithStr 
   
として 
晴晴晴晴晴晴
晴こんちわ晴
晴晴晴晴晴晴 
を 
 (Deco('晴 ',Core("こんちわ"))) 
 が表すことにします。 
  
 表示時の一行の長さを求めるメソッドは 
    member this.OneLineWidth () = 
        match this with 
        |Core(str) -> String.length str 
        |Deco(ch,inside) -> 2 + inside.OneLineWidth() 
 と定義します。
  
> (Deco('晴',Core("こんちわ"))).OneLineWidth();;
val it : int = 6
 
各行をリストの要素化するメソッドは 
 
    member this.MakeUpStringLst () = 
        match this with 
        |Core(str) -> [str] 
        |Deco(ch,inside) 
                 -> let oldInsideLst =inside.MakeUpStringLst() 
                    let oldInsideWidth = inside.OneLineWidth() 
                    let newWithOutTopBottomLineLst = List.map(fun s -> ch.ToString() + s + ch.ToString()) (oldInsideLst) 
                    let newTopBottomLine = new System.String(ch, oldInsideWidth + 2) 
                    newTopBottomLine :: newWithOutTopBottomLineLst @ [newTopBottomLine] 
 
と定義します。 
 
> (Deco('晴',Core("こんちわ"))).MakeUpStringLst();;
val it : string list = ["晴晴晴晴晴晴"; "晴こんちわ晴"; "晴晴晴晴晴晴"]
 
表示部分は 
    member this.Disp () = 
        List.iter (fun s -> printfn "%s" s) (this.MakeUpStringLst()) 
 
です。 
 
 
あとは makeInstanse "hollow" [' ';'#';'%']で(Deco('%',(Deco('#',(Deco(' ',Core("hellow")))))))を作り出すメソッドを定義します。 
 
let makeInstance str inChLst = 
    let rec sub chLst res = 
        match chLst with 
        | [] -> res 
        | h :: tl -> sub tl (Deco(h,res)) 
    sub  inChLst (Core(str))    
 
> makeInstance "Hellow"  [' ';'#';'%'];; 
val it : BorderWithStr = Deco ('%',Deco ('#',Deco (' ',Core "Hellow"))) 
 
全コードは次の通りです。 
 
open System 
type BorderWithStr = 
    |Core of string 
    |Deco of char*BorderWithStr 
     
    member this.OneLineWidth () = 
        match this with 
        |Core(str) -> String.length str 
        |Deco(ch,inside) -> 2 + inside.OneLineWidth() 
     
    member this.MakeUpStringLst () = 
        match this with 
        |Core(str) -> [str] 
        |Deco(ch,inside) 
                 -> let oldInsideLst =inside.MakeUpStringLst() 
                    let oldInsideWidth = inside.OneLineWidth() 
                    let newWithOutTopBottomLineLst = List.map(fun s -> ch.ToString() + s + ch.ToString()) (oldInsideLst) 
                    let newTopBottomLine = new System.String(ch, oldInsideWidth + 2) 
                    newTopBottomLine :: newWithOutTopBottomLineLst @ [newTopBottomLine] 
         
    member this.Disp () = 
        List.iter (fun s -> printfn "%s" s) (this.MakeUpStringLst()) 
 
let makeInstance str inChLst = 
    let rec sub chLst res = 
        match chLst with 
        | [] -> res 
        | h :: tl -> sub tl (Deco(h,res)) 
    sub  inChLst (Core(str))    
 
(実行例) 
> (makeInstance "こんちわ" [' ';'晴';'光']).Disp();;
光光光光光光光光光光
光晴晴晴晴晴晴晴晴光
光晴         晴光
光晴  こんちわ  晴光
光晴         晴光
光晴晴晴晴晴晴晴晴光
光光光光光光光光光光
val it : unit = ()
 
スポンサーサイト

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

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

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

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

この人とブロともになる

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