[[ネタ記録庫/AA折れ線グラフ]]
[[ネタ記録庫/AAGraph]]

#contents

* [[AA折れ線グラフ:http://oss.timedia.co.jp/index.fcgi/kahua-web/show/column/%ba%a3%c6%fc%a4%ce%b0%ec%b9%d4/%a3%b2%a3%b0%a3%b0%a3%b6%c7%af%a3%b3%b7%ee#H-1bpntk8]] [#me590200]


>AAで折れ線グラフを書くというお題. 
>入力は'R','F','C'の3種類も文字からなる長さ1以上の文字列 
>'R'は上昇を表し,折れ線グラフの要素としては '/' (スラッシュ)1文字に対応 
>'F'は下降を表し,折れ線グラフの要素としては '?' (バックスラッシュ)1文字に対応 
>'C'は変化なしを表し,折れ線グラフの要素としては'_'(アンダスコア)1文字に対応 
>たとえば, 

 $ ./plot RCRFCRFFCCRFFRRCRRCCFRFRFF

>とすると 

                   __      
                  /  ?/?/? 
  _/?_/?        _/        ?
 /      ?__/?  /           
             ?/            

>が出力されるようなスクリプトを書け. 
> --nobsun

源馬のSchemeでの回答はこちら。~
http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?gemma -- [[源馬]] &new{2006-07-01 (土) 12:00:06};


*解答 in Haskell [#nd70223e]
下村です。
無駄に長い上に汚いですけど…。

 output str =
     let result = graph str
         output' :: [String] -> IO ()
         output' mat =
             if any null mat then return ()
                             else do if any (' '/=) h then putStrLn h
                                                      else return ()
                                     output' t
                                         where
                                           h = map head mat
                                           t = map tail mat
     in
       output' result
 
 graph :: String -> [String]
 graph str =
     let 
         height =  (length str) * 2
         graph' [] _       = []
         graph' (x:xs) pos =
             case x of
               'R' -> oneline (pos) '/' height : graph' xs (pos-1)
               'F' -> oneline (pos+1) '??' height : graph' xs (pos+1)
               'C' -> oneline pos '_' height : graph' xs pos
     in
       graph' str (length str)
 
 -- n番目の文字がcであるような、長さlの文字列を生成する
 oneline :: Int -> Char -> Int -> String
 oneline _ _ 0 = ""
 oneline n c l = (if n==0 then c else ' ') : oneline (n-1) c (l-1)

で、結果は…

 Main> output "RCRFCRFFCCRFFRRCRRCCFRFRFF"
                   __      
                  /  ?/?/? 
  _/?_/?        _/        ?
 /      ?__/?  /           
             ?/            
 
 Main> 


*解答 in OCaml [#yc2d1595]
また下村です。OCamlで書き換えたので書いときます。Haskell版より関数とかをちょっと整理しました。あと、文字列はコマンドライン引数で指定するようにしてあります。explodeとimplodeは拡張ライブラリ関数なので、コンパイルするためにはExtLibをインストールする必要があります。

 (* <<COMPILE>> "ocamlopt -I +extlib extlib.cmxa lineGraph.ml" *)
 open ExtString.String;;
 open List;;
 exception NotRFC;;
 
 let any = List.fold_left (or) false;;
 
 let graph charlist =
   let height = (length charlist) * 2 in
   let rec transpose mat = if any (map (fun x -> x=[]) mat)
     then []
     else map hd mat :: transpose (map tl mat) in
   let rec oneline n c l = if l=0
     then []
     else (if n=0 then c else ' ') :: oneline (n-1) c (l-1) in
   let rec graph' charlist pos =
     match charlist with
 	[] -> []
       | c::cs -> match c with
             'R' -> oneline (pos) '/' height :: graph' cs (pos-1)
 	  | 'F' -> oneline (pos+1) '??' height :: graph' cs (pos+1)
 	  | 'C' -> oneline pos '_' height :: graph' cs pos
 	  | otherwise -> raise NotRFC
    in
     transpose (graph' charlist (length charlist));;
 
 let output =
   try
     let result =
       map (fun l -> if any (map (fun x -> x<>' ') l)
 	              then implode l ^ "?n" else "")
 	(graph (explode Sys.argv.(1))) in
     let rec output' list = match list with
 	[] -> ()
       | (""::ls) -> output' ls
       | (l::ls) -> print_string l;
 	  output' ls in
       output' result
   with
       NotRFC ->
 	print_string ("Usage : " ^ Sys.argv.(0) ^ " [RFC]*?n")
     | Invalid_argument _ ->
 	print_string ("Usage : " ^ Sys.argv.(0) ^ " [RFC]*?n");;

実行結果は…

 mac{sho}% ./a.out RCRFCRFFCCRFFRRCRRCCFRFRFF                   [~/src/ocaml]
                   __      
                  /  ?/?/? 
  _/?_/?        _/        ?
 /      ?__/?  /           
             ?/            
 mac{sho}%                                                      [~/src/ocaml]
- Ocamlがわかってないので、おぼろげにしかわからないです。なんかすごい。今度、教えてください。 -- [[源馬]] &new{2006-07-04 (火) 03:35:28};
トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS